Skip to main content

Python version PyPI version PyPI downloads Ask DeepWiki GitHub stars License

   _____      _ _ _
  / ____|    | | (_)
 | |    _   _| | |_ _ __   __ _ _ __
 | |   | | | | | | | '_ \ / _` | '_ \
 | |___| |_| | | | | | | | (_| | | | |
  \_____\__,_|_|_|_|_| |_|\__,_|_| |_|

Cullinan

A business-first Python web framework for building applications through decorators, module boundaries, and built-in IoC/DI.

Cullinan is a Python Web Framework for developers who want to organize applications around business services, controllers, and methods instead of manually wiring an app object. Its default path is decorator-first discovery plus @application + @configure(...), with @module used as the application boundary when ownership, runtime structure, and stability matter. The framework-facing API stays engine-neutral: Cullinan internally bridges your business application into Tornado or ASGI runtimes instead of making a concrete server framework the primary developer mental model.


What is Cullinan?

Cullinan is designed to make the framework work around your business architecture, not the other way around.

  • Business-first application model - write services, controllers, middleware, and methods first
  • Decorator-first discovery - let Python imports and decorator metadata assemble the runtime
  • Structured module boundaries - use @module to express ownership and runtime boundaries
  • Built-in IoC/DI and lifecycle - keep application wiring inside the framework model
  • Engine-neutral Web facade - build against Cullinan semantics while the framework adapts to Tornado or ASGI internally
  • Public semantic path - build, run, test, and extend applications through stable public APIs

Cullinan is not centered on treating an app object as a manual registration hub. The recommended development flow is to declare business components, define a root module when structure matters, and let the framework assemble the application runtime.


Why Cullinan?

1. Framework semantics before manual wiring

Cullinan gives you a clear application model: declare components with decorators, let the framework discover them, and keep explicit runtime internals as an advanced path rather than the default onboarding path.

2. Application boundaries that scale past toy examples

@module is more than a naming convention. It is the structured boundary for owned packages, runtime composition, and higher-level lifecycle behavior when your application grows.

3. Web, DI, lifecycle, and testing in one model

Routing, parameter binding, dependency injection, lifecycle hooks, middleware, and test flow all sit inside one framework vocabulary instead of forcing developers to stitch together multiple unrelated patterns.

4. A Pythonic path for business applications

Cullinan is designed to keep developers focused on business architecture and business methods. You can stay on the public path for most application work and only move into internals when you intentionally need advanced extension behavior.

5. A clearer semantic package surface

Cullinan now exposes a clearer framework-shaped package surface:

  • cullinan - recommended public startup and declaration API for application code
  • cullinan.web - controllers, route decorators, request/response, parameters, middleware
  • cullinan.core - IoC/DI, lifecycle, context, and semantic rules
  • cullinan.application - advanced application semantics for maintainers and framework-aware integrations
  • cullinan.testing - test-facing helpers
  • cullinan.runtime / cullinan.transport - advanced discovery and adapter boundaries
  • cullinan.support - constrained support utilities, not a second public app path

Framework capabilities

Capability layer What Cullinan provides
Application composition @application + @configure(...), decorator-driven discovery, structured runtime assembly
Web API model cullinan.web facade for @controller, RESTful decorators, WebResponse, parameters, middleware
Parameter system Typed Path, Query, Body, validation, conversion, and controller-method binding
IoC/DI and lifecycle Inject(), InjectByName(), request scope, startup/shutdown hooks, component lifecycle
Runtime boundaries @module ownership, clearer package structure, better runtime organization
Testing and delivery get_asgi_app(), resettable registries, packaging-friendly runtime, cross-platform support

Cullinan's goal is not to expose every internal knob on the README homepage. The goal is to provide a coherent framework model that remains readable from first contact through production use.


Install

Cullinan is published on PyPI and currently supports Python 3.9+.

pip install -U pip
pip install cullinan

After installation, start from the minimal example in examples/minimal_app/ or the repository guide in docs/examples.md.


Quick Start

The recommended starting point is: define business components, decorate them, and declare the application entry with @configure(...) + @application + main().

from cullinan import application, configure
from cullinan.core import service
from cullinan.web import controller, get_api


@service
class GreetingService:
    def greet(self) -> str:
        return "Hello from Cullinan!"


@controller(url="/hello")
class HelloController:
    greeting_service: GreetingService  # constructor injection: one line is all you need

    @get_api(url="")
    def hello(self):
        return {"message": self.greeting_service.greet()}


@configure(user_packages=["minimal_app"], server_port=4080)
@application
def main(): ...

Run it:

python -m minimal_app

Then open:

http://localhost:4080/hello

This example shows the default Cullinan path:

  • business service first
  • controller methods as the public web surface
  • @application + @configure(...) + main() as the startup flow
  • @module available when explicit runtime boundaries are needed
  • runtime backend selection delegated to Cullinan instead of driving application structure

Learning path

If you are new to Cullinan, use this order:

  1. examples/minimal_app/ - shortest public entrypoint
  2. examples/controller_service_inject/ - service/controller layering with Inject()
  3. examples/middleware_and_module/ - @module boundaries and middleware semantics
  4. examples/parameter_handling/ - method-level Path, Query, and Body
  5. examples/testing_flow/ - public-API testing with get_asgi_app()

Then move into the documentation knowledge base:


Documentation

English

Chinese


Current series

v0.95 is the Phase A convergence cut for the 1.0 roadmap, continuing the v0.94 opt iteration. This release line locks down the public surface and packaging baseline around:

  • @application + @configure(...) + main() as the startup flow
  • decorator-first discovery through Python imports
  • @module as the structured boundary for runtime ownership
  • built-in IoC/DI, lifecycle, and semantic diagnostics
  • a semantic package surface centered on the top-level cullinan API, with advanced semantic namespaces under cullinan.application, cullinan.web, and cullinan.core
  • engine-neutral runtime selection over Tornado / ASGI backends
  • pyproject.toml + setuptools.build_meta packaging with setup.py kept as a compatibility shim
  • PEP 561 typed-package distribution via cullinan/py.typed

The v0.94 opt iteration (A1-A4 kernel behavior optimization + B1-B3 mkdocs mechanism) deprecates legacy compatibility symbols, adds strict _xxx private-injection and strict lifecycle propagation switches, optimizes scope validation, and restructures the docs build channel mapping so origin/preview is the single pre-release authority.

Version-specific details and migration notes live in the documentation knowledge base rather than in the homepage narrative.


Project links


License

MIT License - see LICENSE for details.

Release files for cullinan 0.95

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

Source distribution (sdist)

Source distribution for cullinan 0.95
File Size Uploaded
cullinan-0.95.tar.gz 221.9 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for cullinan 0.95
File Interpreter ABI Platform
cullinan-0.95-py3-none-any.whl Python 3 none any Details

Total release size: 494.7 kB

Release files / cullinan-0.95.tar.gz

Download URL cullinan-0.95.tar.gz
Size 221.9 kB
Tags Source
SHA-256 checksum
How to use checksums
9f320048bb61b82c6d22885746052b39c3b33c3f9f0abaf07aa6b7f122052d74
BLAKE2b-256 checksum
How to use checksums
0a86e67c4df0f0de54b8c93ef289a84745a69aa56e419d148f908b40edeb038a
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release files / cullinan-0.95-py3-none-any.whl

Download URL cullinan-0.95-py3-none-any.whl
Size 272.8 kB
Tags Python 3
SHA-256 checksum
How to use checksums
37f70756db4978975b59a58513f601b4a069139ce7c36652033ea9964bfaf648
BLAKE2b-256 checksum
How to use checksums
5049f5b4465c77c38f1eaed24f33874f8e7f1d76095da94f05cb8dd194464004
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
No
Uploaded via twine/7.0.0 CPython/3.14.7

Release history Release notifications | RSS feed

This release

0.95 This release

2 release files

0.94

2 release files

0.93

2 release files

0.92

2 release files

0.91

2 release files

0.83

2 release files

0.82

2 release files

0.81

2 release files

0.80

2 release files

0.79

2 release files

0.78

2 release files

0.77

2 release files

0.76

2 release files

0.75

2 release files

0.63

2 release files

0.57

2 release files

0.56

2 release files

0.55

2 release files

0.54

2 release files

0.53

2 release files

0.52

2 release files

0.51

2 release files

0.50

2 release files

0.44

1 release file

0.43

1 release file

0.42

1 release file

0.41

1 release file

0.40

1 release file

0.39

1 release file

0.38

1 release file

0.37

1 release file

0.35

1 release file

0.34

1 release file

0.33

1 release file

0.32

1 release file

0.31

1 release file

0.2.12

1 release file

0.2.11

1 release file

0.2.10

1 release file

0.2.9

1 release file

0.2.2

1 release file

0.2.0

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