Skip to main content

Usage

Documentation Index

Fetch the complete documentation index at: https://docs.typesafe.ai/llms.txt Use this file to discover all available pages before exploring further.

Usage

Guides and patterns for working with the TypeSafe Python SDK.

Calling the System One API

import asyncio

from typesafe_sdk import AsyncTypeSafeClient, Choice, Noul, Score


async def main() -> None:
    async with AsyncTypeSafeClient() as client:
        result = await client.system_one(
            "I was charged twice. Please help ASAP.",
            {
                "billing": Noul(instructions="Is this about billing?"),
                "tone": Choice(
                    instructions="What is the tone?",
                    criteria={"calm": None, "angry": None},
                ),
                "urgency": Score(
                    instructions="How urgent is this?",
                    criteria=["low", "medium", "high"],
                ),
            },
        )
        print(
            result.nouls["billing"].noul,
            result.choices["tone"].choice,
            result.scores["urgency"].score,
        )


asyncio.run(main())
from typesafe_sdk import Choice, Noul, Score, TypeSafeClient

client = TypeSafeClient()
state = "I was charged twice. Please help ASAP."
questions = {
    "billing": Noul(instructions="Is this about billing?"),
    "tone": Choice(
        instructions="What is the tone?", criteria={"calm": None, "angry": None}
    ),
    "urgency": Score(
        instructions="How urgent is this?", criteria=["low", "medium", "high"]
    ),
}
result = client.system_one(state, questions)
print(
    result.nouls["billing"].noul,
    result.choices["tone"].choice,
    result.scores["urgency"].score,
)

Typed system_one responses

It is possible to provide a response model to system_one to make using the response more type-safe:

from typesafe_sdk import Noul, NoulAnswer, SystemOneResponse, TypeSafeClient


class BillingResponse(SystemOneResponse):
    billing: NoulAnswer


with TypeSafeClient() as client:
    result = client.system_one(
        "I was charged twice.",
        {"billing": Noul(instructions="Is this about billing?")},
        response_model=BillingResponse,
    )
    assert 0 <= result.billing.noul <= 1
    assert result.billing == result.nouls["billing"]
    print(result.request_id)

Custom response types

It is also possible to define a completely new response model without inheriting from SystemOneResponse:

from pydantic import BaseModel

from typesafe_sdk import Noul, NoulAnswer, TypeSafeClient


class BillingAnswers(BaseModel):
    billing: NoulAnswer


class BillingResponse(BaseModel):
    answers: BillingAnswers


result = TypeSafeClient().system_one(
    "I was charged twice.",
    {"billing": Noul(instructions="Is this about billing?")},
    response_model=BillingResponse,
)
assert 0 <= result.answers.billing.noul <= 1

Choosing a model

Inspect the available models:

from typesafe_sdk import TypeSafeClient

print(TypeSafeClient().models.list())

Select the model when constructing a client:

client = TypeSafeClient(model="jev")

See the Models resource reference for details.

Retries

Pass a custom RetryPolicy as retry on the client or per call.

from typesafe_sdk import RetryPolicy, TypeSafeClient

client = TypeSafeClient(retry=RetryPolicy(max_retries=3, backoff_max=0.2, timeout=1.0))
from typesafe_sdk import RetryPolicy

client.system_one(
    state, questions, retry=RetryPolicy(max_retries=3, backoff_max=0.2, timeout=1.0)
)

Error handling

Handle exceptions raised by the SDK:

from typesafe_sdk import TypeSafeAPIError

try:
    client.system_one(state, questions)
except TypeSafeAPIError as error:
    print(error.status, error.request_id)

Logging

The SDK logs to the typesafe_sdk logger. Configure it according to standard logging guide:

import logging

logging.getLogger("typesafe_sdk").setLevel(logging.DEBUG)

Or set TYPESAFE_LOG_LEVEL to one of debug, info, warning, error, or off before importing the SDK.

info logs one summary line per request; debug also logs request and response headers and bodies. Secret headers — authorization, API keys, cookies, and any header whose name contains token or secret — are redacted from log output. Request and response bodies are not redacted.

Environment variables

The SDK reads and uses the following environment variables:

VariableConfiguresDefault
TYPESAFE_API_KEYAPI key (required)—
TYPESAFE_BASE_URLAPI root URLhttps://api.typesafe.ai
TYPESAFE_DEFAULT_MODELDefault modeljev-latest
TYPESAFE_LOG_LEVELtypesafe_sdk logger level, applied once at importunset

See the constants reference for SDK defaults.

Forward compatibility

The SDK keeps working as the TypeSafe API evolves, so you can adopt new API features before an SDK release adds first-class support for them.

Extra request fields

Send request fields this SDK version predates with extra_body:

from typesafe_sdk import Noul, TypeSafeClient

with TypeSafeClient() as client:
    client.system_one(
        "I was charged twice.",
        {"billing": Noul(instructions="About billing?")},
        extra_body={"beam_width": 4},
    )

Raw question dictionaries

from typesafe_sdk import TypeSafeClient

with TypeSafeClient() as client:
    client.system_one(
        "I was charged twice.",
        {"billing": {"type": "noul", "instructions": "About billing?", "weight": 2}},
    )

Tip

Tip

Unknown fields are a forward-compatibility escape hatch. Ignore their type-checking errors and prefer upgrading the SDK instead.

Unknown answer kinds

The SDK logs a warning and skips unrecognized answer kinds. Use raw_http_response to inspect the complete API response, including those answers:

from typesafe_sdk import Noul, TypeSafeClient

result = TypeSafeClient().system_one(
    "I was charged twice.",
    {"billing": Noul(instructions="Is this about billing?")},
)
raw_answers = result.raw_http_response.json()["answers"]

Unknown response fields

Unknown extra fields on recognized responses are ignored.