Skip to main content

quadkit-contracts

Quadkit

PyPI Python License

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.3 in the 0.x series, released in lockstep with the other four 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.3) when you depend on these types directly. Full policy: stability and compatibility.

Apache-2.0 — see LICENSE. "Quadkit" and the Quadkit logo are trademarks of the project — see TRADEMARK.md.

Release files for quadkit-contracts 0.0.4

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for quadkit-contracts 0.0.4
File Size Uploaded
quadkit_contracts-0.0.4.tar.gz 409.1 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for quadkit-contracts 0.0.4
File Interpreter ABI Platform
quadkit_contracts-0.0.4-py3-none-any.whl Python 3 none any Details

Total release size: 847.0 kB

Release files / quadkit_contracts-0.0.4.tar.gz

Download URL quadkit_contracts-0.0.4.tar.gz
Size 409.1 kB
Tags Source
SHA-256 checksum
How to use checksums
7368d279373f406a0fba5adb1360e4e81e7c4f4a993a7acd4dc745d65e6a5cf2
BLAKE2b-256 checksum
How to use checksums
8a9d0baf2ef351ea7d0436af56a82732dd6f8ce00129fb082d746119f78b821b
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.7

Release files / quadkit_contracts-0.0.4-py3-none-any.whl

Download URL quadkit_contracts-0.0.4-py3-none-any.whl
Size 437.9 kB
Tags Python 3
SHA-256 checksum
How to use checksums
451393f269bd9a7c8e48e275d3f5deb1a89bc17ab977283667e604981f7857aa
BLAKE2b-256 checksum
How to use checksums
9abc03628580b40cccb5787e891acbfa459ef04dd3b397b18b6d6edfe502d77d
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.13.7

Release history Release notifications | RSS feed

0.0.42

2 release files

0.0.41

2 release files

This release

0.0.4 This release

2 release files

0.0.3

2 release files

0.0.2

2 release files

0.0.1

2 release 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