Aito SDK

The Aito SDK consists of:

  • schema: Data structure for the Aito Database Schema

  • client: A versatile client to make requests to an Aito Database Instance

  • v2: A client for the Aito v2 API

  • client_request: Request objects used in AitoClient request so that you don’t have to worry about the Aito API endpoint

  • client_response: Enriched response objects returned after executing a request with the AitoClient

  • api: Different useful functions that uses an AitoClient object to interact with an Aito Database Instance

  • DataFrameHandler: Utility to read, write, and convert a Pandas DataFrame in accordance to a Aito Table Schema

Note

We highly recommend you to take a look at the quickstart guide to uploading data if you haven’t already.

AitoSchema

Before uploading data into Aito, you need to create a table with a AitoTableSchema.

You can infer a table schema from a Pandas DataFrame with infer_from_pandas_data_frame().

You can also create a table schema column-by-column and infer the AitoColumnTypeSchema with infer_from_samples().

AitoClient

The AitoClient offers different functions to send a Request object to your Aito instance.

  • Make a request: request()

  • Make a request asynchronously using AIOHTTP ClientSession: async_request()

  • Bounded asynchronous request with asyncio semaphore: bounded_async_request()

  • Make multiple requests asynchronously: batch_requests()

AitoClientV2

The AitoClientV2 talks to the v2 API. It is a separate class from the v1 AitoClient rather than a flag on it, because the two APIs return genuinely different response shapes — the reasoning is written up in docs/v2-client-design.md.

from aito.client.v2 import AitoClientV2

client = AitoClientV2(instance_url, api_key)

prediction = client.predict(
    from_table='invoices', where={'vendor': 'Elenia Oy'}, predict='gl_code')
print(prediction.first.value, prediction.first.probability)

Querying:

Note

The named methods post to v2’s enforced named endpoints, which validate that the body matches the operation. A mismatch is a 400 naming the endpoint that wants that body, rather than a query that silently does something else.

Manipulating the database:

Note

These operations require the client to be setup with the READ-WRITE API key

Errors carry a machine-readable code, so you branch on the code rather than on the text of the message:

from aito.client.v2 import AitoV2Error

try:
    client.delete_collection('invoices')
except AitoV2Error as err:
    if not err.is_not_found:   # a 404 here is the ordinary "drop if exists" case
        raise

Responses carry the engine’s non-fatal warnings, which are the only in-band signal that the server answered a slightly different query than the one you sent:

res = client.query({'from': 'invoices', 'where': {'no_such_column': 'x'}})
for warning in res.warnings:
    print(warning.code, warning.message)

# or make it a hard failure:
strict = AitoClientV2(instance_url, api_key, on_warning='raise')

Aito reports its own server-side processing time in the x-aitoai-response-time header, which is what an application should surface rather than the round trip. The parsed body does not carry it, so pass on_response:

timings = []
client = AitoClientV2(instance_url, api_key,
                      on_response=lambda resp, path: timings.append(
                          (path, float(resp.headers['x-aitoai-response-time']))))

A complete runnable example — create a collection, load it, predict, explain, evaluate, drop it — is in examples/v2_quickstart.py.

AitoAPI

aito.api module offers different functions that takes a Aito Client object as the first argument

Troubleshooting

The easiest way to troubleshoot the Aito SDK is by enabling the debug logging. You can enable the debug logging by:

import logging

logging.basicConfig(level=logging.DEBUG)