Skip to main content
Sign up in the Caesar app, create an API key, and set CAESAR_API_KEY before running the SDK.

Install

The package installs as caesar-search and imports as caesar_search. Requires Python 3.10+ with httpx and Pydantic v2 (installed automatically). Current version: 0.2.0, MIT licensed.

Clients

Caesar is the synchronous client. AsyncCaesar has the identical surface with await.
Both clients are context managers; outside a with block, call close() (sync) or aclose() (async).

Methods

The core methods map to POST /v1/search, POST /v1/document, POST /v1/feedback, plus the Files knowledge base endpoints. Full request and response schemas are in the API reference.

Uploading files

upload_file() collapses the presign → upload → index flow into one call. Pass a path (the filename defaults to its basename) or bytes with filename=:
The file bytes go straight to storage via the presigned URL — the API key is never sent there. Batch several uploads with index=False, then call index_files() once. See Files for supported types, limits, and the workspace search scope.

How read() picks doc_id vs URL

The positional target is routed by shape: a UUID-shaped string is sent as doc_id; anything else is sent as canonical_url. Explicit doc_id= or url= keywords win when given. With neither, the SDK raises ValueError("provide a doc_id or a url"). Defaults: include is ["metadata", "content"]; content selection is full_document; content format is markdown; max_chars is omitted unless you pass it. See documents for the response shape.

Continuation reads

When content.truncated is true, resume from where the previous read stopped:
A non-zero start_char forces full_document selection so offsets stay contiguous against the raw document text. Combining start_char with query will not produce query-relevant selection.

Response shaping

search() exposes the response shaping controls directly:
verbosity is one of ids_only, compact, standard (the default), or full — only full includes provenance. On the wire these become response.verbosity and response.budget.max_chars_total.

Errors

All six error classes are importable from caesar_search. The hierarchy: .code is the stable machine-readable code from the error envelope; the exception message is formatted as code: message.

Retries

The client retries statuses 429, 500, 502, 503, and 504 — up to max_retries times (default 3, so 4 attempts total) with exponential backoff starting at 0.5 s and capped at 8 s. Caesar rate limits use X-RateLimit-Reset; if a numeric Retry-After header is present, the client honors it, also capped at 8 s. HTTP-date Retry-After values fall back to the exponential schedule. Timeouts and connection failures are never retried — they raise APITimeoutError / APIConnectionError immediately. After retries are exhausted, the status error for the last response is raised.

Raw responses and extra_body

client.with_raw_response mirrors all three methods with the same parameters but returns the raw httpx.Response (no model validation) — useful for headers like the rate-limit headers:
extra_body merges a dict into the request body last, so it can set fields the typed signature does not expose — and it overrides anything the SDK would have set:

Typing

Responses are Pydantic v2 models from caesar_search.models (SearchResponse, DocumentResponse, FeedbackResponse, and their nested types). The package ships py.typed, so type checkers pick everything up. Field names match the wire format exactly (search_id, doc_id, canonical_url); document metadata lives under DocumentResponse.doc, and markdown content lives under DocumentResponse.content.

For agents

  • timeout is in seconds (30.0), not milliseconds. The TypeScript SDK uses timeoutMs in milliseconds — do not carry values between them unconverted.
  • read() routes its positional argument purely by UUID shape: UUID goes as doc_id, everything else as canonical_url. Pass doc_id= or url= explicitly when ambiguity matters.
  • A non-zero start_char forces full_document selection; pairing it with query will not return query-relevant content.
  • extra_body is merged last and overrides any field the SDK builds, including the response wrapper produced by verbosity/max_chars_total.
  • Caesar() reads CAESAR_API_KEY by default. If no key is provided, API calls fail with 401 missing_api_key; fail setup early when CAESAR_API_KEY is unset.
  • Caesar rate limits use X-RateLimit-Reset; Retry-After is parsed as numeric seconds only when present. HTTP-date values silently fall back to exponential backoff, and timeouts are never retried.