aito.client.v2.client.AitoClientV2

class aito.client.v2.client.AitoClientV2(instance_url: str, api_key: str, env: str | None = None, meta: bool = False, on_warning: str = 'log', timeout: float = 30.0, check_credentials: bool = True, on_response: Callable[[Any, str], None] | None = None)

Bases: object

A client that connects to the Aito v2 API

Parameters:
  • instance_url (str) – the database URL, e.g. https://shared.aito.ai/db/my-db, with no /api/... suffix

  • api_key (str) – the database API key

  • env (Optional[str]) – the environment to address; None addresses master

  • meta (bool) – request the meta block on every response, which names the engine that answered. Off by default, matching the API’s own opt-in

  • on_warning (str) – what to do when a response carries warnings — 'ignore', 'log' (the default), or 'raise'

  • timeout (float) – the request timeout in seconds

  • check_credentials (bool) – verify the URL and key by fetching the schema

  • on_response (Optional[Callable[[Any, str], None]]) – called as on_response(response, path) after every HTTP call, successful or not, with the raw requests.Response. The only way to reach anything the parsed body does not carry — response headers in particular. Aito reports its own server-side processing time in x-aitoai-response-time (milliseconds), which is what an app should show a user rather than the round trip, since the round trip is mostly network. Keep the callback cheap and non-throwing: it runs inline, and an exception in it would surface as a failed request

Raises:
  • ValueError – the environment name is one the engine reserves

  • AitoV2Error – the credentials could not be verified

>>> client = AitoClientV2(your_instance_url, your_api_key)
>>> res = client.predict(
...     from_table='invoices', where={'vendor': 'Elenia Oy'}, predict='gl_code')
>>> res.first.value, res.first.probability
('6110', 0.9656853940913004)

Methods

aggregate(from_table, aggregate[, where])

compute aggregates over the rows a filter selects

batch(queries[, timeout])

run several queries in one request

branch_env(name)

branch a new environment off master

copy_schema(query)

copy a schema, via POST /schema/_copy

create_collection(name, columns)

create a v2 collection

delete_collection(name)

delete a collection or legacy table and its data

delete_entries(from_table, where)

delete the rows a filter selects

delete_env(name)

delete an environment

estimate(from_table, estimate[, where, select])

estimate the numeric value of a field

evaluate(query[, timeout])

run a held-out evaluation and return its metrics

get_operators()

the live operator inventory of this instance

get_schema([table])

the schema of the database, or of one table or collection

get_version()

the version of the Aito instance

list_envs()

the environments of this database

match(from_table, match[, where, select, ...])

rank the candidate values of a link field against some evidence

modify(operations)

apply table maintenance operations atomically

optimize(name)

rebuild a collection's index after a bulk load

predict(from_table, predict[, where, ...])

predict the values of a field, ranked by probability

query(query[, timeout])

run any query body against POST /_query

recommend(from_table, recommend, goal[, ...])

rank the values of a field by how well they achieve a goal

relate(from_table, relate[, where, select, ...])

find the statistical relationships between a condition and some fields

request(method, path[, query, timeout])

make a raw request to a v2 endpoint and return the parsed JSON

search(from_table[, where, select, ...])

retrieve matching rows

upload_entries(name, entries[, batch_size])

insert rows into a collection, in batches

Attributes

api_url

the base URL of the v2 API, including the environment segment

headers

the headers sent with every request

aggregate(from_table: str, aggregate: List[str], where: Dict | None = None) V2AggregateResponse

compute aggregates over the rows a filter selects

Parameters:
  • from_table (str) – the collection or table to read

  • aggregate (List[str]) – the aggregate expressions, e.g. ['amount.$mean']. The supported operators are $mean, $sum, $min and $max

  • where (Optional[Dict]) – the filter

Return type:

V2AggregateResponse

property api_url: str

the base URL of the v2 API, including the environment segment

An environment is two path segments, /env/<name>. The single dotted segment (/db/<db>/env.<name>) does not match the route at all.

Return type:

str

batch(queries: List[Dict], timeout: float | None = None) V2BatchResponse

run several queries in one request

All or nothing: a batch is not a way to collect per-query failures. One bad element fails the whole request — a query naming a missing table makes the call answer 404 not_found, with no partial results — so this raises rather than returning a batch with an error in it.

Parameters:
  • queries (List[Dict]) – the query bodies

  • timeout (Optional[float]) – override the client’s timeout for this call

Raises:

AitoV2Error – any one of the queries failed

Return type:

V2BatchResponse

branch_env(name: str) Dict

branch a new environment off master

Branching returns no key — the database key authorizes the new environment.

Parameters:

name (str) – the new environment name

Raises:

ValueError – the name is one the engine reserves

Return type:

Dict

copy_schema(query: Dict) Dict

copy a schema, via POST /schema/_copy

