httpx. It mirrors the TypeScript SDK and exposes a fluent builder over the same typed-graph workflow definition.
Installation
Requires Python 3.13 (the SDK pins to>=3.13,<3.14 today; this is expected to loosen before the official launch).
anyformat; the import path uses the dotted namespace anyformat.sdk (transport) and anyformat.workflow (schema factories).
Authentication
Pass the API key toClient, or set ANYFORMAT_API_KEY in the environment and read it from there.
Basic usage
Full flow: build a workflow with a fluent builder, run a document, await the typed result.Result exposes typed scalar accessors via result.fields[name] for linear workflows (one untagged extraction) and the full envelope at result.raw for everything else (parse markdown, multiple extractions per split, classifications, splits).
Async usage
AsyncClient is the async sibling — every builder, handle, and result method has an async counterpart.
Builder methods
All node types in the typed graph are exposed as fluent methods.parse is required; the others are optional and can be chained in any topology the API allows.
| Method | What it adds | Notes |
|---|---|---|
.parse(*, mode='standard', prompt_hint=None, figure_enhancement=False) | The required parse node | All args keyword-only. mode='agentic' for the per-block agentic strategy. |
.classify(*categories) | A classify node | Categories from ClassifyCategory(id=..., name=..., description=...) |
.split(*rules, route_from=None) | A splitter node | Use route_from= after .classify() to wire which branch fans out |
.extract(fields, *, branch=None, lookup_files=None) | An extract node | branch= is required after .classify() / .split(); Schema.* factories produce field objects |
.validate(*rules, branch=None) | A validate node | Attaches to the most recent extract (or the one named by branch) |
.create() | Persists the workflow | Returns a Workflow handle you can .run(...) on |
.build() | Same shape without the network call | Returns a WorkflowDefinition — useful for tests and inspection |
Workflow.run(file=None, *, text=None) accepts either file: bytes | pathlib.Path | str (a file path) or text= (raw text — useful for emails / plain-text bodies). Exactly one must be set. Returns a Run handle; Run.wait(timeout=300, poll_interval=3) returns the Result.
Managing workflows
The client lists and deletes the workflows on your account:| Method | What it does | Returns |
|---|---|---|
client.list_workflows(page=1, page_size=20, status=None) | One page of your workflows | list[Workflow] — each is .run(...)-able (page_size max 100) |
client.delete_workflow(workflow_id) | Soft-deletes a workflow | The deleted workflow_id (a 404 raises NotFound) |
AsyncClient: await client.list_workflows(...) returns list[AsyncWorkflow] and await client.delete_workflow(id) returns the id.
Reading results
Error handling
The SDK raises typed exceptions you can catch:APIError exposes .status_code, .error_code, and .detail. The wire-format error codes (e.g. EXTRACTION_FAILED, RATE_LIMITED) are documented at Errors.
Webhooks (not on the SDK surface yet)
Client doesn’t expose webhook endpoints today. Until it does, register and delete webhooks with httpx directly:
Links
- PyPI —
pip install anyformat - TypeScript SDK — the same fluent shape in TS
- Coding assistant — let Claude drive anyformat from your editor
