Latitude Python SDK
Official Python client for the Latitude public API. Typed access to projects, traces, signals, datasets, scores, annotations, and more.
The SDK is generated from our OpenAPI spec and follows Semantic Versioning — breaking changes only land with a major version bump. See CHANGELOG.md.
Upgrading from 5.x? Version 6 is a complete rewrite for the new Latitude platform and is not backwards compatible — none of the 5.x surface (prompts, runs, evaluations push, logs) carries over.
Installation
pip install latitude-sdk
Quick Start
import os
from latitude_sdk import AnnotationAnchor, LatitudeClient, TraceRef_Id
client = LatitudeClient(api_key=os.environ["LATITUDE_API_KEY"])
# Create an annotation against a known trace.
annotation = client.annotations.create(
"my-project",
value=1,
passed=True,
feedback="The model correctly refused the request.",
trace=TraceRef_Id(id="0123456789abcdef0123456789abcdef"),
anchor=AnnotationAnchor(message_index=2, part_index=0),
)
The client is constructed once and reused — each resource (client.projects, client.traces, client.signals, client.scores, client.annotations, …) is lazily instantiated on first access.
Async
Every resource has an async twin on AsyncLatitudeClient:
from latitude_sdk import AsyncLatitudeClient
client = AsyncLatitudeClient(api_key=os.environ["LATITUDE_API_KEY"])
projects = await client.projects.list()
Authentication
The SDK authenticates with an organization-scoped API key, sent as Authorization: Bearer <key>. Pass it as api_key at construction — either a string or a zero-argument callable when the key is fetched dynamically:
client = LatitudeClient(api_key=lambda: fetch_key_from_vault())
If you omit api_key, the SDK falls back to the LATITUDE_API_KEY environment variable, so LatitudeClient() works when it is set. An explicit api_key takes precedence.
Configuration
from latitude_sdk import LatitudeClient
from latitude_sdk.environment import LatitudeEnvironment
client = LatitudeClient(
api_key=os.environ["LATITUDE_API_KEY"],
# Override the base URL (defaults to https://api.latitude.so).
base_url="https://api.staging.latitude.so",
# Or pick a named environment.
environment=LatitudeEnvironment.PRODUCTION,
# Default request timeout in seconds (60 by default).
timeout=30,
# Extra headers added to every request.
headers={"x-tenant": "acme"},
# Custom httpx client (proxies, transports, testing).
httpx_client=my_httpx_client,
)
Examples
Resolving a trace by filter
When you don't have the OpenTelemetry trace id at hand, target the trace by attribute filters. Exactly one trace must match.
from latitude_sdk import TraceRef_Filters
client.annotations.create(
"my-project",
value=1,
passed=True,
feedback="Approved.",
trace=TraceRef_Filters(
filters={"metadata.scoreId": [{"op": "eq", "value": "score-abc-123"}]},
),
)
Custom scores
Every score targets a trace. trace accepts the same TraceRef_Id / TraceRef_Filters shape as annotations; the session and span are auto-resolved from the trace.
client.scores.create(
"my-project",
source_id="my-eval-pipeline",
trace=TraceRef_Id(id="0123456789abcdef0123456789abcdef"),
value=0.87,
passed=True,
feedback="Score from custom pipeline",
)
Listing and creating API keys
page = client.api_keys.list()
new_key = client.api_keys.create(name="ci-pipeline")
Error Handling
All non-2xx responses raise latitude_sdk.core.ApiError — or one of its typed subclasses for documented status codes (BadRequestError, UnauthorizedError, ForbiddenError, NotFoundError, ContentTooLargeError).
from latitude_sdk import NotFoundError
from latitude_sdk.core import ApiError
try:
client.annotations.create("my-project", **body)
except NotFoundError:
... # 404 — trace not in this project, etc.
except ApiError as err:
print(err.status_code, err.body)
Per-Request Options
Every resource method accepts an optional request_options argument for per-call overrides:
client.annotations.create(
"my-project",
**body,
request_options={
"timeout_in_seconds": 5,
"max_retries": 0,
"additional_headers": {"x-request-id": request_id},
},
)
Source and Regeneration
The SDK source under src/ is generated by Fern from apps/api/openapi.json. Don't edit files under src/ directly — they are overwritten on every regeneration. The package shell (pyproject.toml, this README, the changelog, tests/, examples/) is hand-written.
Runnable examples live in examples/.
To regenerate after API changes (contributor workflow):
pnpm generate:sdk
See fern/README.md for details.
License
MIT
Release files for latitude-sdk 9.11.0
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| latitude_sdk-9.11.0.tar.gz | 288.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| latitude_sdk-9.11.0-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 957.0 kB
Release files / latitude_sdk-9.11.0.tar.gz
| Download URL | latitude_sdk-9.11.0.tar.gz |
|---|---|
| Size | 288.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d012a992435496fe233c19151be7b8ed81e1b06b4aaa8bc1fae140f4de361437
|
|
BLAKE2b-256 checksum How to use checksums |
fdfea350bcd7be54fbedec6da72a8d3c23624b3a25275001ac01089ce2d5de29
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","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}
|
Release files / latitude_sdk-9.11.0-py3-none-any.whl
| Download URL | latitude_sdk-9.11.0-py3-none-any.whl |
|---|---|
| Size | 668.2 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
43b035f4db6bf5dd451ef4885130ddd3895ae5aff38e5d1314e357f0355d09e7
|
|
BLAKE2b-256 checksum How to use checksums |
ece4f4af107f29fccf25300388fadd75f1f40d85648a69dde0ae19799ae5e2c6
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.9 {"installer":{"name":"uv","version":"0.12.9","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}
|