Skip to main content

dottxt Python Library

The .txt Python library provides access to the .txt REST API from Python 3.10+ applications.

Request API access here.

It provides two client surfaces:

  • DotTxt for sync access with DotTxt helpers and OpenAI-compatible namespaces
  • AsyncDotTxt for async access with the same helper semantics

The API uses:

  • base URL: https://api.dottxt.ai/v1
  • auth: Authorization: Bearer $DOTTXT_API_KEY
  • primary endpoints: GET /models and POST /chat/completions

Install

pip install dottxt

Configure

export DOTTXT_API_KEY="your-api-key"

All clients in this package read DOTTXT_API_KEY by default.

Optional overrides:

export DOTTXT_BASE_URL="https://api.dottxt.ai/v1"
export DOTTXT_MODEL="<model-id>"

CLI

Use the dottxt CLI for login, model discovery, and one-off generation.

Client Surfaces

Choose the client that matches the shape you want to work with:

  • DotTxt.generate(...) and AsyncDotTxt.generate(...) accept JSON Schema as a string/object, plus any typed schema supported by Pydantic TypeAdapter (for example: Pydantic models, Enums, Literals, Unions, Optionals, and typed containers), and objects exposing to_json() -> str (for example Genson). Root {"type":"structural-tag", ...} schema objects are accepted without JSON Schema metaschema validation. They return a validated Pydantic model instance for Pydantic input, or parsed JSON for the other schema input types.
  • DotTxt and AsyncDotTxt also expose OpenAI SDK chat and models namespaces for direct SDK access alongside DotTxt helpers.

For constructor kwargs passed through to the OpenAI SDK client (DotTxt(..., **client_kwargs) / AsyncDotTxt(..., **client_kwargs)), see OpenAI Python base client parameters.

Native DotTxt Client

from typing import Literal

from pydantic import BaseModel, Field

from dottxt import DotTxt


class IncidentSummary(BaseModel):
    severity: Literal["low", "medium", "high"]
    team: str = Field(max_length=32)


client = DotTxt()

result = client.generate(
    model="openai/gpt-oss-20b",
    input="Summarize this incident: checkout errors are blocking purchases.",
    response_format=IncidentSummary,
)
print(result)
# Example model output:
# severity='high' team='checkout'
print(result.model_dump())
# Example output:
# {'severity': 'high', 'team': 'checkout'}

models = client.models.list()
print([model.id for model in models.data])
# Example output:
# ['openai/gpt-oss-20b', 'openai/gpt-4.1-mini']

Async Native Client

import asyncio
from typing import Literal

from pydantic import BaseModel, Field

from dottxt import AsyncDotTxt


class IncidentSummary(BaseModel):
    severity: Literal["low", "medium", "high"]
    team: str = Field(max_length=32)


async def main() -> None:
    client = AsyncDotTxt()
    result = await client.generate(
        model="openai/gpt-oss-20b",
        input="Summarize this incident: checkout errors are blocking purchases.",
        response_format=IncidentSummary,
    )
    print(result)
    # Example model output:
    # severity='high' team='checkout'
    print(result.model_dump())
    # Example output:
    # {'severity': 'high', 'team': 'checkout'}

    models = await client.models.list()
    print([model.id for model in models.data])
    # Example output:
    # ['openai/gpt-oss-20b', 'openai/gpt-4.1-mini']


asyncio.run(main())

For DotTxt and AsyncDotTxt, generate(...) accepts response_format as:

  • a Pydantic model class
  • a TypedDict type
  • a dataclass type
  • an Enum class
  • a typing.Literal[...] type
  • a typing.Union[...] type
  • a typing.Optional[...] type
  • typed containers such as list[...], dict[...], tuple[...]
  • a JSON string containing JSON Schema
  • a JSON object (dict)
  • an object exposing to_json() -> str that returns JSON Schema

Notes:

  • Raw list instances as response_format are not supported.
  • Root {"type":"structural-tag", ...} schema objects bypass metaschema checks.

For direct chat.completions.create(...), pass the wrapped OpenAI-style response_format payload yourself.

Use DotTxt.models.list() and AsyncDotTxt.models.list() for model listing.

Streaming Fields

