Skip to content

Metadata builders

For convenience, we have a set of meta building APIs for defining metadata. This page describes each API and provides some examples.

The meta-building APIs create entries to populate the metadata fields of APIs and aggregation functions. They live in the .kxi namespace.

  • .kxi.metaDescription - Creates a description entry for an API/aggregation function's metadata. It takes the parameter:

    • descr - string - The description of the UDA
  • .kxi.metaParam - Creates a parameter entry for an API/aggregation function's metadata.

    It takes the following parameters:

    • param - dictionary - Dictionary containing any subset of the following keys:

      • name - symbol - Name of the parameter.
      • type - short|short[] - Possible type(s) for the parameter.
      • isReq - boolean - Whether the parameter is required (this is only meaningful for APIs).
      • default - any - Default value of the parameter if it is not required (this is only meaningful for APIs).
      • description - string - Plain text description of the parameter.
  • .kxi.metaReturn - Creates a return entry for an API/aggregation function's metadata.

    It takes the following parameters:

    • return - dictionary - Dictionary containing any subset of the following keys:

      • type - short|short[] - Possible type(s) for the return.
      • description - string - Plain text description of the return value.
  • .kxi.metaMisc - Creates a miscellaneous metadata entry.

    It takes the following parameters:

    • misc - dictionary - Dictionary containing any subset of the supported misc fields:

      • safe - boolean - True if API can be retried safely in the event of a failure, false otherwise.

Examples

Using the APIs

Uses the meta-building helpers (.kxi.metaDescription, .kxi.metaParam, .kxi.metaReturn, etc.) to construct rich metadata for an API and an aggregate function, including descriptions, typed parameters (required/defaults), return metadata, and misc flags (for example safe).

//--------------------------------------------------------------------------------
// Metadata using the meta-building APIs.
//--------------------------------------------------------------------------------

.da.registerAPI[`myAPI;
    .kxi.metaDescription["Simple 'select ... from ... where ...' API."],
    .kxi.metaParam[`name`type`isReq`description!(`table;-11h;1b;"Table to query")],
    .kxi.metaParam[`name`type`isReq`default`description!(`filter;0 10h;0b;();"Filter (in functional or string form).")],
    .kxi.metaParam[`name`type`isReq`default`description!(`col;11 -11h;0b;`sym`time;"Column(s) to select.")],
    .kxi.metaReturn[`type`description!(98h;"Result of the select.")],
    .kxi.metaMisc[enlist[`safe]!enlist 1b]
    ]

// Note: Can only have 1 parameter for an agg function.
.sgagg.registerAggFn[`myAggFn;
    .kxi.metaDescription["Takes the sum."],
    .kxi.metaParam[`type`description!(2 4 5 6 7 8 9h;"Some list of summable vectors.")],
    .kxi.metaReturn[`type`description!(6 7 8 9h;"The sum of the lists.")];
    ()
    ]

Using a default dictionary

Registers an API using a simple dictionary of parameter defaults. This approach only populates the params field and implicitly marks all parameters as optional, with no description or return metadata.

//--------------------------------------------------------------------------------
// Metadata using a default dictionary. This only populates the `params` field.
// Also note that it marks all parameters optional.
//--------------------------------------------------------------------------------

.da.registerAPI[`myAPI;`table`filter`col!(`trade;();`sym`time)]

Using a string

Registers the API or aggregate function with just a plain-text description. Only the description field is populated, making this the quickest way to provide minimal usage guidance.

//--------------------------------------------------------------------------------
// Description using just a plain string. This populates just the `description`
// field. This offers a quick way to minimally describe how an API/agg function
// should be used.
// These calls would be equivalent to just using the `description` key in the
// other examples.
//--------------------------------------------------------------------------------

.da.registerAPI[`myAPI;"Simple 'select ... from ... where ...' API."]

.sgagg.registerAggFn[`myAggFn;"Takes the sum.";()]

Using JSON

Defines metadata explicitly as a dictionary (JSON-style structure), allowing full control over the description, parameter schema, and return metadata, and supports registration using either the dictionary directly or its JSON-encoded string form. Supplying an empty dictionary (()) is equivalent to registering the API or aggregate function with no metadata at all.

//--------------------------------------------------------------------------------
// Metadata using JSON.
//--------------------------------------------------------------------------------

// API.
apiMetaData:()!()
apiMetaData[`description]:"Simple 'select ... from ... where ...' API."
apiMetaData[`param]:flip
    (`name      ,`type  ,`required  ,`default   ,`descr)!flip(
    (`table     ;98h    ;1b         ;()         ;"Table to query");
    (`filter    ;0 10h  ;0b         ;()         ;"Filter (in functional or string form).");
    (`col       ;11 -11h;0b         ;`sym`time  ;"Column(s) to select.")
    )
apiMetaData[`return]:`type`description!(98;"Result of the select.")

.da.registerAPI[`myAPI;apiMetaData] // Or, equivalently ...
.da.registerAPI[`myAPI;.j.j apiDescr] // Stringed

// Agg function.
aggMetaData:()!()
aggMetaData[`description]:"Takes the sum."
aggMetaData[`param]:`name`type`descr!(`x;2 4 5 6 7 8 9h;"Some list of summable vectors.")

.sgagg.registerAggFn[`myAggFn;aggDescr;()] // Or equivalently ...
.sgagg.registerAggFn[`myAggFn;.j.j aggDescr;()] // Stringed
//--------------------------------------------------------------------------------
// No description at all.
//--------------------------------------------------------------------------------

.da.registerAPI[`myAPI;()]

.sgagg.registerAggFn[`myAggFn;();()]