Skip to main content

nace-sdk (Python)

The official Python client for the Drex API: calibrated answers to typed questions (POST /v1/systemone) and document jobs — parse, split, classify, extract and ground.

The client is built on the TypeSafe AI Python SDK (MIT; see THIRD_PARTY_NOTICES.md): system_one, Noul, Choice, Score, SystemOneResponse with .nouls, .choices and .scores, RetryPolicy and the error classes match typesafe-sdk, so TypeSafeClient code runs on NaceClient after renaming the imports. It depends only on httpx, pydantic and typing-extensions.

pip install nace-sdk
export NACE_API_KEY=nace_sk_...

Python 3.11 or later. Create a key on the API keys page.

Decisions

from nace_sdk import Choice, NaceClient, Noul, Score

with NaceClient() as client:  # reads NACE_API_KEY, NACE_BASE_URL, NACE_DEFAULT_DECISION_MODEL
    result = client.system_one(
        state="I was charged twice for my March invoice.",
        questions={
            "wants_refund": Noul(instructions="Is the customer asking for a refund?"),
            "topic": Choice(instructions="Which topic is it?", criteria={"billing": None, "shipping": None, "other": None}),
            "urgency": Score(instructions="How urgent is it?", criteria=["low", "medium", "high"]),
        },
    )

print(result.nouls["wants_refund"].noul)
print(result.choices["topic"].choice, result.request_id)

AsyncNaceClient has the same methods, awaited.

Documents

from nace_sdk import NaceClient, UrlSource

with NaceClient() as client:
    # An https:// URL whose last path segment names the file: its extension picks the parser.
    created = client.documents.parse("https://example.com/invoice.pdf", output={"formats": ["markdown"]})
    job = client.jobs.wait(created.job_id)
    print(job.result["document"]["markdown"])

    # A URL whose last segment isn't the file's name needs a file_name.
    client.documents.parse(UrlSource(url="https://arxiv.org/pdf/1706.03762", file_name="attention.pdf"))

    # on_conflict="new_version" replaces the file at that path instead of failing with path_conflict.
    file = client.documents.upload("invoice.pdf", path="invoices/invoice.pdf", on_conflict="new_version")
    extracted = client.documents.extract(
        file.as_source(),
        schema={"type": "object", "properties": {"total": {"type": "number"}}},
        wait_seconds=60,
    )

    # Or save the schema once and name it.
    saved = client.extraction_schemas.create("Invoice", {"type": "object", "properties": {"total": {"type": "number"}}})
    client.documents.extract(file.as_source(), schema_id=saved.schema_id)

Uploads go straight to the document service with a one-use token, never with your API key; files of 32 MiB and more go up in parts. To run a resumable upload yourself, use create_upload_session, upload_part, complete_upload_session, get_upload_session (which parts landed) and abort_upload_session; create_upload_grant mints a token for another client to upload with. Every document job and upload session create carries an Idempotency-Key, so retries never start a second job or session. The /v1 routes send no Access-Control-Allow-Origin header, so keep Drex calls on your server: a browser uploads with a grant your server mints, and opens job files through jobs.file_link links.

client.jobs has get, list, iter, wait, delete, events, get_request (the request a job ran under), rows (a parsed sheet's rows, a page at a time), file_link (a signed link to a stored file) and download (any job file, including full Markdown that is still being prepared). client.extraction_schemas has list, iter, get, create, list_versions and iter_versions (oldest first), get_version and create_version; creates are not retried unless you pass retry, since a retry could save a second schema.

Errors and retries

Every failure raises a NaceError. HTTP failures are NaceAPIError subclasses (NaceBadRequestError, NaceAuthenticationError, NaceInsufficientCreditError, NacePermissionDeniedError, NaceNotFoundError, NaceConflictError, NaceUnprocessableEntityError, NaceRateLimitError, NaceInternalServerError, NaceOverloadedError) with status, body, request_id, type, code, issues, detail and server_retryable; a success whose body doesn't match is a NaceAPIResponseValidationError, and a failed connection a NaceAPIConnectionError (NaceAPITimeoutError on a timeout). jobs.wait raises NaceJobFailedError or NaceJobTimeoutError. The client retries 408, 429, 5xx, dropped connections and timeouts (2 retries within a 30 s budget, 0.5 s doubling to 5 s, honoring retry-after-ms), except an error the server marks "retryable": false. The budget counts from the first attempt, so with the defaults an attempt that fails after 30 s, such as one that hit the 60 s timeout, is not retried: raise RetryPolicy(timeout=...) above your attempts and waits, or pass None. jobs.download retries opening each file the same way, but not a transfer cut off midway; jobs.events is not retried, and saved-schema creates aren't unless you pass retry.

from nace_sdk import NaceClient, RetryPolicy

# Up to 5 attempts of up to 90 s each, and the waits between them.
client = NaceClient(timeout=90, retry=RetryPolicy(max_retries=4, timeout=500))

The SDK logs to the nace_sdk logger: NACE_LOG_LEVEL=debug sets its level, and a handler (for example logging.basicConfig()) shows the records. At debug it logs headers and bodies, with the API key, upload tokens and PDF passwords redacted.

The nace command line tool is pip install nace-cli; it reads the key nace login saves through nace_sdk.credentials. Full guide: Python SDK.

License

Apache-2.0

Metadata

Release files for nace-sdk 0.1.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for nace-sdk 0.1.0
File Size Uploaded
nace_sdk-0.1.0.tar.gz 54.3 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for nace-sdk 0.1.0
File Interpreter ABI Platform
nace_sdk-0.1.0-py3-none-any.whl Python 3 none any Details

Total release size: 120.9 kB

Release files / nace_sdk-0.1.0.tar.gz

Download URL nace_sdk-0.1.0.tar.gz
Size 54.3 kB
Tags Source
SHA-256 checksum
How to use checksums
7165b20acf8b89ca2c1d45dec9daebfb3429a58be1c71739941ff6bf22f099f8
BLAKE2b-256 checksum
How to use checksums
821e46fe70f0ba96676c7fa4e9c0557638ada825b4ba06fa14b6495807b88db2
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release files / nace_sdk-0.1.0-py3-none-any.whl

Download URL nace_sdk-0.1.0-py3-none-any.whl
Size 66.5 kB
Tags Python 3
SHA-256 checksum
How to use checksums
ae8ea7cbd3de6825c02c39492926532bc3a6719fa7c413c9c7f04b3d027c3d12
BLAKE2b-256 checksum
How to use checksums
ae4d3461b06f3392c96e3e0df44c9d3da38fee67b407b1757ed38affbb90afff
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.14

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 8, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.1.0 This release

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page