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.1.tar.gz (12.4 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.1-py3-none-any.whl (9.9 kB view details)

Uploaded Python 3

File details

Details for the file pydantic-ddd-interface-0.1.1.tar.gz.

File metadata

  • Download URL: pydantic-ddd-interface-0.1.1.tar.gz
  • Upload date:
  • Size: 12.4 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.1.tar.gz
Algorithm Hash digest
SHA256 6c843c72a75834d3d6521da3e451c674fd20882260a73fcd4879acf0bf6b3bbb
MD5 5dee5fd990cda0553a7e486e6bc03d64
BLAKE2b-256 70b3a172970f28c99eb6cb68fdb72f9df02e7eef49294b402bb272c38b7e07b4

See more details on using hashes here.

File details

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

File metadata

  • Download URL: pydantic_ddd_interface-0.1.1-py3-none-any.whl
  • Upload date:
  • Size: 9.9 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.1-py3-none-any.whl
Algorithm Hash digest
SHA256 bc88fd2043bcc3061e6bd997a7ba8476c74583921649f906f0268eef2b572f33
MD5 cf475313fe8fef076b33797dea535935
BLAKE2b-256 d22ad4b929494894b398668116b78e6f0378f5c0f947c0c31d422b717d4045bf

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