Skip to main content

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

Python Pydantic License Poetry


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

  • Type-safe entities with identity
  • Value objects using Pydantic
  • Domain service abstractions
  • Rich domain modeling

โš™๏ธ Application Layer

  • Command/Result pattern
  • Use case interfaces
  • Structured error handling
  • Business workflow orchestration

๐Ÿ—„๏ธ Infrastructure Layer

  • Repository patterns (CRUD, Read, Aggregate)
  • Schema-based operations
  • Database abstraction
  • External service integration

๐Ÿงช Developer Experience

  • Full type hints support
  • IDE autocompletion
  • Runtime validation
  • Clear error messages

๐Ÿ“ฆ 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 lifecycle
  • IModel - Base class for value objects using Pydantic validation
  • IDomainService - Interface for domain services containing business logic
โš™๏ธ Application Layer APIs

Use Cases & Commands

  • IUseCase[TCommand, TResult] - Generic interface for business use cases
  • IUseCaseCommand - Base class for use case input commands
  • IUseCaseResult - Base class for use case output results

Exception Handling

  • UseCaseError - Base exception for use case operations
  • UseCaseCommandError - Command validation errors
  • UseCaseResultError - Result validation errors
  • UseCaseExecutionError - Execution-time errors
๐Ÿ—„๏ธ Infrastructure Layer APIs

Repository Patterns

  • ICrudRepository[TEntity, TCreateSchema, TReadSchema, TUpdateSchema] - Full CRUD operations
  • IReadRepository[TEntity, TReadSchema] - Read-only operations for entities
  • IReadAggregateRepository[TModel, TReadAggregateSchema] - Complex reads with relationships

Data Schemas

  • ICreateSchema - Schema for create operations
  • IReadSchema - Schema for read operations
  • IUpdateSchema - Schema for update operations
  • IReadAggregateSchema - Schema for aggregate read operations

Exception Handling

  • RepositoryError - Base repository exception
  • RecordNotFoundError - Entity not found errors
  • DuplicateRecordError - 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

pydantic_ddd_interface-0.1.2.tar.gz (12.8 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

pydantic_ddd_interface-0.1.2-py3-none-any.whl (10.4 kB view details)

Uploaded Python 3

File details

Details for the file pydantic_ddd_interface-0.1.2.tar.gz.

File metadata

  • Download URL: pydantic_ddd_interface-0.1.2.tar.gz
  • Upload date:
  • Size: 12.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 colorama/0.4.4 importlib-metadata/4.6.4 keyring/23.5.0 pkginfo/1.8.2 readme-renderer/34.0 requests-toolbelt/0.9.1 requests/2.25.1 rfc3986/1.5.0 tqdm/4.57.0 urllib3/1.26.5 CPython/3.10.12

File hashes

Hashes for pydantic_ddd_interface-0.1.2.tar.gz
Algorithm Hash digest
SHA256 f02151a977cd0a3d181cbc23fdb1b3354b717d5a46bb9b4073ce5ca1d9de88b7
MD5 3beb5deb962baf3582043fc71220d723
BLAKE2b-256 81987d2ff7405f0c6a75c6fa476417bddff1333fab32d95b6ab11d9a09de9c16

See more details on using hashes here.

File details

Details for the file pydantic_ddd_interface-0.1.2-py3-none-any.whl.

File metadata

  • Download URL: pydantic_ddd_interface-0.1.2-py3-none-any.whl
  • Upload date:
  • Size: 10.4 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/3.8.0 colorama/0.4.4 importlib-metadata/4.6.4 keyring/23.5.0 pkginfo/1.8.2 readme-renderer/34.0 requests-toolbelt/0.9.1 requests/2.25.1 rfc3986/1.5.0 tqdm/4.57.0 urllib3/1.26.5 CPython/3.10.12

File hashes

Hashes for pydantic_ddd_interface-0.1.2-py3-none-any.whl
Algorithm Hash digest
SHA256 b51b1b0c0480a4e67653e8506eefe99f8c03536f86892937a7b1760db8c18ce9
MD5 cebe5642b68eb02ea8a1d6f146d5415f
BLAKE2b-256 a940ac10117566402ca1dc4db103cc1845a5a4f0bd6eea87c45382f5aa4f8bfc

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page