Use code annotations to promise meaningful data.

To annotate a Python function, use this format:

import adilib
from adilib import adi
...

@adi('https://adiframework.com/schemas/<schema domain identifier>')
def f(<argument1>, <argument2>, ...):
    ...

In the above, <schema domain identifier> should be replaced with the URL-encoding of the identifier of an existing schema domain. For example, pathology (see the reference documentation). The whole URI argument can be omitted if you make the following call wherever your one-time setup code runs (e.g. in an __init__.py file in case you are developing a library):

import adilib
adilib.setup('https://adiframework.com/schemas/<schema domain identifier>')

If you are working with a custom schema defined locally by files tables.tsv, fields.tsv, entities.tsv, properties.tsv, values.tsv, provide a file URI to the directory containing these files instead:

import adilib
adilib.setup('file:///home/user/project/my_schema/')

adilib will automatically analyze the argument tokens <argument1>, <argument2>, etc., for a match against table or entity type names. Since return values in Python are not named, to annotate a return value you must specify this explicitly:

@adi(
    'https://adiframework.com/schemas/<schema domain identifier>',
    {'return' : '<return_entity_type>'},
)
def f(<argument1>, <argument2>, ...):
    ...

You can also augment the annotations provided by the schema with additional annotations that are specific to the function:

@adi(
    {'Cell protein expression' : 'Protein expression measured on a per-cell basis, but in this case specifically as the result of multiplexed immunofluorescence imaging acquisition.'})
def f(cell_protein_expression):
   ...

adilib will generally be able to parse arguments that are lists, dictionaries, lists of lists, lists of dictionaries, pandas dataframes, and numpy matrices.