Skip to main content

Meta-data

Reference

Before going into specifics here is a full example for context:

def pythagoras(a: float, b: float) -> object:
"""Pythagoras theorem

Uses pythagoras theorem to calculate the hypotenuse length of a right-angled triangle.

Args:
a: The first side length
:units: mm
:latex: \\\\Delta_A
b: The second side length
:units: mm
:latex: \\\\Delta_B

Returns:
h: The hypotenuse length of the triangle
:units: mm
:latex: h

.. codeauthor:: Hugh Groves <[email protected]>
.. codeauthor:: George Aggrey <[email protected]>

.. levelofreview:: Complete

.. assumption:: Triangle is right-angled
.. assumption:: Triangle is planar

.. versionchanged:: 1.0.0
Changed to the power of 2, instead of 3 as in original version

.. versionchanged:: 1.0.1
Fixed typo in input argument descriptions

.. additionalinformationlink:: https://en.wikipedia.org/wiki/Pythagorean_theorem
Wikipedia article on pythagoras theorem

.. persistentcalcid:: e4b77e3d-562c-4bc1-bdde-bdc1e76f5ae2
"""

h = math.sqrt(a ** 2 + b ** 2)
return h

Parameters (inputs and outputs)

The following meta-data can be extracted from parameters and used within the ArupCompute system:

  • Symbol
  • Type
  • Description
  • Units (optional)
  • LaTeX (optional)

The majority of the information is extracted from the docstring, although some is also taken from the function definition.

Example:

Args:
a: The first side length
:units: mm
:latex: \\\\Delta_A
b: The second side length
:units: mm
:latex: \\\\Delta_B

Returns:
h: The hypotenuse length of the triangle
:units: mm
:latex: h

Docstring format for inputs / output meta-data:

Args:
<input_1>: <description_i1>
:units: <units_i1>
:latex: <latex_i1>
<input_2>: <description_i2>
:units: <units_i2>
:latex: <latex_i2>

Returns:
<result_1>: <description_r1>
:units: <units_r1>
:latex: <latex_r1>
<result_2>: <description_r2>
:units: <units_r2>
:latex: <latex_r2>

Symbol

The symbol of your input is extracted from the function signature. The symbol from the function inputs will be used to correlate with the data in the docstrings, so make sure they match!

input-correlated-by-symbol

Type

Types are extracted using PEP484 style annotations.

Including type annotations will help ensure the ArupCompute system works as expected, as well as helping users provide the correct information to your functions.

This article from RealPython explain the python type system in great detail.

warning

Type hints by themselves don't cause Python to enforce types. Type hints simply suggest types to whoever or whatever (ie. the ArupCompute frontend) is reading your code, which is helpful for improving the documentation and usability of what you write. Python will not stop you from using the wrong type for an argument (it won't throw an error for the wrong type).

Common options will be:

  • Text -> str
  • Number -> float or -> int
  • True / false -> bool

ArupCompute supports use of more "complex" type hints as well, including for collections-based types like:

  • Lists (ex. list of numbers) -> List[float] or -> List[int]
  • Dictionary -> Dict[str, int] (the types of both keys and values are needed)

Collections-based type hints will be shown as JSON input fields in the AC frontend:

json-input

tip

If you want to use these types as hints, you'll need to import the typing module.

from typing import Dict, List, Optional, Tuple

a: Dict[str, str] = {"colour": "blue"}
b: List[int] = [5]
c: Tuple[int, str, float] = (3, "yes", 7.5)

This type hints cheat sheet is a useful reference.

ArupCompute also supports type hints for numpy types:

  • Numpy array -> numpy.ndarray or -> numpy.typing.ArrayLike

Type hints for user defined classes are supported as well. Refer to this section of the docs for notes on working with Python classes and class instances as inputs. As with collections-based inputs, object inputs will be shown as JSON input fields in the AC frontend.

