Compute
The import path for the released package is listed on the compatibility matrix.
How the released Python client is shaped: imports, submitting a task spec, awaiting a terminal state without blocking, canceling work, and reading a streamed result bundle.
Before you install
This page prints no package name. The released package, its version and the Python versions it is tested against are published on the compatibility matrix, because they move with each release.
Your base URL and current API version appear in the portal under developer settings, and in the API description you download.
Keep your work key in your operating system credential store or your team's secret manager. Pass the client a reference to it, never the secret itself.
Imports and the call shape
The client mirrors the API namespaces, so a call site shows the authority it needs.
# The import path for the released package is listed on the compatibility matrix.
client = lithi.Client(credential=credential_from_store())
quote = await client.work.quote(task_spec)
Work submission lives under client.work. Configuration, identities, sources, profiles and finance live under their own namespaces, and a work key cannot reach any of them.
Your task_spec carries the same seven objects everywhere: workflow, input, parameters, quality, policy, output and limits.
Wait for a terminal state without blocking
Terminal states are SUCCEEDED, PARTIAL, FAILED and CANCELLED. Everything else means keep waiting.
TERMINAL = {"SUCCEEDED", "PARTIAL", "FAILED", "CANCELLED"}
async def wait_for_terminal(client, job_id):
while True:
status = await client.work.status(job_id=job_id)
if status.state in TERMINAL:
return status
await sleep_until(status.valid_until)
Wait on valid_until rather than a fixed interval. A read past its valid_until is stale, whatever your timer says.
Cancel work you no longer want
Cancellation is a request, not an instant stop. The job moves to CANCELLING, then to CANCELLED once it settles.
Work already accepted before your request is charged under your applicable commercial policy. Read the receipt rather than assuming a canceled job costs nothing.
Cancel the job through the cancel operation. Ending your own Python task only ends your read.
Read a streamed result bundle
Stream part files if the data is large, but treat them as incomplete until the manifest is present.
manifest = await client.work.result(job_id=job_id)
# result-manifest.json is written last and binds every file, count and schema.
for part in manifest.data_parts:
async for row in read_part(part):
handle(row)
Accepted rows sit under data/part-*. Typed failures, abstentions and preserved disagreements sit in their own directories beside it, so read all four before you call a run clean.
Tabular output arrives with lithi_status, lithi_result, lithi_error_code, lithi_confidence, lithi_evidence, lithi_verification and lithi_usage appended.
When something refuses
Each operation carries its own generated error_schema, so there is no one error table to import. Every refusal carries a safe reason and a non-empty next action.
Keep EDGE_ABUSE_LIMITED, CANONICAL_ADMISSION_LIMITED, CANONICAL_BUDGET_EXHAUSTED and CELL_CAPACITY_UNAVAILABLE in separate branches. Two of them describe authority, and no retry fixes those.
Confirm what your version supports on the client compatibility matrix, and see what each file in a result bundle holds before you parse one.