Skip to main content

Python SDK for the to11.ai platform

Project description

to11ai-sdk

Python SDK for to11.ai — the AI engineering platform for prompt management, tracing, and evals.

Use it to fetch managed prompts at runtime, wire your provider client (OpenAI, Anthropic, …) to the to11 gateway with the right auth/trace headers, and group model calls into sessions, conversations, and turns for tracing. Synchronous, snake_case, Python 3.10+. Only runtime dependency: Pydantic.

Installation

pip install to11ai-sdk
# or: uv add to11ai-sdk  ·  poetry add to11ai-sdk

The SDK's only runtime dependency is Pydantic. The provider client libraries used in the examples below (openai, anthropic) are not dependencies — install whichever you use yourself, e.g. pip install openai.

Quick start

Create a client, fetch a prompt for the current environment, and send it through the gateway with your normal provider client:

import os
from to11ai_sdk import create_client
from openai import OpenAI

to11 = create_client(
    # Each also resolves from an env var, so on a server you can pass nothing:
    base_url=os.environ.get("TO11_API_URL"),        # -> https://api.to11.ai
    api_key=os.environ.get("TO11_API_KEY"),         # -> TO11_API_KEY
    project_id=os.environ.get("TO11_PROJECT_ID"),   # -> TO11_PROJECT_ID
    env=os.environ.get("TO11_ENV"),                 # "prod", "staging", … -> TO11_ENV
)

# Fetch a released prompt for the client's project + environment, shaped for OpenAI.
prompt = to11.prompts.render("welcome-message", variables={"name": "Ada"}, format="openai")

# Point your provider client at the gateway and send it.
openai = OpenAI(**to11.openai_options())
completion = openai.chat.completions.create(
    **prompt["config"],
    messages=prompt["messages"],
    extra_headers=to11.turn().headers(prompt),  # auth + trace id + prompt provenance
)

prompt["config"] carries the model parameters, prompt["messages"] the rendered messages, and turn().headers(prompt) the headers that authenticate the gateway call and record which prompt produced the trace.

Configuring the client

create_client(...) takes keyword-only args. Each URL/credential resolves option → environment variable → built-in default, so a server app can construct it from the environment alone:

Argument Resolves from Default
base_url option → TO11_API_URL https://api.to11.ai
gateway_url option → TO11_GATEWAY_URL https://gw.to11.ai
api_key option → TO11_API_KEY — (required)
project_id option → TO11_PROJECT_ID
env option → TO11_ENV — (lowercase-kebab, 1–63 chars)
provider_api_key option — (BYOK; carried by openai_options()/anthropic_options())
format option — ("openai" | "anthropic"; omit for the neutral result)
on_unknown_role option "drop"
timeout_s / max_retries option 30.0 / 3
behavior_overrides option None

The client exposes the resolved values as read-only attributes — to11.base_url, to11.gateway_url, to11.api_key, to11.project_id, and to11.env. Use the non-secret ones (base_url/gateway_url/project_id/env) for diagnostics; api_key is exposed to build manual auth headers — treat it as a secret and never log it. provider_api_key (BYOK) is deliberately not exposed back off the client.

Fetching prompts

prompts.render(slug, ...) resolves the released prompt for the client's project_id + env in one request. Set format (on the client or per call) to get a result shaped for that provider; omit it for the provider-neutral result.

