A Python library providing interface definitions for Domain-Driven Design (DDD) patterns using Pydantic for type safety and validation.
Project description
๐๏ธ Pydddi
Pydantic-powered Domain-Driven Design Interfaces
A modern Python library for building clean, type-safe DDD applications
Transform your Python applications with enterprise-grade DDD patterns ๐
โจ What is Pydddi?
Pydddi brings the power of Domain-Driven Design to Python with type safety at its core. Built on top of Pydantic, it provides clean interfaces and patterns that make your code more maintainable, testable, and scalable.
๐ฏ Why Choose Pydddi?
| Feature | Benefit |
|---|---|
| ๐ Type Safety | Catch errors at development time with Pydantic validation |
| ๐๏ธ Clean Architecture | Enforce separation of concerns with clear layer boundaries |
| ๐งฉ Modular Design | Mix and match interfaces based on your needs |
| โก Modern Python | Leverages Python 3.12+ features for optimal performance |
| ๐ Self-Documenting | Interfaces serve as living documentation |
๐ Features
๐๏ธ Domain Layer
|
โ๏ธ Application Layer
|
๐๏ธ Infrastructure Layer
|
๐งช Developer Experience
|
๐ฆ Quick Start
# Install the package
pip install pydantic-ddd-interface
# Start building your domain
from pydddi import IEntity, IUseCase, ICrudRepository
# You're ready to build enterprise-grade applications! ๐
๐ง Usage Examples
๐ก Tip: Each layer has a specific responsibility. Start with the domain and work your way out!
๐๏ธ Domain Layer
Define your business entities and value objects
from pydddi import IEntity, IModel
class User(IEntity[int]):
"""Lightweight user entity - just identity and core attributes"""
id: int
name: str
email: str
def get_id(self) -> int:
return self.id
class UserProfile(IModel):
"""Heavy model with relationships - used in domain logic processing"""
user: User
posts: List["Post"]
followers: List["User"]
settings: "UserSettings"
activity_history: List["ActivityLog"]
# Domain logic methods can access all related data
def get_total_engagement(self) -> int:
return sum(post.likes + post.comments for post in self.posts)
โ๏ธ Application Layer
Orchestrate business workflows with use cases
from pydddi import IUseCase, IUseCaseCommand, IUseCaseResult
class CreateUserCommand(IUseCaseCommand):
"""Command to create a new user"""
name: str
email: str
class CreateUserResult(IUseCaseResult):
"""Result of user creation"""
user_id: int
success: bool
message: str
class CreateUserUseCase(IUseCase[CreateUserCommand, CreateUserResult]):
"""Use case for creating users with business validation"""
async def execute(self, command: CreateUserCommand) -> CreateUserResult:
# Your business logic here
# - Validate email uniqueness
# - Apply business rules
# - Persist user
pass
๐๏ธ Infrastructure Layer
Handle data persistence and external integrations
from pydddi import ICrudRepository, IReadRepository, IReadAggregateRepository
from pydddi import ICreateSchema, IUpdateSchema
class UserCreateSchema(ICreateSchema):
"""Schema for user creation"""
name: str
email: str
class UserUpdateSchema(IUpdateSchema):
"""Schema for user updates"""
name: str | None = None
email: str | None = None
๐ Click to see repository implementations
# ๐จ CRUD Repository - for lightweight entity operations
class UserCrudRepository(ICrudRepository[User, UserCreateSchema, User, UserUpdateSchema]):
async def create(self, schema: UserCreateSchema) -> User:
"""Create a new user entity (lightweight)"""
pass
async def read(self, id: int) -> User:
"""Get user entity by ID (no relationships)"""
pass
# ... other CRUD methods
# ๐ Read Repository - for simple read operations on lightweight entities
class UserReadRepository(IReadRepository[User, User]):
async def read(self, id: int) -> User:
"""Get user entity without relationships"""
pass
async def list(self, limit: int = None, **filters) -> List[User]:
"""List user entities (lightweight)"""
pass
# ๐ Read Aggregate Repository - for heavy models with full relationships
class UserProfileRepository(IReadAggregateRepository[UserProfile, User]):
async def read(self, id: int) -> UserProfile:
"""Get heavy UserProfile with all related data (posts, followers, etc.)"""
pass
async def list(self, limit: int = None, **filters) -> List[UserProfile]:
"""List UserProfile with full relationship data for domain processing"""
pass
๐๏ธ Architecture Overview
graph TB
subgraph "๐ฅ๏ธ Presentation Layer"
API[REST API / GraphQL]
CLI[CLI Commands]
end
subgraph "โ๏ธ Application Layer"
UC[Use Cases]
CMD[Commands & Results]
end
subgraph "๐๏ธ Domain Layer"
ENT[Entities]
VO[Value Objects]
DS[Domain Services]
end
subgraph "๐๏ธ Infrastructure Layer"
REPO[Repositories]
DB[(Database)]
EXT[External APIs]
end
API --> UC
CLI --> UC
UC --> ENT
UC --> REPO
REPO --> DB
REPO --> EXT
style UC fill:#e1f5fe
style ENT fill:#f3e5f5
style REPO fill:#e8f5e8
๐ฏ Design Principles
| Principle | Implementation |
|---|---|
| ๐ Dependency Inversion | Infrastructure depends on domain abstractions |
| ๐งฉ Single Responsibility | Each interface has one clear purpose |
| โก Open/Closed | Extend behavior without modifying existing code |
| ๐ญ Interface Segregation | Small, focused interfaces over large ones |
๐ API Reference
๐๏ธ Domain Layer APIs
Entities & Models
IEntity- Base class for entities with identity and lifecycleIModel- Base class for value objects using Pydantic validationIDomainService- Interface for domain services containing business logic
โ๏ธ Application Layer APIs
Use Cases & Commands
IUseCase[TCommand, TResult]- Generic interface for business use casesIUseCaseCommand- Base class for use case input commandsIUseCaseResult- Base class for use case output results
Exception Handling
UseCaseError- Base exception for use case operationsUseCaseCommandError- Command validation errorsUseCaseResultError- Result validation errorsUseCaseExecutionError- Execution-time errors
๐๏ธ Infrastructure Layer APIs
Repository Patterns
ICrudRepository[TEntity, TCreateSchema, TReadSchema, TUpdateSchema]- Full CRUD operationsIReadRepository[TEntity, TReadSchema]- Read-only operations for entitiesIReadAggregateRepository[TModel, TReadAggregateSchema]- Complex reads with relationships
Data Schemas
ICreateSchema- Schema for create operationsIReadSchema- Schema for read operationsIUpdateSchema- Schema for update operationsIReadAggregateSchema- Schema for aggregate read operations
Exception Handling
RepositoryError- Base repository exceptionRecordNotFoundError- Entity not found errorsDuplicateRecordError- Duplicate entity errors
๐ฏ Repository Usage Guide
| Repository Type | Use Case | Returns | Example | Weight |
|---|---|---|---|---|
| ICrudRepository | Lightweight entity lifecycle | IEntity |
User CRUD operations | ๐ชถ Light |
| IReadRepository | Simple entity queries | IEntity |
User identity lookup | ๐ชถ Light |
| IReadAggregateRepository | Heavy models with relationships | IModel |
UserProfile with posts/followers | ๐๏ธ Heavy |
๐ค Contributing
We welcome contributions! Here's how you can help:
| ๐ Found a Bug? | ๐ก Have an Idea? | ๐ Improve Docs? |
|---|---|---|
| Open an Issue | Start a Discussion | Submit a PR |
๐ ๏ธ Development Setup
# Clone the repository
git clone https://github.com/nodashin/pydantic-ddd-interface.git
cd pydantic-ddd-interface
# Install dependencies
poetry install
# Run tests
poetry run pytest
# Format code
poetry run black .
๐ License
This project is licensed under the MIT License - see the LICENSE file for details.
Made with โค๏ธ for the Python DDD community
Star โญ this repo if you find it useful!
Project details
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file pydantic_ddd_interface-0.2.0.tar.gz.
File metadata
- Download URL: pydantic_ddd_interface-0.2.0.tar.gz
- Upload date:
- Size: 11.2 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
9170bb4b120dc188e05e217d654bf54f827b09c2369981e5a6a97b7efd62d24e
|
|
| MD5 |
ab4813633058bc733a47da014e69e91c
|
|
| BLAKE2b-256 |
5f01098e15d1086f761dd03a83c90217d38ad345104c7f4036a4a75eb23d6971
|
File details
Details for the file pydantic_ddd_interface-0.2.0-py3-none-any.whl.
File metadata
- Download URL: pydantic_ddd_interface-0.2.0-py3-none-any.whl
- Upload date:
- Size: 10.4 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: twine/6.1.0 CPython/3.12.4
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
a49799d667eece96f2d66b0a5c6367a36129c757be8ae8b6df4271560efb8c8e
|
|
| MD5 |
fdc5b308e487066ec50bd1163e51d64e
|
|
| BLAKE2b-256 |
cde96bd8dff6776ce12661c4dc18cdd2488c822566fbde95faea345d560e3261
|