Skip to content

kxi-toolkit: UDA

Decorator-based UDA authoring API for kdb Insights Enterprise.

Provides the uda builder object for defining, describing, and registering User-Defined Analytics (UDAs) in Python.

Example
import pykx as kx
from kxi_toolkit import uda, register_udas, select_table, Symbol, Timestamp, Table

@uda.name("salesSummary")
@uda.description("Sales summary grouped by sym")
@uda.safe()
def sales_summary(table: Symbol, startTS: Timestamp = None, endTS: Timestamp = None) -> Table:
    raw = select_table(table, startTS, endTS)
    return kx.q(
        "{0!select cnt:count i, avg_price:avg price, total_vol:sum size by sym from x}",
        raw,
    )

@sales_summary.aggregation
def sales_summary_agg(partials) -> Table:
    combined = kx.q.raze([kx.Table(data=d) for d in partials])
    result = kx.q(
        "{select cnt:sum cnt, avg_price:avg avg_price, total_vol:sum total_vol by sym from x}",
        combined,
    )
    return kx.q(".kxi.response.ok", result)

register_udas()

Functions:

  • register_udas – Register all decorated UDAs with the KXI runtime.

Attributes:

  • defined_udas (dict[tuple[str, str], '_UDAFunc']) – Registry of all decorated UDAs, keyed by (module, function_name).
  • uda – The primary API for authoring User-Defined Analytics (UDAs).

defined_udas

defined_udas: dict[tuple[str, str], '_UDAFunc'] = {}

Registry of all decorated UDAs, keyed by (module, function_name).

Populated automatically when @uda.name() is applied.

register_udas

register_udas()

Register all decorated UDAs with the KXI runtime.

Iterates over defined_udas and calls .kxi.registerUDA for each entry via pykx. Safe to call outside a KXI runtime — failures are logged as warnings and do not raise.

Call this exactly once, after all @uda.name() and .aggregation decorators have been applied across all modules.

Outside a licensed KXI environment the decorators still work as a documentation and API description layer — register_udas() will warn and continue rather than raise.

If your UDA query and aggregation functions live in different modules, import the UDA object into the aggregation module, attach the aggregation, then call register_udas():

# agg_module.py
from my_udas import my_uda

@my_uda.aggregation
def my_uda_agg(partials) -> Table:
    ...

register_udas()

uda

uda = _UDABuilder()

The primary API for authoring User-Defined Analytics (UDAs).

Applying @uda.* decorators to a Python function produces a UDA object — a plain Python callable with extra metadata attached. The function still works as normal; the metadata is collected and passed to .kxi.registerUDA when register_udas() is called.

The following fields are exposed on the resulting UDA object:

Attributes:

  • name (str) – q-style name the UDA is registered under (e.g. "salesSummary" or ".myns.salesSummary"). Set via @uda.name(). Required.
  • description (str) – Human-readable description shown in the KXI UI. Set via @uda.description().
  • category (list[str]) – Category labels for UI grouping. Set via @uda.categories().
  • tag (str) – Optional free-form tag string. Set via @uda.misc(tag=...).
  • params (list) – Parameter descriptors inferred from type hints; override individual fields with @uda.param().
  • returns (dict[str, str]) – Return type descriptor, e.g. {"type": "table"}; inferred from type hints, override with @uda.returns().
  • misc (dict[str, Any]) – Miscellaneous metadata, e.g. {"safe": True}. Set via @uda.misc() or @uda.safe().
  • function (str) – Python function name — implicit, inferred from the callable.
  • file_path (str) – Source file path — implicit, populated at registration time.
  • language (str) – Always "py" — implicit.

Aggregation functions are attached directly on the UDA object after decoration, not via uda:

@uda.name("myUDA")
def my_uda(table: Symbol) -> Table:
    ...

@my_uda.aggregation
def my_uda_agg(partials) -> Table:
    ...

The aggregation function receives a list of partial results from each DAP and must return a single combined result.

See the module overview for a full usage example.

Back to top