prompt = to11.prompts.render(
    "weather-concierge",
    variables={"city": "New York", "units": "fahrenheit"},
    # label=...      # override the client's environment for this call
    # subject=...    # a stable id so a weighted release pins the same caller to a variant
    # fallback=...   # a previously-rendered RenderedPrompt served on a network error
    # format="openai" | "anthropic"
    # on_unknown_role="drop" | "warn" | "error"
)
  • With format the result is spread-ready: {"messages": ..., "config": ..., "metadata": ...} (config = the version's model params; metadata = prompt/version/release provenance). For Anthropic it also carries a top-level "system".
  • Without format you get the neutral RenderedPrompt: .messages, .tools, .tool_choice, .prompt_id, .version, .version_id, .release_id, .variant_name, .content_hash, .label, .slug, .block_render_record, .model_config_ (trailing underscore avoids Pydantic's reserved name).

Authored developer blocks come back as-is; the SDK maps them per provider (OpenAI keeps developer; Anthropic folds system/developer into the top-level system). on_unknown_role controls how an unrecognized role is handled during provider conversion.

Sending through the gateway

openai_options() / anthropic_options() return spread-ready kwargs (base_url, api_key, default_headers) for a provider client pointed at the gateway; default_headers carries the static tenant auth. Add turn().headers(prompt) per call for the trace id and prompt provenance:

from anthropic import Anthropic
anthropic = Anthropic(**to11.anthropic_options())

By default the gateway runs the call on the project's configured provider credential (managed). For BYOK, set provider_api_key on create_client.

Sessions, conversations & turns

Group model calls for tracing. to11.turn() uses the client's default session; create explicit ones with to11.session(id=None) / to11.conversation(id=None). turn().headers(prompt=None) emits the session/conversation ids + a fresh traceparent (plus prompt provenance when a rendered/shaped prompt is passed) — for the gateway call you make. (This is separate from the SDK's OTel-based traceparent on its own control-plane requests.)

Managing prompts, versions & labels

Beyond render(), the prompts namespace covers the control-plane lifecycle. All of these default project_id from the client — pass it per call only to override:

to11 = create_client(api_key="...", project_id="proj_abc123")

to11.prompts.list()                                        # uses the bound project_id
to11.prompts.get(prompt_id="prompt_1")
to11.prompts.get_version(prompt_id="prompt_1", version_number=3)
to11.prompts.move_label(prompt_id="prompt_1", label="production", version_id="ver_9", reason="promote")

Full set: create, list, get, update, archive, create_version, list_versions, get_version, move_label, list_labels, and the project-label registry (list_project_labels, create_project_label, get_project_label, update_project_label, delete_project_label, list_project_label_usages, list_label_events). to11.project_environments and to11.routing_rules expose the environment and routing-rule surfaces.

update_project_label(description=None) means "leave unchanged"; pass description="" to clear it.

Error handling

To11aiError is the base; catch it broadly or match a subclass:

from to11ai_sdk import To11aiRateLimitError, PromptNotFoundError

try:
    prompt = to11.prompts.render("welcome-message")
except To11aiRateLimitError as exc:
    ...  # exc.retry_after_seconds
except PromptNotFoundError:
    ...
Class When
To11aiApiError non-2xx API response (status_code, error_code, details)
To11aiAuthError 401/403
To11aiRateLimitError 429 (retry_after_seconds)
To11aiValidationError 400
To11aiNetworkError network failure / timeout
PromptNotFoundError · LabelNotFoundError · MissingLabelError · NoActiveReleaseError · PromptPolicyViolationError · PromptLabelNotRegisteredError typed prompt-resolution errors
UnknownRoleError an unrecognized message role with on_unknown_role="error"
To11aiResponseValidationError a 2xx body that fails schema validation

Documentation

Full reference: https://docs.to11.ai/reference/python-sdk. Licensed under MPL-2.0.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

to11ai_sdk-2.0.0rc1.tar.gz (119.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

to11ai_sdk-2.0.0rc1-py3-none-any.whl (54.4 kB view details)

Uploaded Python 3

File details

Details for the file to11ai_sdk-2.0.0rc1.tar.gz.

File metadata

  • Download URL: to11ai_sdk-2.0.0rc1.tar.gz
  • Upload date:
  • Size: 119.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for to11ai_sdk-2.0.0rc1.tar.gz
Algorithm Hash digest
SHA256 1931e107a8fbb3e3df5b95d7a395e9785d46bf88787d604747dcc6ae8744b68c
MD5 498c4ee2bee98c5ed000aab32c6b28f8
BLAKE2b-256 7521f9a2dfa21cabe769b63213ee524abd1ecbeab2a274f58bf5dea377c0e556

See more details on using hashes here.

File details

Details for the file to11ai_sdk-2.0.0rc1-py3-none-any.whl.

File metadata

  • Download URL: to11ai_sdk-2.0.0rc1-py3-none-any.whl
  • Upload date:
  • Size: 54.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.31 {"installer":{"name":"uv","version":"0.11.31","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for to11ai_sdk-2.0.0rc1-py3-none-any.whl
Algorithm Hash digest
SHA256 6697124b8035ee1a1879ad4575be4a741b585ddeb5486e782ab274971920ddfd
MD5 a576ff10da286356410246dd8480dcd3
BLAKE2b-256 ffc37ee1b308e599511dd3d6c705f297131c06b0f929de80470fb05e7cb495e2

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page