Skip to main content

castiron

A schema→typed-code compiler for Python.

Point castiron at a schema source — a Supabase URL, your SQL migrations, or a live database — and get typed models (and, soon, a typed client for tables, views, and RPCs). A check mode will fail CI when your application code drifts from the schema. No database connection required for the OpenAPI and migrations sources.

"It's cast-iron. It doesn't care." — and neither should your types drift.

📖 Documentation


🚧 Status: pre-alpha. castiron is on PyPI and installable, but it is young and moving fast: the pipeline, sources, and emitters are still being built out, and APIs may change between releases. It is the successor to supabase-pydantic, carrying forward its schema-fidelity engine on a source-agnostic architecture.

Quickstart

uv add cast-iron       # or: pip install cast-iron
castiron --version     # the command has no hyphen

You install the hyphenated cast-iron and run the unhyphenated castiron. PyPI does not allow castiron as a distribution name, so the hyphen belongs to the distribution and nothing else — the command, the import package (import castiron), and this repository all stay unhyphenated.

Generate typed Pydantic models from a Supabase project — one command, no database connection, no driver, no connection string:

export CASTIRON_KEY='eyJhbGciOi...'
castiron gen --from https://abcdefgh.supabase.co --emit pydantic
castiron: read 6 tables, 1 enum and 4 functions from https://abcdefgh.supabase.co/rest/v1/
castiron: wrote schema.py (14.2 kB)

--from also takes a path, so a saved OpenAPI document regenerates offline — useful in CI and air-gapped builds:

castiron gen --from ./openapi.json --emit pydantic --output src/myapp/models

You get one file with Row, Insert, Update and operational models, enum classes, and nested foreign-key relationships:

class Orders(OrdersBaseSchema):
    """Orders Schema for Pydantic.

    Customer orders.

    Inherits from OrdersBaseSchema. Add any customization here.
    """

    # Foreign Keys
    user: Users | None = Field(default=None)
    order_items: list[OrderItems] | None = Field(default=None)

Output is deterministic — the same schema and options produce the same bytes, every time — and lint-clean as emitted, under ruff's F, UP and I rules at ruff's own defaults. See The generated code for that promise, its limits, and how enum member names are derived.

Put your settings in pyproject.toml and the flags go away (the API key is deliberately rejected there — that file gets committed):

[tool.castiron]
from = "https://abcdefgh.supabase.co"
emit = ["pydantic"]
output = "src/myapp/models"

Full walkthrough: Quickstart · CLI reference · Configuration

The idea

flowchart LR
    S1["OpenAPI / PostgREST"] --> IR
    S2["SQL migrations<br/>(planned)"] --> IR
    S3["Live database<br/>(planned)"] --> IR
    IR["Schema IR<br/>one typed, formal model"] --> E1["Pydantic v2"]
    IR --> E2["SQLAlchemy<br/>(planned)"]
    IR --> E3["Typed Supabase client<br/>(planned)"]
    IR --> CHK["check<br/>drift guard in CI<br/>(planned)"]

Pluggable sources parse a schema into one formalized Schema IR; pluggable emitters turn the IR into typed code. check — planned, not yet a command — will re-emit in memory and fail if the committed output has drifted.

Honest about what it knows

The OpenAPI source needs no database credentials and sees everything your API key can see — column types, nullability, primary keys, single-column foreign keys, enums, and RPC signatures. It cannot see unique or check constraints, identity/generated columns, exact integer widths below bigint, or function return types. castiron does not guess at them; it documents them and warns when one is about to change your output.

Read What the OpenAPI source can and cannot see before you trust a generated constraint.

Why "castiron"

Cast iron is durable, low-maintenance, and does one job for decades. It also puns on type casting — casting an untyped schema into hard, checked types.

Development

castiron uses uv and hatchling.

uv sync                 # create the environment and install dev deps
uv run castiron --version
make validate           # ruff + vulture + mypy + pytest (the pre-push gate)
make serve-docs         # preview the documentation site

See CONTRIBUTING.md.

License

MIT © Kevin Boehm

Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cast_iron-0.3.1.tar.gz (679.6 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cast_iron-0.3.1-py3-none-any.whl (146.3 kB view details)

Uploaded Python 3

File details

Details for the file cast_iron-0.3.1.tar.gz.

File metadata

  • Download URL: cast_iron-0.3.1.tar.gz
  • Upload date:
  • Size: 679.6 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cast_iron-0.3.1.tar.gz
Algorithm Hash digest
SHA256 8612029af21b9c1071ca10a01e4dc30ee4f7be6a381fbcc0517c745569713677
MD5 a651b91476b6fa49aadb81611f55bfbd
BLAKE2b-256 02c851e653234585b2ce0d39de9329af5490b5123e282cbcb3cf499713f9a949

See more details on using hashes here.

Provenance

The following attestation bundles were made for cast_iron-0.3.1.tar.gz:

Publisher: release.yml on kmbhm1/castiron

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file cast_iron-0.3.1-py3-none-any.whl.

File metadata

  • Download URL: cast_iron-0.3.1-py3-none-any.whl
  • Upload date:
  • Size: 146.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/7.0.0 CPython/3.13.14

File hashes

Hashes for cast_iron-0.3.1-py3-none-any.whl
Algorithm Hash digest
SHA256 fc9466e2bdf152bbe7f8fc6ec5a1b8e4f6802bdf67840bb21659d8dcedfafc5d
MD5 b3c95a93695f5d66d30df5a2ee4e2fdf
BLAKE2b-256 c1b92a907bcb6ed66deae0867857cd8b4f901532124eb88aa367b856a04293ce

See more details on using hashes here.

Provenance

The following attestation bundles were made for cast_iron-0.3.1-py3-none-any.whl:

Publisher: release.yml on kmbhm1/castiron

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Release history Release notifications | RSS feed

0.6.0

2 files

0.5.0

2 files

0.4.0

2 files

This release

0.3.1 This release

2 files

0.3.0

2 files

0.2.0

2 files

0.1.1

2 files

0.1.0

2 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