Domain model toolset to properly build Value Objects, Entities, Aggregates, and Services.
Install the package from PyPI using pip:
pip install complex-heart-domain-modelor using uv:
uv add complex-heart-domain-modelThis package provides decorators to enforce invariants on your domain models using Python dataclasses.
from dataclasses import dataclass
from complexheart.domain.models import has_invariants, invariant, InvariantViolation
@dataclass
@has_invariants
class OrderLine:
name: str
unit_price: float
quantity: int = 0
@invariant
def quantity_must_be_greater_than_zero(self) -> bool:
return self.quantity >= 0
@invariant
def price_must_be_positive_value(self) -> bool:
return self.unit_price >= 0
def total_cost(self) -> float:
return self.unit_price * self.quantityWhen creating an instance that violates any invariant, an InvariantViolation exception is raised:
# This will raise InvariantViolation
order = OrderLine(name="Nintendo Switch", unit_price=-250.0, quantity=1)The @has_invariants decorator integrates seamlessly with dataclass __post_init__ methods:
from dataclasses import dataclass
from complexheart.domain.models import has_invariants, invariant
@dataclass
@has_invariants
class FullName:
first_name: str
last_name: str
def __post_init__(self):
if not self.last_name:
self.last_name = "Doe"
@invariant
def first_name_must_not_be_empty(self) -> bool:
return len(self.first_name.strip()) > 0
@invariant
def last_name_must_not_be_empty(self) -> bool:
return len(self.last_name.strip()) > 0