ArupCompute Python calculations can also use other collections-based and functions-based type hints, but these type hints are not currently supported by ArupCompute or on the ArupCompute frontend:

  • Union -> Union[int, str, float] (an object of either int, str or float type)
  • Optional -> Optional[int] (either an object of the given type or None, note that AC does not currently support optional inputs)
  • Type alias (ie. assigning a type to an alias, so you can use the type or the alias interchangeably)
  • Callable (ie. functions)
  • Generics (ie. arbitrary types)

Description

The description of the input will be extracted from the Args section of the docstrings.

This will usually be presented to users as a tooltip.

LaTeX

LaTeX notation can be used to typeset inputs. An exhaustive guide can be found here, but for example this notation \gamma_{max} would appear as below in the web interface.

gamma-max

You can preview what the typesetting will look like in this interactive editor.

warning

The backslash in a LaTeX symbol needs to be escaped 3 times (ex. \gamma specified as \\\\gamma) to be parsed properly by ArupCompute.

Units (optional)

Units are declared by using the :units: annotation. LaTeX notation can be used to typeset the units, for example mm^2 would appear as below in the web interface.

mm2

Version(s)

For function revisions the Sphinx ‘versionchanged’ directive will be reused.

Semver 2.0 format is to be used for version numbering.

If no versionchanged directives are present the function will assume the version 0.0.0 - Initial revision.

It is best-practice to leave all prior versionchanged tags in the docstring to allow a version history to be generated and shown to end users.

.. versionchanged:: <semver>
<description>

.. versionchanged:: 1.2.3
Fixed divide by 0 error in certain circumstances

Author(s)

For capturing code author(s) we will reuse the Sphinx 'codeauthor' directive. The first instance of 'codeauthor' will be used as the main author, subsequent ones will be 'additional' authors.

.. codeauthor:: <Name> <<email>>

.. codeauthor:: Hugh Groves <[email protected]>

Level of review

An indication of the level of review that the function has undertaken.

Options are:

  • Work in progress
  • Complete

If no levelofreview directive is present the default value assumed will be 'Complete'.

.. levelofreview:: <level>

.. levelofreview:: Work in progress

Assumption

Assumptions that the user may need to know about for using the function correctly.

.. assumption:: <text>

.. assumption:: Triangle is planar

This directive is used to provide external links, for example to guidance on how to use the function.

.. additionalinformationlink:: <url>
<link text>

.. additionalinformationlink:: https://en.wikipedia.org/wiki/Pythagorean_theorem
Wikipedia article on pythagoras theorem

Persistent calculation identifier

This meta-data is used to track functions across multiple library versions, even if the functions name, folder, inputs, description etc. change.

UUIDv4 format is required. This website can be used to generate UUIDv4.

.. persistentcalcid:: <UUIDv4>

.. persistentcalcid:: a4889bcf-d2bb-41eb-8b06-ac87ac80a6b3

Explanation

For the ArupCompute system to work meta-data about the functions within a library need to be scraped.

In the C# backend this is achieved using Attributes. A full list of supported Attributes can be found in the arupcompute-sdk-dotnet repo.

For the python backend an alternative system must be found.

Reasoning behind chosen solution

As is reasonably common in the python ecosystem docstrings and annotations will be used to encode the meta-data.

PEP287 states that reStructuredText should be used in docstrings.

PEP3107 and PEP484 show how type annotations can be used.

reStructuredText contains the concept of ‘directives’ and ‘field lists’ for encapsulating additional meta-data. We will reuse this in our system. Popular documentation generator Sphinx utilises these features of reStructuredText to capture meta-data. There are a number of directives used within Sphinx that capture data we are interested in, so we will reuse the same syntax so that the same docstrings can inform ArupCompute as well as auto-generated documentation.

Directives

Directives follow this format:

.. <directive_name>:: <argument>
<block>

As a tangible example here is one from the Sphinx documentation

.. deprecated:: 3.1
Use function 'spam' instead

Field lists

Field lists follow the format

:fieldname: Field content

These are limited to single arguments, and can appear as supplements to directives.

Directives vs. field lists

Although much of the ArupCompute meta-data is simple key-value pairs, for consistency with more complicated instructions and to allow for future extensibility all top-level meta-data constructs will be implemented as directives.

Further information