Skip to main content
Both clients are published as sqwishai: the Python client on PyPI and the TypeScript client on npm. They call the HTTP API for you, with retries and helpers that wait for jobs. You can also call the API over HTTP, as in the quickstart.

Install

The Python client needs Python 3.11 or newer. The TypeScript client needs Node 20 or newer. Its package is JavaScript with its type declarations, so it needs no build step of your own. It has no dependencies: the client uses the standard fetch API. PyPI and npm list every release: sqwishai on PyPI and sqwishai on npm.

Make a first call

Set SQWISH_API_KEY to an API key, then run this. It asks one yes-or-no question and prints the probability of yes.
In Python, responses are typed dictionaries. In TypeScript, wire fields keep their snake_case names, and methods use camelCase. Read the response explains what comes back. The shorter examples below use this client. In them, context and decisions hold the values above, and dataset_id (datasetId in TypeScript) is the ID of one of your datasets.

Configure the client

Both clients read the key from SQWISH_API_KEY, and the address from SQWISH_BASE_URL when you set it. An argument you pass wins.
Close a Python client when you are done with it, so its HTTP connections are released. A with block closes it for you.

Proxies and certificates

Version 0.5.0 of the Python client doesn’t read proxy settings or certificate files from the environment, such as HTTPS_PROXY or SSL_CERT_FILE. Behind a corporate proxy, pass an httpx.Client of your own. It keeps its own settings:
httpx.Client() with no arguments reads HTTPS_PROXY and SSL_CERT_FILE itself. For AsyncOneHot, pass an httpx.AsyncClient. In TypeScript, pass fetch: a fetch of your own, such as one that sends through your proxy. Node trusts the extra certificate authorities listed in NODE_EXTRA_CA_CERTS.

Async Python

AsyncOneHot has the same methods as OneHot. Open it with async with, and await each call.

Resource groups

Both clients have resource groups for datasets and their versions, families, models, fine-tuning, labelling and accounts. Where a list comes in pages, list returns one page and iter follows the cursors through the rest. The OpenAPI document is the contract. The SDK types are convenience views, and they may not have every field or route of the API. For anything the clients don’t wrap yet, call the API over HTTP.

Wait for a job or a family

A job’s wait polls until the job ends. When its timeout runs out, the waiting stops, but the job carries on. In both clients, the fine-tuning wait returns a fine-tune that succeeded, whatever its outcome. The outcome is joined when the model passed its gate. A model that joins its family doesn’t answer calls to the family’s name at once. A family that is switched on first loads the model and checks that it answers. Then it moves to it (how a family moves). families.wait(family, model) waits for that move, in both clients. It returns the family once the family serves model. Pass the job’s output_model, or the model’s number such as support-router@2.
families.wait fails at once when the wait can’t end:
  • The family is switched off, so it never moves.
  • The model failed its gate, so it never joined.
  • The model was deleted or discarded.
  • The model is not the family’s latest. A family moves only to its latest model, so it won’t move back to an older one.
If its timeout runs out first, the error says what the move waits for. Examples are the model still loading, or a place past your limit. The family carries on moving.

Retries

Both clients retry a call by themselves when it can succeed later, such as after a retryable error or a lost connection. They make two retries by default. To change that, set max_retries in Python or maxRetries in TypeScript when you make the client. It takes 0 to 10, and 0 turns retries off. Before a retry, the client waits as long as Retry-After says, when the server sends it. Otherwise it backs off exponentially, for about 4 seconds at most, with jitter. All the attempts of a call, and the waits between them, fit within its timeout. Retries and idempotency has the policy for plain HTTP calls.

Idempotency keys

Supported creates and inference send one idempotency key with every attempt of a call. Successful answers can be replayed for 24 hours. Failed or expired operations are not run again. To keep one operation across a process restart, persist a key of your own and pass it in. It is idempotency_key in Python and idempotencyKey in TypeScript. An error names the key its call sent, so you can ask about the same operation later (Errors). An organisation with zero data retention keeps no answer, so a key isn’t honoured there. A retry the client makes after a network error runs the request again, and it is charged again.

Wait for a cold model

A fine-tuned model that hasn’t been used for a while may still be loading (readiness and cold starts). With fallback set to none, a decision sent to it while it loads can fail with model_warming. That failure charged nothing, and its key keeps the failure. wait_for_warm=30 in Python, or waitForWarm: 30 in TypeScript, is the one exception to one key per call. While the model loads, the client sends the decision again after each Retry-After, for up to 30 seconds. It uses a new key each time. It does this only under a key it made itself. With your own key, it raises model_warming, and you start a new call with a new key when you choose.

Calls the clients don’t repeat

A family’s delete is never repeated by itself. Neither is a family’s switch that names served. A second call could find the family gone or moved. After an unclear failure, read the family before you send one again. Switches and keep warm have no idempotency-key contract. Before you repeat one yourself, read the family or the model (Retries and idempotency).

Errors

When the API answers with an error, the client raises an APIError in Python and throws one in TypeScript. Branch on its code. Errors lists every code. In Python, str(error) gives the API’s sentence followed by the code, the status and the request ID. In TypeScript, message gives the same. Quote it when you ask for help. After an error that is retryable, or whose idempotency status is pending, call again with the error’s key and the same input. The same key asks about the same operation. A call without it starts another, and a decision sent that way is charged as well if the first was answered.
A call that got no answer ends with a timeout or a connection error instead. That error carries the same key, as idempotency_key in Python or idempotencyKey in TypeScript. A wait helper raises JobFailed when its job ends failed or cancelled. Its job holds the whole job, with any error.