quadkit-contracts
Protocols, shared types, and the exception hierarchy for Quadkit —
with zero runtime dependencies beyond typing-extensions. Every
published package depends on contracts; no implementation package
defines a protocol another package depends on.
For integration authors who need to bind against Quadkit interfaces without pulling in the framework — thin adapters import only this package.
The quadkit family
| Package | Role |
|---|---|
quadkit-contracts |
zero-dependency protocols, types, exception hierarchy |
quadkit |
the framework core — DI container, modules, config, logging, Result |
quadkit-web |
ASGI layer — controllers, routing, middleware, OpenAPI docs |
quadkit-cli |
project scaffolding and code generators |
quadkit-testing |
in-process test beds, fakes, fixtures |
Installation
uv add quadkit-contracts
Requires Python >= 3.11.
Minimal working example
Protocols are structural: implement the shape, and the container binds your implementation to the contract.
from typing import Protocol
from quadkit.result import Err, Ok, Result
class UserNotFound(Exception):
"""A domain failure the caller is expected to handle."""
class UserRepository(Protocol):
async def find_name(self, user_id: str) -> Result[str, UserNotFound]: ...
async def find_name_or_unknown(repo: UserRepository, user_id: str) -> str:
result = await repo.find_name(user_id)
return result.match(ok=lambda name: name, err=lambda e: "unknown")
The domain-model side — pydantic-based entities and events:
from quadkit.contracts.domain.events import DomainEvent
from quadkit.domain import AggregateRoot
class UserCreated(DomainEvent):
user_id: str
email: str
class User(AggregateRoot):
email: str
The Result toolkit
Result is this package's flagship: expected failures become values
the type system can see. pipeline() chains fallible steps fluently;
as_result wraps exception-raising calls without swallowing the
unexpected ones:
from quadkit.result import Err, Ok, as_result, pipeline
def parse_port(raw: str):
try:
port = int(raw)
except ValueError as exc:
return Err(exc)
if not 1 <= port <= 65535:
return Err(ValueError(f"port out of range: {port}"))
return Ok(port)
result = (
pipeline("8080") # infallible start
.then(parse_port) # Result[int, ValueError]
.map(lambda port: f"listening on :{port}")
.finalize() # Result[str, ValueError]
)
@as_result(ValueError, TypeError) # only these become Err
async def load_setting(raw: str) -> int:
return int(raw)
collect() gathers many results, partition() splits them into
successes and failures, and try_catch() is the sync counterpart of
as_result. Full walkthrough:
contracts — errors as values.
Optional extras
| Extra | Contents |
|---|---|
quadkit-contracts[dev] / [test] |
development / test tooling |
Public API entry points
| Module | Contents |
|---|---|
quadkit.result |
Result[T, E], Ok, Err, as_result(), as_result_sync(), try_catch(), ResultPipeline |
quadkit.contracts.core.di |
ContainerRegistrarProtocol, ContainerResolverProtocol |
quadkit.contracts.core.provider |
ProviderProtocol, ProviderPriority |
quadkit.contracts.core.registry |
RegistryProtocol, StrategyRegistryProtocol, BackendRegistryProtocol |
quadkit.contracts.domain.base |
DomainModelProtocol, ID |
quadkit.contracts.domain.events |
DomainEvent |
quadkit.contracts.exceptions |
QuadkitError and the full hierarchy |
quadkit.contracts.infra.cache |
CacheBackendProtocol |
quadkit.contracts.data |
DatabaseProviderProtocol |
quadkit.contracts.security.secrets |
SecretStoreProtocol |
Deep-dive: contracts in the docs set.
Configuration
None — this package carries types, not behavior.
Error handling
The taxonomy lives here: QuadkitError is the root; DomainError
subclasses describe expected business failures (NotFoundError,
ValidationError, ConflictError, PermissionDeniedError, ...). The
web layer maps them to HTTP problem responses — see
error handling.
Testing
Protocols are tested by conformance: implement the shape, run your
implementation through the behavior callers rely on. quadkit-testing
ships the fakes used by the framework's own tests.
Security
This package ships interfaces and types only — no network, no I/O, no runtime dependencies. Report vulnerabilities privately per SECURITY.md.
Stability
Version 0.0.46 in the 0.x series, released in lockstep with the
other twelve distributions. These protocols carry no compatibility
guarantee yet: minor releases may add, rename, or remove members
while the framework is pre-1.0. Because this package is published
whole, protocols for not-yet-released areas are the most likely to
change; the settled ones are those exercised by quadkit,
quadkit-web, quadkit-testing, and quadkit-cli. Pin an exact
version (quadkit-contracts==0.0.46) when you depend on these types
directly. Full policy:
stability and compatibility.
Links
- Documentation — https://oridecon.dev/quadkit/
- Getting started — https://oridecon.dev/quadkit/getting-started/installation/
- Changelog — https://github.com/dbtinoy-/quadkit/blob/main/CHANGELOG.md
- Issues — https://github.com/dbtinoy-/quadkit/issues
- Security — report privately per SECURITY.md
- Contributing — CONTRIBUTING.md
Apache-2.0 — see LICENSE. "Quadkit" and the Quadkit logo are trademarks of the project — see TRADEMARK.md.
Metadata
Release files for quadkit-contracts 0.0.46
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 | Actions |
|---|---|---|---|---|
| quadkit_contracts-0.0.46.tar.gz | 409.2 kB | Without provenance | Details for quadkit_contracts-0.0.46.tar.gz |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Actions Reset |
|---|---|---|---|---|
| quadkit_contracts-0.0.46-py3-none-any.whl | Python 3 | none | any | Details for quadkit_contracts-0.0.46-py3-none-any.whl |
Total release size: 858.1 kB
Release files / quadkit_contracts-0.0.46.tar.gz
| Download URL | quadkit_contracts-0.0.46.tar.gz |
|---|---|
| Size | 409.2 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
59204fc20a8de01921b75ad0dc281f921037468d1267daf0363fad716cdfd275
|
|
BLAKE2b-256 checksum How to use checksums |
6f943f735d91f8e3baaa1c6aa5da1f0e12c219be9d9049fad987bb2513e80e1f
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Release files / quadkit_contracts-0.0.46-py3-none-any.whl
| Download URL | quadkit_contracts-0.0.46-py3-none-any.whl |
|---|---|
| Size | 448.9 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
c6859a544ba0ea91cdc5a6d7920fc2743e541d630bf690dab8ed75ded137bd1e
|
|
BLAKE2b-256 checksum How to use checksums |
c9f8eaa9fb60228d55a95449c27f450411384f532636f8a66dbbc3471f607a90
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
uv/0.12.23 {"installer":{"name":"uv","version":"0.12.23","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Arch Linux","version":null,"id":null,"libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":null}
|
Security for quadkit-contracts 0.0.46
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.
To learn more about protecting yourself from malicious actors, visit our package security documentation.