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). Callconfigureonce at startup, before the first request.craftainer_crud.models: the declarativeBase/IdentifiedBase, the record-lifecycle mixins (Archivable,Draftable,Schedulable,Lockable) and the sharedRevisionmodel.craftainer_crud.views: the Pydantic view base (ORMView), bulk, revision and stats response shapes.craftainer_crud.repositories: theRepositoryprotocol,SQLAlchemyRepository,InMemoryRepositoryand the filter/sort clauses.craftainer_crud.interfaces:CRUDInterface,OwnerScope, revision and event sinks,build_repository_providerand friends.craftainer_crud.controllers:build_json_router,build_xml_router,build_web_routerandbuild_resource_router;crud_manifest_routerandapi_catalog_router(controllers.crud_manifest).craftainer_crud.manifest:ManifestRegistry,ManifestOptionsandbuild_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)
| File | Size | Uploaded | Provenance | |
|---|---|---|---|---|
| craftainer_crud-0.2.0.tar.gz | 324.0 kB | Without provenance | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| 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.