Python SDK (v2)
aitoai is the official Python client. It ships a client for the v2 API โ
available since aitoai 0.7.0 โ alongside the v1 client, and a command-line
tool. Every snippet on this page that talks to the
sandbox runs as written.
- PyPI: aitoai
- Source: github.com/AitoDotAI/aito-python-tools
- SDK reference: aitodotai.github.io/aito-python-tools
Install
pip install aitoai
That installs the API clients only (requests, packaging, jsonschema,
aiohttp, ndjson). The command-line tool, schema inference and file conversion need
the dataframe toolchain, which is an extra (since aitoai 0.7.0):
pip install 'aitoai[cli]'
Pick the API version
Each API version has its own package, and its meaning never changes:
from aito.v2 import Client # the v2 API
from aito.v1 import Client # the v1 API
aito.Client is the default version, and moves only on a major release of
the package: since aitoai 1.0.0 it is the v2 client (0.x: v1). It is fine for
a quickstart; production code should import the version it means, so an SDK
upgrade cannot change the API underneath it.
The pre-0.7 paths (aito.client.AitoClient, aito.client.v2.AitoClientV2,
aito.api) were removed in aitoai 1.0.0: importing one raises an ImportError
that names the replacement. To stay on the v1 API, from aito.v1 import Client,
or pin aitoai<1.
Connect
from aito.v2 import Client
client = Client('https://shared.aito.ai/db/aito-demo',
'yg4rTlXkqDzm4y8gPeY75HCKaNwfbTQ2si64ONTi', env='v2')
print(client.get_version()['version'])
The first argument is the database URL (โฆ/db/<name>), not an endpoint.
env selects an environment; leave it out for master.
The client checks the key on construction, so a wrong URL or key fails here
rather than on the first query.
Query and predict
Each operation is a method that posts to its own endpoint and returns a parsed
response. A predicted value is hit.value, its probability hit.probability:
from aito.v2 import Client
client = Client('https://shared.aito.ai/db/aito-demo',
'yg4rTlXkqDzm4y8gPeY75HCKaNwfbTQ2si64ONTi', env='v2')
res = client.predict(from_table='invoices',
where={'Description': {'$match': 'cloud services'}},
predict='GLCode', limit=3, why=True)
top = res.first
print(top.value, round(top.probability, 3))
print(top.why['type']) # the explanation tree, as in the curl examples
rows = client.query({'from': 'products', 'where': {'name': {'$match': 'milk'}},
'select': ['name', 'price'], 'limit': 2})
for row in rows:
print(row['name'], row['price'])
The other operations follow the same shape: search, recommend, match,
relate, estimate, aggregate, evaluate and batch, plus query for any
body the universal _query endpoint accepts (that is also
the way to send an operation the client has no method for). get_schema()
reads the schema, and delete_collection(name) drops a collection.
Errors and warnings
Errors carry the machine-readable code from the API, so you branch on the code rather than on the message text:
from aito.v2 import Client, Error
client = Client('https://shared.aito.ai/db/aito-demo',
'yg4rTlXkqDzm4y8gPeY75HCKaNwfbTQ2si64ONTi', env='v2')
try:
client.predict(from_table='invoices', predict='no_such_field')
except Error as err:
print(err.status_code, err.code)
Responses also carry the engine's non-fatal warnings โ the only signal
that it answered a slightly different query than the one you sent (an unknown
field in where, say). They are logged by default; on_warning='raise' makes
them errors:
from aito.v2 import Client
client = Client('https://shared.aito.ai/db/aito-demo',
'yg4rTlXkqDzm4y8gPeY75HCKaNwfbTQ2si64ONTi', env='v2')
res = client.query({'from': 'invoices', 'where': {'no_such_column': 'x'}})
for warning in res.warnings:
print(warning.code)
Load your own data
Writes need a read-write key for your own instance (the sandbox is read-only โ ask for an instance). Declare a collection, upload rows in batches, then optimize once after the bulk load:
from aito.v2 import Client
client = Client('https://your-instance.aito.ai/db/your-db', '<read-write-key>')
client.create_collection('invoices', {
'vendor': {'type': 'String'},
'description': {'type': 'Text', 'analyzer': 'english'},
'amount': {'type': 'Decimal'},
'gl_code': {'type': 'String'},
})
client.upload_entries('invoices', rows, batch_size=1000) # rows: a list of dicts
client.optimize('invoices')
To try a change without touching master, branch an environment with
client.branch_env('staging') and point a client at it with env='staging';
see Environments. The SDK repository's
examples/v2_quickstart.py
does the whole round trip โ create, load, predict, explain, evaluate, drop.
Versions
| aitoai | What changed for v2 users |
|---|---|
| 0.6.0 | First v2 client (aito.client.v2.AitoClientV2) |
| 0.7.0 | aito.v2 / aito.v1 packages and the default aito.Client; the CLI toolchain moved to the [cli] extra |
| 1.0.0 | aito.Client is v2; the pre-0.7 import paths are removed (the CLI stays on v1 through 1.x) |
The full history is in the changelog.