vgi.arguments
Module overview
Argument parsing and validation for VGI functions.
This module provides classes for handling function arguments in VGI:
class AnyArrow
Section titled “class AnyArrow”Description
Sentinel type for arguments accepting multiple Arrow types.
Use this with AnyArrowValue in the Annotated pattern when an argument
should accept multiple valid Arrow types, validated via the type_bound
parameter. When accessed, returns an AnyArrowValue containing the value
plus metadata (position and name).
Choosing Between Specific Types and AnyArrowValue
-
Single required type: Use
Annotated[str, Arg(...)]or similar. The argument will only accept that exact type. -
Multiple valid types: Use
Annotated[AnyArrowValue, Arg(...)]withtype_boundto specify which types are acceptable. For example, numeric operations that work on integers, floats, and decimals should useAnyArrowValue.
The type_bound parameter is ONLY meaningful for AnyArrowValue arguments.
Using it with other types will emit a warning.
Examples using Annotated (recommended):
from typing import Annotatedfrom vgi import Arg, AnyArrowValue
# Single type: function only works with stringsclass UpperCaseFunction(TableFunctionGenerator): column: Annotated[str, Arg(0, doc="String column to uppercase")]
# Multiple types: function works with any numeric typeclass DoubleFunction(TableFunctionGenerator): column: Annotated[ AnyArrowValue, Arg(0, type_bound=[pa.types.is_integer, pa.types.is_floating]) ]
def on_bind(self) -> None: # Access column metadata for dynamic output type self._output_type = self.column.value
# Any type: function works with all typesclass IdentityFunction(TableFunctionGenerator): column: Annotated[AnyArrowValue, Arg(0, doc="Column to pass through")]Accessing values
When using AnyArrowValue, access the value via the .value attribute:
val = self.column.value # The column name as a stringpos = self.column.position # The positional indexNote
Unlike TableInput, AnyArrow arguments have actual Arrow values -
they are just not constrained to a specific Arrow type.
Attributes
attribute position
Section titled “attribute position”int | str
The argument’s positional index or name used to resolve it.
class AnyArrowValue
Section titled “class AnyArrowValue”Description
Wrapper for AnyArrow argument values with metadata.
When an Arg returns an AnyArrow type, accessing the attribute returns
an AnyArrowValue instead of just the raw value. This provides access to
both the value and the argument’s position/name for schema lookups.
Example using Annotated (recommended):
from typing import Annotated
class MyFunction(TableFunctionGenerator): col1: Annotated[AnyArrowValue, Arg(0, doc="First column")]
def on_bind(self) -> None: # self.col1 is an AnyArrowValue print(self.col1.value) # The column name print(self.col1.position) # The positional indexExample using legacy Arg[AnyArrow] syntax:
class MyFunction(TableFunctionGenerator): col1 = Arg[AnyArrow](0, doc="First column") # type: ignore[assignment]Attributes
attribute position
Section titled “attribute position”int | str
The positional index from the Arg definition (int for positional,
str for named arguments).
class Arg
Section titled “class Arg”Description
Descriptor for declarative argument parsing with optional validation.
Use as a class attribute to declare function arguments that are automatically
parsed from self.arguments when accessed. This eliminates the need to override
__init__ for simple argument parsing.
Note
For named arguments (string position), the Python attribute name should match the SQL key. This is the standard convention:
format = Arg[str]("format") # Recommended: attribute == keyAvoid using different names:
output_format = Arg[str]("format") # Not recommendedWhile this works at runtime, it can cause issues with metadata serialization where only one name is preserved.
Attributes
attribute position
Section titled “attribute position”int | str
Positional index (int) or named key (str).
attribute default
Section titled “attribute default”ArgT | Any
Default value if argument not provided. Omit for required arguments.
attribute ge
Section titled “attribute ge”float | int | None
Value must be >= this (for numeric types).
attribute le
Section titled “attribute le”float | int | None
Value must be <= this (for numeric types).
attribute gt
Section titled “attribute gt”float | int | None
Value must be > this (for numeric types).
attribute lt
Section titled “attribute lt”float | int | None
Value must be < this (for numeric types).
attribute choices
Section titled “attribute choices”Sequence[ArgT] | None
Value must be one of these options.
attribute pattern
Section titled “attribute pattern”str | None
Value must match this regex pattern (for strings).
attribute varargs
Section titled “attribute varargs”If True, collect all remaining positional arguments from this position onwards. Returns tuple[ArgT, …]. Requires at least 1 value. Must be positional (not named).
attribute arrow_type
Section titled “attribute arrow_type”Explicit Arrow type for this argument. If not provided,
type is inferred from the type hint using PYTHON_TO_ARROW.
attribute type_bound
Section titled “attribute type_bound”Type predicate(s) for Arg[AnyArrow] column type validation.
Accepts a single predicate (e.g., pa.types.is_integer) or a sequence
of predicates where any match is valid (OR logic). Only meaningful
for Arg[AnyArrow] arguments; issues a warning if used with other types.
attribute const
Section titled “attribute const”If True, marks this argument as constant-folded (ConstParam).
Constant arguments have their values known at planning time.
attribute is_any
Section titled “attribute is_any”If True, indicates this argument accepts any Arrow type (AnyArrow).
Used for tracking when AnyArrow was specified in the type hint.
Methods
method format_error
Section titled “method format_error”format_error(message: str) -> strFormat an error message with argument context.
Use this method when performing custom validation to produce error messages that include the argument’s position and name.
method validate_type_bound
Section titled “method validate_type_bound”validate_type_bound(field_type: pa.DataType) -> NoneValidate that the field type satisfies the type bound predicate(s).
This method is called during function initialization for Arg[AnyArrow]
arguments that have type_bound specified.
If multiple predicates are provided, uses OR logic (any match is valid).
class Arguments
Section titled “class Arguments”Description
Container for function arguments.
Access arguments using get() for Python values:
# Positional arguments (by index)count = args.get(0) # First argumentname = args.get(1, default="unnamed") # With default
# Named arguments (by string)separator = args.get("sep", default=",")threshold = args.get("threshold")
# With type validation (optional, for strict checking)count = args.get(0, type=pa.int64())For direct Arrow Scalar access, use positional/named attributes:
scalar = args.positional[0] # pa.Scalar | Nonescalar = args.named["sep"] # pa.ScalarAttributes
attribute positional
Section titled “attribute positional”tuple[Scalar[Any] | None, …]
Tuple of positional argument values as pa.Scalar.
attribute named
Section titled “attribute named”dict[str, Scalar[Any]] | None
Dictionary mapping argument names to pa.Scalar values.
Methods
method get
Section titled “method get”get(
key: int | str,
*,
type: pa.DataType | None = None,
default: Any = _MISSING,
) -> AnyGet argument as Python value.
SQL NULL is a real value, distinct from “argument not provided”.
default is consulted only when the caller omitted the argument
entirely; an explicit SQL NULL returns None.
method get_varargs
Section titled “method get_varargs”get_varargs(
start: int,
*,
type: pa.DataType | None = None,
) -> tuple[Any, …]Get all positional arguments from start position onwards.
method encoded_dict
Section titled “method encoded_dict”encoded_dict() -> dict[str, Scalar[Any] | None]Convert arguments to a dictionary suitable for serialization.
Positional arguments are stored with keys “positional_0”, “positional_1”, etc. Named arguments are stored with their actual names prefixed by “named_”.
The reason why a dictionary is used is to facilitate serialization with Arrow, which can easily handle flat structures, but doesn’t handle variable typed arrays of arbitrary objects.
method schema
Section titled “method schema”schema() -> pa.SchemaReturn Arrow schema for serializing these Arguments.
Creates a schema with one field per argument: “positional_0”, “positional_1”, etc. for positional args, and “named_<name>” for named args. Field types are taken directly from scalar values to handle Arrow extension types.
method decode
Section titled “method decode”decode(data: pa.StructScalar) -> ArgumentsDecode Arguments from a serialized dictionary.
method serialize_to_bytes
Section titled “method serialize_to_bytes”serialize_to_bytes() -> bytesSerialize Arguments to bytes using Arrow IPC format.
Creates a single-row RecordBatch with the arguments encoded as
a struct column, then serializes it to IPC stream bytes.
Builds the batch with explicit types from scalar values to handle
Arrow extension types (e.g., HUGEINT) that from_pylist() cannot infer.
method deserialize_from_bytes
Section titled “method deserialize_from_bytes”deserialize_from_bytes(
data: bytes,
ipc_validation: Any = None,
) -> ArgumentsDeserialize Arguments from bytes.
class ArgumentValidationError
Section titled “class ArgumentValidationError”Bases: ValueError
Description
Raised when an argument fails validation.
This exception provides detailed context about what went wrong and suggests how to fix the issue.
Attributes
attribute arg_name
Section titled “attribute arg_name”str | None
Name of the argument that failed validation.
attribute position
Section titled “attribute position”int | str | None
Positional index or named key of the argument.
attribute constraint
Section titled “attribute constraint”str | None
Description of the constraint that was violated.
attribute doc
Section titled “attribute doc”str | None
Documentation string for the argument (if provided).
attribute valid_range
Section titled “attribute valid_range”str | None
Human-readable description of valid values.
attribute default
Section titled “attribute default”Any
Default value (if any) that could be used instead.
attribute choices
Section titled “attribute choices”Sequence[Any] | None
Valid choices, if the argument is constrained to a set.
class Auth
Section titled “class Auth”Description
Metadata for auth context parameter in compute().
Use with Annotated to declare a parameter that receives the AuthContext
for the current request. Returns AuthContext.anonymous() when no
authentication is configured (including stdio transport).
class ConstParam
Section titled “class ConstParam”Description
Metadata for constant scalar parameters in compute().
Use with Annotated to declare parameters that receive constant (non-columnar)
values known at planning time. The type is inferred from the Annotated first
argument (e.g., Annotated[int, ConstParam(...)] infers pa.int64()).
Attributes
attribute arrow_type
Section titled “attribute arrow_type”Optional explicit Arrow type. If not provided, type is inferred from the Annotated first argument.
attribute position
Section titled “attribute position”int | None
Position in the argument list
(optional for ScalarFunction where position is inferred from signature).
attribute phase
Section titled “attribute phase”str
Phase when this const param is needed (aggregate functions only).
"all" = every callback, "update" = only update,
"finalize" = only finalize.
attribute choices
Section titled “attribute choices”Sequence[Any] | None
Closed set of allowed values. Surfaced for agent discovery
(via vgi_function_arguments()) AND enforced at bind: a const value
outside the set raises ArgumentValidationError.
attribute ge
Section titled “attribute ge”float | int | None
Value must be >= this (inclusive lower bound); enforced at bind.
attribute le
Section titled “attribute le”float | int | None
Value must be <= this (inclusive upper bound); enforced at bind.
attribute gt
Section titled “attribute gt”float | int | None
Value must be > this (exclusive lower bound); enforced at bind.
attribute lt
Section titled “attribute lt”float | int | None
Value must be < this (exclusive upper bound); enforced at bind.
attribute pattern
Section titled “attribute pattern”str | None
Regex the value must match (string params); enforced at bind.
class OutputLength
Section titled “class OutputLength”Description
Metadata for output length parameter in compute().
Use with Annotated to declare a parameter that receives the number of rows in the input batch. This is useful for scalar functions that don’t take any column arguments but need to know how many output values to produce.
class Param
Section titled “class Param”Description
Metadata for columnar parameters in compute() or class-level declarations.
Use with Annotated to declare parameters that receive pa.Array values
at runtime. The type information is used for catalog registration and
argument validation.
For ScalarFunction compute() methods, position is inferred from parameter order.
Example (ScalarFunction compute() - position inferred):
class AddColumns(ScalarFunction): @classmethod def compute( cls, left: Annotated[pa.Array, Param(pa.int64(), "First value")], right: Annotated[pa.Array, Param(pa.int64(), "Second value")], ) -> Annotated[pa.Array, Returns(pa.int64())]: return pc.add(left, right)Example (AnyArrow with type_bound):
class Double(ScalarFunction): @classmethod def compute( cls, value: Annotated[pa.Array, Param(doc="Numeric value", type_bound=pa.types.is_numeric)], ) -> Annotated[pa.Array, Returns()]: return pc.multiply(value, 2)Attributes
attribute arrow_type
Section titled “attribute arrow_type”The Arrow data type, Python type
(int/str/float/bool/bytes), or None for AnyArrow (accepts any type).
attribute type_bound
Section titled “attribute type_bound”TypeBoundPredicate | Sequence[TypeBoundPredicate] | None
Type predicate(s) for validating input column types.
Only meaningful when arrow_type is None (AnyArrow).
attribute varargs
Section titled “attribute varargs”bool
If True, this parameter collects all remaining positional arguments as a list of arrays.
attribute position
Section titled “attribute position”int | None
Explicit column position (for class-level attributes). None means position is inferred from method signature order.
attribute choices
Section titled “attribute choices”Sequence[Any] | None
Closed set of allowed values, surfaced for agent discovery.
Advisory for a columnar Param: it is published through
vgi_function_arguments() but NOT enforced per row by the framework
(validate column contents in compute() if required). On a scalar
ConstParam the equivalent constraint IS enforced at bind.
attribute ge
Section titled “attribute ge”float | int | None
Value must be >= this (inclusive lower bound). Advisory on Param
(see choices).
attribute le
Section titled “attribute le”float | int | None
Value must be <= this (inclusive upper bound). Advisory on Param.
attribute gt
Section titled “attribute gt”float | int | None
Value must be > this (exclusive lower bound). Advisory on Param.
attribute lt
Section titled “attribute lt”float | int | None
Value must be < this (exclusive upper bound).
attribute pattern
Section titled “attribute pattern”str | None
Regex the value must match (for string parameters).
class Returns
Section titled “class Returns”Description
Metadata for compute() return type.
Use with Annotated to declare the output Arrow type for catalog registration.
The annotation indicates that compute() returns a pa.Array of the specified type.
Attributes
attribute arrow_type
Section titled “attribute arrow_type”The Arrow data type of the output, or None for AnyArrow
(dynamic output type determined at bind time).
class Secret
Section titled “class Secret”Description
Metadata for secrets parameter in compute() or on_bind().
Use with Annotated to declare parameters that receive secret values
from the DuckDB SecretManager. Secrets contain multiple key-value pairs
where keys are strings and values can be any DuckDB type.
Attributes
attribute secret_type
Section titled “attribute secret_type”str
The secret type to look up (e.g., “vgi_example”, “s3”). Required — C++ enforces type matching.
attribute scope
Section titled “attribute scope”str | None
Optional static scope for pre-resolution (resolved before first bind call).
class SecretLookupEntry
Section titled “class SecretLookupEntry”Bases: ArrowSerializableDataclass
Description
A request to look up a specific secret.
Used both in function metadata (static requirements from annotations)
and in runtime requests (dynamic scoped lookups). Also used directly
as the catalog-level secret requirement type (replacing the former
CatalogSecretRequirement which had identical fields).
Extends ArrowSerializableDataclass so it can be serialized in
catalog FunctionInfo payloads.
secret_type is required — C++ enforces type matching.
Supported lookup patterns:
- By type only: SecretLookupEntry(secret_type=“s3”)
- By type + scope: SecretLookupEntry(secret_type=“s3”, scope=“s3://bucket/”)
- By type + name: SecretLookupEntry(secret_type=“s3”, secret_name=“my_cred”)
- By type + scope + name: all three fields set
Attributes
attribute secret_type
Section titled “attribute secret_type”str
The DuckDB secret type to match (required; C++ enforces type matching).
attribute scope
Section titled “attribute scope”str | None
Optional URI prefix the secret must apply to.
attribute secret_name
Section titled “attribute secret_name”str | None
Optional name of the specific secret to resolve.
Methods
method to_dict
Section titled “method to_dict”to_dict() -> dict[str, str | None]Convert to dictionary for serialization.
method from_dict
Section titled “method from_dict”from_dict(d: dict[str, Any]) -> SecretLookupEntryCreate from dictionary.
class Setting
Section titled “class Setting”Description
Metadata for settings parameter in compute().
Use with Annotated to declare parameters that receive setting values from the DuckDB session. Settings are string key-value pairs.
Attributes
attribute key
Section titled “attribute key”str | None
The setting key name. If not provided, uses the parameter name.
class TableInput
Section titled “class TableInput”Description
Sentinel type for table input parameters in table-in-out functions.
Use this as the type parameter for Arg to declare which argument
receives the streaming table input. Every TableInOutFunction must have
exactly one TableInput argument, and it must be positional (not named).
The TableInput argument determines which table expression feeds the
function when called from SQL. It doesn’t correspond to an actual Arrow
value - the table data arrives as streaming RecordBatches via process().
class TaggedUnion
Section titled “class TaggedUnion”Description
A decoded union-typed argument: which member is set (tag) and its value.
DuckDB UNION / Arrow union arguments are tagged: the discriminator
(which member is present) lives in the Arrow UnionScalar.type_code, not
in the member value. Plain Scalar.as_py() returns only the member value
and drops that tag, so union arguments are decoded into this wrapper
instead — tag is the active member’s field name and value is its
Python value.
Example:
config: Annotated[TaggedUnion, Arg("config", arrow_type=pa.sparse_union([...]))]...cfg = params.args.config # TaggedUnion(tag=..., value=...)if cfg.tag == "random_forest_classifier": grid = cfg.value # the member struct, as a dictAttributes
function validate_const_arg_constraints
Section titled “function validate_const_arg_constraints”validate_const_arg_constraints(
const_params: Mapping[str, Arg[Any]],
arguments: Arguments,
) -> None
Enforce const-argument value constraints at bind time.
Const arguments are bind-time scalars, so validate them once (not per batch /
per group). Reuses Arg._validate, raising ArgumentValidationError
for any value that violates a declared choices/ge/le/gt/lt/
pattern constraint — so a bad value fails fast at bind instead of silently
reaching compute()/update(). Shared by the scalar and aggregate bind
paths so both enforce identically (and match the legacy descriptor path).