AsyncDotTxt.stream(...) yields PatchEvent objects as the model fills in a schema-constrained response. The wire format is the gateway's stream: "patch" mode (RFC 6902 JSON Patch over NDJSON).

Each event carries the raw op (event.op) and an independent deep copy of the document so far (event.snapshot). For the common case of reacting to one field at a time, use the demux properties: event.field is the JSON Pointer with the leading / stripped ("intent", "steps/0", "address/city"), and event.value is the op's value.

import asyncio
from typing import Literal

from pydantic import BaseModel

from dottxt import AsyncDotTxt


class SupportTicket(BaseModel):
    # Field order = arrival order. Put what unblocks downstream work first.
    intent: Literal["billing", "technical", "account"]
    urgency: Literal["low", "medium", "high", "critical"]
    reply: str


async def main() -> None:
    client = AsyncDotTxt()
    stream = client.stream(
        model="openai/gpt-oss-20b",
        response_format=SupportTicket,
        input="I was charged twice this month, please refund the duplicate.",
    )
    async for event in stream:
        match event.field:
            case "intent":
                print(f"dispatching to {event.value} queue")
            case "urgency" if event.value == "critical":
                print("paging oncall")
            case "reply":
                print(f"reply: {event.value}")


asyncio.run(main())

The routing decision can fire tens of milliseconds into generation while reply continues to stream. See docs/client.md for the full reference.

OpenAI-Compatible Usage

Use DotTxt when you want an OpenAI-style client surface with chat.completions.create(...) and models.list().

from typing import Literal

from pydantic import BaseModel, Field

from dottxt import DotTxt as OpenAI


class IncidentSummary(BaseModel):
    severity: Literal["low", "medium", "high"]
    team: str = Field(max_length=32)


client = OpenAI()

completion = client.chat.completions.create(
    model="openai/gpt-oss-20b",
    messages=[
        {
            "role": "user",
            "content": "Summarize this incident: checkout errors are blocking purchases.",
        }
    ],
    response_format={
        "type": "json_schema",
        "json_schema": {
            "name": "incident_summary",
            "schema": IncidentSummary.model_json_schema(),
        },
    },
)
print(completion.choices[0].message.content)
# Example output:
# {"severity":"high","team":"checkout"}

models = client.models.list()
print([model.id for model in models.data])
# Example output:
# ['openai/gpt-oss-20b', 'openai/gpt-4.1-mini']

The compatibility surface expects the wrapped OpenAI-style response_format payload:

  • {"type": "json_schema", "json_schema": {...}}

Examples

Metadata

Release files for dottxt 0.3.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 dottxt 0.3.0
File Size Uploaded
dottxt-0.3.0.tar.gz 131.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for dottxt 0.3.0
File Interpreter ABI Platform
dottxt-0.3.0-py3-none-any.whl Python 3 none any Details

Total release size: 160.6 kB

Release files / dottxt-0.3.0.tar.gz

Download URL dottxt-0.3.0.tar.gz
Size 131.6 kB
Tags Source
SHA-256 checksum
How to use checksums
0940594b8611d4b7166de9af89a7c4694afa42accd0e94bbceb365fa0f3f72f3
BLAKE2b-256 checksum
How to use checksums
d123c63310fd4a97d3d75c800c064f3faf0610ef15ee308c26ce3c749fe0f7e0
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

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 Jun 5, 2026.

Transparency log

Release files / dottxt-0.3.0-py3-none-any.whl

Download URL dottxt-0.3.0-py3-none-any.whl
Size 29.0 kB
Tags Python 3
SHA-256 checksum
How to use checksums
578a17683130584184b5e03d9dff25009c5c066735fa02d1454860a05b566149
BLAKE2b-256 checksum
How to use checksums
59f167cb217bcde6c21072a5739fff32f60044ce86b332a78eb049807260b7ec
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.13

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 Jun 5, 2026.

Transparency log

Release history Release notifications | RSS feed

This release

0.3.0 This release

2 release files

0.2.0

2 release files

0.1.5

1 release file

0.1.4

1 release file

0.1.3

1 release file

0.1.2

1 release file

0.1.1

1 release file

0.0.1

1 release file

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