Skip to content

API Metadata

Marcos edited this page Jul 6, 2021 · 8 revisions

Overview

API Metadata is extracted using internal tools at NI. This produces several files which are then uploaded to this Git repository. Since these files are generated, they should not be manually changed, as any edits will be lost next time new versions of the files are uploaded. The files contain simple Python dictionaries and their contents are hopefully self-explanatory.

  • src/<driver>/metadata/functions.py
  • src/<driver>/metadata/enums.py
  • src/<driver>/metadata/attributes.py

In addition, the following files are also sourced in the Git repository, but are hand-coded by the nimi-python developers.

  • src/<driver>/metadata/config.py: General driver information.
  • src/<driver>/metadata/__init__.py: Makes it simple for the nimi-python code generator to load the metadata.
  • src/<driver>/metadata/attributes_addon.py: Additions or overrides applied on top of attribute metadata (as loaded from attributes.py)
  • src/<driver>/metadata/functions_addon.py: Additions or overrides applied on top of function metadata (as loaded from attributes.py)

These "add on" files are important because the Python API is "richer" in a sense than the source of the extracted metadata (based on the C API). In Python, memory management is done for the client. In Python, we want to leverage enums. In Python, you can have default values for arguments. This is the sort of thing we need to include in this "add on" Pythons-specific metadata.

Size info

In our C APIs, all memory management is left to the client. Through documentation, the client learns what needs to be done. In the nimi-python case, we want our Python bindings to handle all buffer allocation.

We do this by specifying parameter metadata which the code generator uses in order to create the correct code in the generated Python bindings. Array and string parameters have this metadata:

{'is_buffer': True}

We specify a size metadata which points to a dictionary with two keys: mechanism and value.

These are the valid values for the size metadata:

      'fixed':    The size is known at compile time, usually defined by the API.
                  'value' should be an int indicating the size that the passed-in array must have.
  'passed-in':    The size of the array parameter is specified in another parameter.
                  'value' should be the name of the parameter through which this is specified.
                  This is used in functions in which the array is returned, so the array input
                  parameter is omitted from the public Python API.
  'ivi-dance':    The size is determined by calling into the function using a size of zero and
                  interpreting the return value as a size rather than an error.
                  'value' should be the name of the parameter through which the size (0 the first
                  call, then the real value on the second call) is passed in.
                  This is used in functions in which the array is returned, so the array input
                  parameter is omitted from the public Python API.
        'len':    Used for input arrays, the size is determined by calling len() on the parameter.
                  The size parameter from the C function is omitted from the public Python API.
'python-code':    The 'value' is actual python code from the aspect of session.py

Method templates

We sometimes need to generate multiple instances of a given function. For example, we might want one instance to use intrinsic Python types and the other to take and/or return high performance numpy types.

For this, you can specify the 'method_templates' key per function. The value associated with this key is an array of dictionaries. Each dictionary should have three key:value pairs.

  1. 'session_filename': ''
  2. 'documentation_filename': ''
  3. 'method_python_name_suffix': 'string'

'session_filename' should be the base name of the MAKO template that will be included by the higher level session.py.mako template in order to expand the implementation of that function. The generator will append to the beginning and to the end of this string before including the file: "session.py/<file base name>.py.mako".

'documentation_filename' should be the base name of the MAKO template that will be included by the higher level functions.rst.mako template in order to expand the documentation of that function. The generator will append to the beginning and to the end of this string before including the file: "functions.rst/<file base name>.rst.mako". You may specify None as the value of this if the function is marked as 'codegen_method':'no' or 'codegen_method':'private' because no documentation is generated for those anyway.

'method_python_name_suffix' is a suffix that the generator will append to the python_name of the function.

This is currently used in two location:

  1. session.py - method definition
  2. function.rst - method documentation

If there is no 'method_templates' for a given function, defaults are used.

Example:

  • Function only has default
  • During session.py generation, /build/templates/session.py/default_method.py.mako will be included
  • During functions.rst generation, /build/templates/functions.rst/default_method.rst.mako will be included

The IVI Dance

(sing to the tune of The Hokey Pokey)

You pass NULL pointer in,
You get an error back,
That's not an error, no,
It's actually the size.

You allocate the buffer.
And you pray that you won't crash.
And that's how you IVI Dance.
Clone this wiki locally