aice-recommendation
Python SDK for the AICE Recommendation Engine: catalog management, event
tracking, recommendations, training jobs and config. A thin httpx client;
all scoring happens server-side.
This is the 0.0.x line, for the engine currently running at
https://reco.aiceafrica.com (unprefixed routes such as /users,
/ingest). 0.0.3 will target the vertical-routed engine and adds
vertical= to the client; the rest of the API stays the same.
Installation
pip install aice-recommendation==0.0.2
Requires Python 3.11+. The only dependency is httpx.
Quick start
from aice_recommendation import RecommendationClient
client = RecommendationClient(
base_url="https://reco.aiceafrica.com",
api_key="sk-proj_...", # the project's key; it decides the project and vertical
)
# Users and items must exist before events can reference them.
client.create_user("user-1", metadata={"region": "KE"})
client.create_item("item-42", metadata={"category": "electronics"})
client.track("user-1", "item-42", "purchase")
job = client.train(epochs=20)
print(client.job_status(job.job_id).status) # pending → running → complete / failed
recs = client.recommend("user-1", n=10)
for r in recs.recommendations:
print(r.rank, r.item_id, r.score, r.explanation)
client.close()
The client is also a context manager (with RecommendationClient(...) as client:).
Async variant, same methods:
from aice_recommendation import AsyncRecommendationClient
async with AsyncRecommendationClient(base_url="https://reco.aiceafrica.com", api_key=KEY) as client:
recs = await client.recommend("user-1", n=10)
Several events at once
from aice_recommendation import Event
result = client.track_batch([
Event("user-1", "item-42", "view"),
Event("user-2", "item-7", "purchase", metadata={"price": 12.5}),
])
print(result.ingested_count, result.failed_count, result.errors)
On the current server the batch is all or nothing: if any event is invalid
(unknown user or item, more than 50 metadata keys, event_type over 100
characters), the whole call raises ValidationError and nothing is ingested.
API surface
| Endpoint | Method |
|---|---|
POST /users |
create_user(user_id, metadata=None) |
GET /users/{id} |
get_user(user_id) |
PUT /users/{id} |
update_user(user_id, metadata=…) |
POST /items |
create_item(item_id, metadata=None) |
GET /items/{id} |
get_item(item_id) |
PUT /items/{id} |
update_item(item_id, metadata=…) |
POST /ingest |
track(user_id, item_id, event_type, timestamp=None, metadata=None) |
POST /ingest/batch |
track_batch(events) |
GET /recommend/{user_id} |
recommend(user_id, n=10, persist=False) |
POST /train |
train(epochs=20) |
GET /train/{job_id} |
job_status(job_id) |
GET /config |
get_config() |
PUT /config |
update_config(overrides) |
GET /verticals |
list_verticals() |
GET /verticals/{name} |
get_vertical(name) |
The /admin routes (creating organizations and projects, rotating keys) are
not covered; keys are issued by the AICE console.
Ids are sent as a single escaped path segment, so an id containing /, ?
or # can't reach a different route. The current server still can't look up
an id containing / (it answers 404).
Errors
Every HTTP error raises a subclass of RecommendationError, which carries
status_code and the server's raw detail:
| Status | Exception |
|---|---|
| 400, 422 | ValidationError |
| 401 | AuthenticationError |
| 403 | ForbiddenError |
| 404 | NotFoundError |
| 409 | ConflictError |
| 5xx | ServerError |
| other 4xx | RecommendationError |
from aice_recommendation import NotFoundError
try:
client.get_user("missing")
except NotFoundError as err:
print(err.status_code, err) # 404 User not found.
Requests are not retried, because the server doesn't deduplicate retried
writes and a retried track could count an event twice. Timeouts and
connection failures surface as httpx exceptions (httpx.TimeoutException,
httpx.ConnectError, …).
Migrating from reco (RecoClient)
| Before | After |
|---|---|
from reco import RecoClient |
from aice_recommendation import RecommendationClient |
RecoError |
RecommendationError |
AuthError |
AuthenticationError |
Item.organization_id |
Item.project_id |
Method names and their arguments are unchanged.
Development
pip install -e ".[dev]"
pytest # offline tests; the live test is skipped
RECO_API_KEY=sk-proj_... pytest tests/test_live.py
The live test runs the full flow against RECO_BASE_URL (default
https://reco.aiceafrica.com). Each run leaves sdktest-* users, items and
events, plus one 1-epoch training job, on that project. It never changes the
project config.
Metadata
Release files for aice-recommendation 0.0.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| aice_recommendation-0.0.2.tar.gz | 11.6 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| aice_recommendation-0.0.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 21.4 kB
Release files / aice_recommendation-0.0.2.tar.gz
| Download URL | aice_recommendation-0.0.2.tar.gz |
|---|---|
| Size | 11.6 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
842f42b81a50549df257204911d6590e2542f561d7eabb07188bb4a1a12c723b
|
|
BLAKE2b-256 checksum How to use checksums |
72c5b8cab5094cfb5e75457f2c3cc7e16afaef1668cc1bdaa1153d27785b8b62
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Release files / aice_recommendation-0.0.2-py3-none-any.whl
| Download URL | aice_recommendation-0.0.2-py3-none-any.whl |
|---|---|
| Size | 9.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c6e386040e07faa03d4c916d62007546d5813a168fba155b308a5b8c5b8ad308
|
|
BLAKE2b-256 checksum How to use checksums |
0c0fbac19423e08d78c920ffd5b9a44c8b5e6bfd067cd7b2cb5a7777a7d33791
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.13.7
|
Security for aice-recommendation 0.0.2
Provenance
Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.
No provenance found
None of the files in this release were uploaded with provenance metadata.
A note on package security
PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.
To learn more about protecting yourself from malicious actors, visit our package security documentation.