
Pragmatic Framework for Ambitious Applications
Build domain-driven Python applications with clean architecture. Start with DDD, evolve to CQRS or Event Sourcing — with pluggable infrastructure and zero boilerplate.
Get Started Tutorial How Do I...?
Why Protean?
-
Domain-First
Model your business in pure Python. No ORM inheritance, no framework lock-in. Your domain code reads like the business, enabling collaboration between developers and domain experts.
-
Plug In Infrastructure Later
Start with in-memory adapters — no database, no broker, no setup. When you're ready, swap in PostgreSQL, Redis, Elasticsearch, or MessageDB through configuration. No code changes.
-
Three Architectural Paths
Begin with DDD, evolve to CQRS, adopt Event Sourcing — all within the same framework. Mix patterns per aggregate. Pragmatism over purity.
-
Test Everything
3,826 tests with a 3.5:1 test-to-code ratio. Run your full domain test suite in-memory in seconds. Every commit is tested against PostgreSQL, Redis, Elasticsearch, MessageDB, and MSSQL across Python 3.11-3.14.
See It in Action
from protean import Domain, handle
from protean.fields import Identifier, String, Text
from protean.utils.globals import current_domain
domain = Domain() # (1)!
@domain.aggregate # (2)!
class Post:
title: String(max_length=100, required=True)
body: Text(required=True)
status: String(max_length=20, default="DRAFT")
def publish(self):
self.status = "PUBLISHED"
self.raise_(PostPublished(post_id=self.id, title=self.title)) # (3)!
@domain.event(part_of="Post") # (4)!
class PostPublished:
post_id: Identifier(required=True)
title: String(required=True)
@domain.command(part_of="Post") # (5)!
class CreatePost:
title: String(max_length=100, required=True)
body: Text(required=True)
@domain.command_handler(part_of=Post) # (6)!
class PostCommandHandler:
@handle(CreatePost)
def create_post(self, command: CreatePost):
post = Post(title=command.title, body=command.body)
current_domain.repository_for(Post).add(post) # (7)!
return post.id
- Domain — The central registry that wires all elements together.
- Aggregate — The core building block encapsulating fields and business logic.
- Raising an Event —
raise_()emits a domain event to notify the rest of the system. - Event — An immutable record of something that happened in the domain.
- Command — An intent to change state, carrying just the needed data.
- Command Handler — Receives a command, creates/updates aggregates, and persists them.
- Repository — Built-in persistence abstraction to add, get, or remove aggregates without touching the database directly.
Aggregates, commands, events, and handlers — all in pure Python, with decorators that wire everything together. No infrastructure required to get started.
Choose Your Path
Protean supports three architectural approaches. Each builds on the one before it — start simple and add sophistication as your needs evolve.
| Path | Best for | |
|---|---|---|
| Domain-Driven Design | Clean domain modeling — the simplest way to start | |
| CQRS | Separate reads from writes with commands and projections | |
| Event Sourcing | Full audit trail, temporal queries, and event replay |
Not sure? Start with DDD — you can evolve later. See Choose a Path for a detailed comparison.
Built to Last
-
3,826 Tests
3.5:1 test-to-code ratio. Every commit validated against PostgreSQL, Redis, Elasticsearch, MessageDB, and MSSQL.
-
Zero Lint Violations
Fully clean Ruff linting and formatting, enforced on every commit via pre-commit hooks.
-
A-Grade Maintainability
97% of source files score in the highest maintainability tier. Average cyclomatic complexity of 2.97.
-
12 Adapters, 5 Ports
Pluggable infrastructure across databases, brokers, event stores, and caches — tested across 4 Python versions.
Explore the Documentation
-
Quickstart
Build a domain in 5 minutes — no infrastructure required.
-
Tutorial
10-chapter tutorial from your first aggregate to production.
-
How Do I...?
Task-oriented index — look up what you're trying to do and jump straight to the right guide.
-
Guides
Step-by-step instructions for every task Protean supports.
-
Core Concepts
DDD, CQRS, and Event Sourcing explained.
-
Adapters
PostgreSQL, Redis, Elasticsearch, MessageDB, and more.
-
Patterns & Recipes
Battle-tested solutions for common challenges.