> ## Documentation Index
> Fetch the complete documentation index at: https://repost.sh/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Python Code Generation

> Configure Python output, understand the generated package, regenerate safely, and keep the runtime and descriptors compatible.

The Python generator writes a complete importable package into your repository. Your schema owns the public models and method tree; `repost-client` owns runtime behavior, so generated code stays small and reviewable.

## Configure the output

```repost repost/schema.repost theme={"languages":{"custom":["/languages/repost.json"]}}
generator sdk {
  language = "python"
  output   = "../src/my_service/repost_sdk"
}
```

`output` is required and resolves relative to the schema file. Its final directory name must be a valid Python package name because it becomes the import path. Keep each generator in its own directory.

The output is engine-owned. Do not hand-edit it or add application files inside it. Regeneration stages the complete tree and replaces engine-owned files atomically.

## What gets emitted

| File                  | Purpose                                                                                |
| --------------------- | -------------------------------------------------------------------------------------- |
| `__init__.py`         | Stable public exports for the client, models, and enums.                               |
| `client.py`           | `RepostClient`, the `webhooks` method tree, lifecycle methods, and typed send methods. |
| `models.py`           | Keyword-only dataclasses and string enums.                                             |
| `descriptors.py`      | Field order, wire names, defaults, and event bindings read by the runtime.             |
| `schemas.json`        | JSON Schema for every deployed event version.                                          |
| `schema.repost`       | A copy of the schema used for generation.                                              |
| `.repost-client.json` | Engine version, schema hash, generated files, and content hashes.                      |

Commit the whole package with the schema migration that produced it.

## Generated models and methods

For this schema:

```repost theme={"languages":{"custom":["/languages/repost.json"]}}
model User {
  id       String
  nickname String?
}

type User {
  created
}
```

the package exports a keyword-only `User` dataclass and a method at `client.webhooks.user.created(...)`. Every method requires `customer_id` and `data`, and accepts optional `idempotency_key` and `cancel` keyword arguments.

Optional fields retain three distinct states: `UNSET` omits the field or applies its schema default, `None` sends JSON null when the schema permits it, and any other value is serialized. Payload fields follow schema declaration order and use their `@map` wire names.

## Regenerate and check drift

<CodeGroup>
  ```bash Generate theme={"languages":{"custom":["/languages/repost.json"]}}
  repost schema generate
  ```

  ```bash Record a migration and generate theme={"languages":{"custom":["/languages/repost.json"]}}
  repost schema migrate dev --name add_user_nickname
  ```

  ```bash Verify committed output theme={"languages":{"custom":["/languages/repost.json"]}}
  repost schema migrate status
  repost schema generate --check
  ```
</CodeGroup>

`migrate dev` records the schema change and regenerates every configured language. `generate --check` writes nothing and exits non-zero when committed output is stale, making it the CI gate for generated Python packages.

In a monorepo, one schema can contain several generators. One CLI run updates them as a unit; see [Polyglot monorepos](/docs/send/monorepos) for output and commit rules.

## Runtime compatibility

`RepostClient()` checks the generated descriptor format against the installed runtime before accepting a send. `RepostDescriptorVersionError` means you must regenerate the package or upgrade `repost-client`.

Generated clients also guard imports of the runtime surfaces they require. An older runtime fails immediately with an actionable upgrade message instead of falling through to a partially compatible send path.

## Continue

<Columns cols={3} className="gap-y-4">
  <Card title="Configuration" icon="sliders-horizontal" href="/docs/send/python/configuration" cta="Configure" arrow="true">
    Configure the runtime owned by the generated client.
  </Card>

  <Card title="Testing" icon="flask-conical" href="/docs/send/python/testing" cta="Test" arrow="true">
    Exercise generated methods with the native no-network testing kit.
  </Card>

  <Card title="Migrations & deploys" icon="git-branch" href="/docs/send/deployments" cta="Version" arrow="true">
    Version and deploy the schema that drives generation.
  </Card>
</Columns>
