Skip to main content

craftainer-crud

A generic CRUD framework for FastAPI: router factories (JSON, XML, and a small web form/component set), a CRUD interface, storage-agnostic repositories (SQLAlchemy async and in-memory), and the model and view bases they build on. A host application keeps its own models, views and settings and builds each resource on top of the generic pieces here; this package imports nothing from the host.

It is an instance of template-python-package (so it gets the devcontainer, CI, release workflow and template sync from there); see docs/TEMPLATE.md for the conventions shared by every instance. The package's own layout and rules are in src/craftainer_crud/README.md.

Install

pip install craftainer-crud            # core
pip install "craftainer-crud[mqtt]"    # + MQTT event sink/source (aiomqtt)
pip install "craftainer-crud[xml]"     # + XML request bodies (defusedxml)

The core needs Python 3.14 or newer. Both extras are imported lazily, only where they are used (MQTTEventSink/MQTTEventSource, and the XML codec and XML router's body parsing), so the core imports without them and a missing extra surfaces as an ImportError at first use. Bring your own database driver (for example asyncpg) for SQLAlchemyRepository.

Public API overview

  • craftainer_crud.config: CrudConfig, MQTTConfig, configure(config, session_factory). Call configure once at startup, before the first request.
  • craftainer_crud.models: the declarative Base/IdentifiedBase, the record-lifecycle mixins (Archivable, Draftable, Schedulable, Lockable) and the shared Revision model.
  • craftainer_crud.views: the Pydantic view base (ORMView), bulk, revision and stats response shapes.
  • craftainer_crud.repositories: the Repository protocol, SQLAlchemyRepository, InMemoryRepository and the filter/sort clauses.
  • craftainer_crud.interfaces: CRUDInterface, OwnerScope, revision and event sinks, build_repository_provider and friends.
  • craftainer_crud.controllers: build_json_router, build_xml_router, build_web_router and build_resource_router; crud_manifest_router and api_catalog_router (controllers.crud_manifest).
  • craftainer_crud.manifest: ManifestRegistry, ManifestOptions and build_manifest, the CRUD manifest builder.

CRUD manifest

A server describes its resources, their filters, optional routes and cache hints in one JSON document (docs/manifest.md, schema schemas/crud-manifest/v1.json). Wire it up once:

from craftainer_crud.controllers.crud_manifest import api_catalog_router, crud_manifest_router
from craftainer_crud.controllers.crud_router import build_resource_router
from craftainer_crud.manifest import ManifestOptions, ManifestRegistry

registry = ManifestRegistry()

router = build_resource_router(
    ...,  # as before
    manifest=ManifestOptions(
        registry=registry, name="heroes", api_version="v2", model=HeroModel,
        owner_scoped=True, read_roles=["viewer"], write_roles=["editor"], delete_roles=["maintainer"],
    ),
)
app.include_router(crud_manifest_router(
    registry, service_name="my-api", service_version="1.4.0", stats_ttl=30,
    oidc_discovery_url="https://idp/.well-known/openid-configuration",
))  # GET /api/_crud/manifest
app.include_router(api_catalog_router(manifest_url="/api/_crud/manifest"))  # GET /.well-known/api-catalog

The factories register what they build, so the manifest cannot list a route that is not mounted. It is filtered to the caller by running each resource's own read_roles dependency, and carries an ETag over that filtered body.

Model changes need an app-side migration

The package ships SQLAlchemy models (Revision, the lifecycle mixins) but no migrations: the host's Alembic setup targets models.base.Base.metadata. A release that changes those models therefore needs a new migration in the host application, and the release notes say so. Migrations stay immutable once applied (NFR-0019 in the host repository).

Versioning

SemVer, starting at 0.1.0. While the major version is 0, a minor release may break the public API; pin craftainer-crud>=0.x,<0.(x+1) until 1.0.0. The version lives only in the git tag release.yml computes; pyproject.toml stays at 0.0.0 and make build stamps RELEASE_VERSION into the build. Releases go to TestPyPI first, then PyPI, through trusted publishing (PYPI_PUBLISH repository variable: testpypi or pypi; unset publishes nothing).

Development

Open the repository in the devcontainer (it starts a Postgres for the integration tests), then run prek run --all-files --hook-stage manual. The pytest hook covers tests/unit and tests/integration under one 100% coverage gate; see tests/README.md.

License

Licensed under the GNU General Public License v3.0.

Metadata

Release files for craftainer-crud 0.2.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 craftainer-crud 0.2.0
File Size Uploaded Provenance
craftainer_crud-0.2.0.tar.gz 324.0 kB Without provenance Details

Built distribution (wheel)

Table of built distributions (wheels) for craftainer-crud 0.2.0
File Interpreter ABI Platform
craftainer_crud-0.2.0-py3-none-any.whl Python 3 none any Details

Total release size: 447.4 kB

Release files / craftainer_crud-0.2.0.tar.gz

Download URL craftainer_crud-0.2.0.tar.gz
Size 324.0 kB
Tags Source
SHA-256 checksum
How to use checksums
483b301838253a5039e2ccc4b26c281937b3699cd91b60d21fca90852e39302a
BLAKE2b-256 checksum
How to use checksums
87b16d5dc1e9065f38eafbc905a56fc8766fcb4eeac91452ffd08b283015166d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Release files / craftainer_crud-0.2.0-py3-none-any.whl

Download URL craftainer_crud-0.2.0-py3-none-any.whl
Size 123.4 kB
Tags Python 3
SHA-256 checksum
How to use checksums
5151c84eb09ee07356ea21d81b16011c80a5de371ed2495a906a4cbf72c5b286
BLAKE2b-256 checksum
How to use checksums
c64f6902467ab8b17e80bafead2d28c0f0021b4808df383e7cb3bc79bc4ad624
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via uv/0.13.0 {"installer":{"name":"uv","version":"0.13.0","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Debian GNU/Linux","version":"13","id":"trixie","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}

Security for craftainer-crud 0.2.0

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.

No provenance found

None of the files in this release were uploaded with provenance metadata.

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

Release history Release notifications | RSS feed

This release

0.2.0 This release

2 release files No provenance

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