Parameters:

query (Dict) – the copy specification

Return type:

Dict

create_collection(name: str, columns: Dict) Dict

create a v2 collection

Parameters:
  • name (str) – the collection name

  • columns (Dict) – the column definitions, the same map a v1 table schema uses — types String / Text / Decimal / Int / Boolean and the array and Json types, plus link, analyzer and nullable

Return type:

Dict

>>> client.create_collection('invoices', {
...     'vendor': {'type': 'String'},
...     'description': {'type': 'Text', 'analyzer': 'english'},
...     'gl_code': {'type': 'String'},
... })
{'status': 'created', 'table': 'invoices', 'type': 'collection'}
delete_collection(name: str) Dict

delete a collection or legacy table and its data

Parameters:

name (str) – the collection or table name

Return type:

Dict

delete_entries(from_table: str, where: Dict) Dict

delete the rows a filter selects

Parameters:
  • from_table (str) – the collection to delete from

  • where (Dict) – which rows to delete. Must select something: an empty filter matches every row, so it is refused rather than treated as “delete everything”

Raises:

ValueErrorwhere is empty

Return type:

Dict

>>> client.delete_entries('invoices', {'gl_code': '6110'})
delete_env(name: str) Dict

delete an environment

Parameters:

name (str) – the environment name

Return type:

Dict

estimate(from_table: str, estimate: str, where: Dict | None = None, select: List | None = None) V2EstimateResponse

estimate the numeric value of a field

Parameters:
  • from_table (str) – the collection or table to learn from

  • estimate (str) – the numeric field to estimate

  • where (Optional[Dict]) – the evidence

  • select (Optional[List]) – the payload keys to return, e.g. ['value', 'why']

Return type:

V2EstimateResponse

evaluate(query: Dict, timeout: float | None = 600.0) V2EvaluationResponse

run a held-out evaluation and return its metrics

_evaluate is its own endpoint on v2 — it is not a _query key, and the grammar rejects one. The body is the v1 body unchanged: a test (or testSource) selector plus an evaluate query.

Parameters:
  • query (Dict) – the evaluation body

  • timeout (Optional[float]) – the request timeout, defaulting to 10 minutes because an evaluation over a large collection is slow by nature

Return type:

V2EvaluationResponse

>>> res = client.evaluate({
...     'test': {'$index': {'$mod': [10, 0]}},
...     'evaluate': {
...         'from': 'invoices',
...         'where': {'vendor': {'$get': 'vendor'}},
...         'predict': 'gl_code',
...     },
... })
>>> res.accuracy, res.base_accuracy
(1.0, 0.2777777777777778)
get_operators() Dict

the live operator inventory of this instance

The set of query operators the instance actually supports, generated from the engine’s own registry rather than from documentation — useful for checking whether a capability exists on the deploy you are talking to.

Return type:

Dict

get_schema(table: str | None = None) Dict

the schema of the database, or of one table or collection

Parameters:

table (Optional[str]) – the table or collection name; None returns the database

Return type:

Dict

get_version() Dict

the version of the Aito instance

Return type:

Dict

property headers: Dict

the headers sent with every request

Return type:

Dict

list_envs() Dict

the environments of this database

Return type:

Dict

match(from_table: str, match: str, where: Dict | None = None, select: List | None = None, limit: int | None = None, why: bool = False) V2RowsResponse

rank the candidate values of a link field against some evidence

The operator behind record matching — a bank payment against the open invoice it settles, say. Candidates come back ranked by $p, and it generalizes: evidence never seen verbatim still ranks, on the strength of the parts of it that were.

Hits carry v1’s feature and field keys alongside $p and $value. That is deliberate — v2 keeps a v1 key and adds the v2 one rather than replacing it, so a v1-era caller moving to /api/v2 over a legacy table keeps working. $value is the canonical one to read.

Parameters:
  • from_table (str) – the collection holding the evidence rows

  • match (str) – the link field whose values are the candidates

  • where (Optional[Dict]) – the evidence to match on

  • select (Optional[List]) – the columns to return, defaulting to ['$p', '$value'] (plus $why when why is set)

  • limit (Optional[int]) – the maximum number of candidates

  • why (bool) – include the $why explanation tree in the default select

Return type:

V2RowsResponse

>>> res = client.match(
...     from_table='payments', match='invoice_id',
...     where={'description': 'KULJETUSLIIKE OY VIITE 999', 'amount': 10734.5})
>>> res.first.value, res.first.probability
('INV-000002', 0.000209)
modify(operations: Dict | List[Dict]) Dict

apply table maintenance operations atomically

Despite the endpoint’s name this does not modify rows — use upload_entries() and delete_entries() for that. _modify applies table-level operations (optimize, repair, migrate, copy, warm) as one transaction, which is what makes it worth having over calling optimize() in a loop: several tables move together, all or nothing.

Parameters:

operations (Union[Dict, List[Dict]]) – one operation, or a list of them. A list is sent as {'operations': [...]}, the shape the endpoint expects

Return type:

Dict

>>> client.modify([{'optimize': 'invoices'}, {'optimize': 'vendors'}])
optimize(name: str) Dict

rebuild a collection’s index after a bulk load

Worth doing, not optional: on a freshly bulk-loaded collection the per-segment statistics have not been merged, so predict returns flatter and batch-count-dependent posteriors until this runs. It is idempotent.

Parameters:

name (str) – the collection name

Return type:

Dict

predict(from_table: str, predict: str, where: Dict | None = None, select: List | None = None, limit: int | None = None, why: bool = False) V2RowsResponse

predict the values of a field, ranked by probability

Parameters:
  • from_table (str) – the collection or table to learn from

  • predict (str) – the field to predict

  • where (Optional[Dict]) – the evidence

  • select (Optional[List]) – the columns to return, defaulting to ['$p', '$value'] (plus $why when why is set)

  • limit (Optional[int]) – the maximum number of candidate values to return. Note that the API’s own default returns only the top handful, so raise it to read a full distribution

  • why (bool) – include the $why explanation tree in the default select

Return type:

V2RowsResponse

>>> res = client.predict(
...     from_table='invoices', where={'vendor': 'Elenia Oy'}, predict='gl_code')
>>> res.first.value
'6110'
query(query: Dict, timeout: float | None = None) V2RowsResponse

run any query body against POST /_query

The universal surface and the escape hatch: _query enforces no mode, so anything the grammar accepts runs here. The named methods below are preferable where one fits, because their endpoints validate that the body matches the operation.

Parameters:
  • query (Dict) – the query body

  • timeout (Optional[float]) – override the client’s timeout for this call

Return type:

V2RowsResponse

recommend(from_table: str, recommend: str, goal: Dict, where: Dict | None = None, select: List | None = None, limit: int | None = None) V2RowsResponse

rank the values of a field by how well they achieve a goal

Parameters:
  • from_table (str) – the collection or table to learn from

  • recommend (str) – the field to recommend a value of

  • goal (Dict) – the outcome to optimize for, e.g. {'purchase': True}

  • where (Optional[Dict]) – the context

  • select (Optional[List]) – the columns to return. When recommend names a link column, the default already returns every column of the linked row

  • limit (Optional[int]) – the maximum number of hits

Return type:

V2RowsResponse

relate(from_table: str, relate: str | List[str] | Dict, where: Dict | None = None, select: List | None = None, order_by: Any | None = None, limit: int | None = None) V2RowsResponse

find the statistical relationships between a condition and some fields

Parameters:
  • from_table (str) – the collection to analyse. Relate runs on collections; a legacy table answers 501

  • relate (Union[str, List[str], Dict]) – the field or fields to relate, or a $patterns specification. v2 takes a list of field names where v1 took a bare string, so a single name given as a string is wrapped for you

  • where (Optional[Dict]) – the condition to relate against

  • select (Optional[List]) – the columns to return, defaulting to ['related', 'condition', 'lift', 'fs']

  • order_by (Optional[Any]) – the ordering, defaulting to 'lift'

  • limit (Optional[int]) – the maximum number of hits

Return type:

V2RowsResponse

request(method: str, path: str, query: Dict | List | None = None, timeout: float | None = None) Any

make a raw request to a v2 endpoint and return the parsed JSON

The transport underneath every other method. Use it to reach an endpoint the client has no named method for.

Parameters:
  • method (str) – the HTTP method

  • path (str) – the path below /api/v2, e.g. /_query

  • query (Optional[Union[Dict, List]]) – the request body, if any

  • timeout (Optional[float]) – override the client’s timeout for this call

Raises:

AitoV2Error – the request failed or the response was not 2xx

Return type:

Any

search(from_table: str, where: Dict | None = None, select: List | None = None, order_by: Any | None = None, limit: int | None = None, offset: int | None = None) V2RowsResponse

retrieve matching rows

The rows surface. The endpoint rejects a body carrying predict, recommend or relate, naming the endpoint that wants it.

Parameters:
  • from_table (str) – the collection or table to read

  • where (Optional[Dict]) – the filter

  • select (Optional[List]) – the columns to return

  • order_by (Optional[Any]) – the ordering

  • limit (Optional[int]) – the maximum number of hits; pass 0 to read only total

  • offset (Optional[int]) – the number of hits to skip

Return type:

V2RowsResponse

upload_entries(name: str, entries: List[Dict], batch_size: int = 1000) int

insert rows into a collection, in batches

Parameters:
  • name (str) – the collection name

  • entries (List[Dict]) – the rows to insert

  • batch_size (int) – the number of rows per request

Returns:

the number of rows inserted

Return type:

int