Core Concepts¶
Understand the architectural patterns used in this template.
Overview¶
This template uses several design patterns to achieve clean, testable, and maintainable code:
-
IoC Container (punq)
Dependency injection for decoupled, testable components.
-
Controller Pattern
Consistent interface for HTTP, bot, and task handlers.
-
Pydantic Settings
Type-safe configuration with environment variable support.
-
Factory Pattern
Flexible object creation with IoC integration.
How They Work Together¶
┌────────────────────────────────────────────────┐
│ Environment Variables │
└────────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ Pydantic Settings Classes │
│ (Type-safe, validated configuration) │
└────────────────────┬───────────────────────────┘
│
▼
┌────────────────────────────────────────────────┐
│ IoC Container (punq) │
│ (Registers settings, services, controllers) │
└────────────────────┬───────────────────────────┘
│
┌──────────┼──────────┐
│ │ │
▼ ▼ ▼
┌─────────────┐ ┌─────────┐ ┌─────────────┐
│ Factories │ │Services │ │ Controllers │
│ (Create API,│ │ (JWT, │ │ (HTTP, │
│ Bot, etc.) │ │ Refresh)│ │ Bot, Task) │
└─────────────┘ └─────────┘ └─────────────┘
Key Principles¶
1. Dependency Inversion¶
High-level modules don't depend on low-level modules. Both depend on abstractions (interfaces).
# Controller depends on abstract JWTAuth, not concrete implementation
class UserController(Controller):
def __init__(self, auth: JWTAuth) -> None:
self._auth = auth
2. Single Responsibility¶
Each class has one reason to change:
- Settings — Configuration
- Services — Business logic
- Controllers — HTTP/Bot/Task handling
- Factories — Object creation
3. Explicit Dependencies¶
All dependencies are declared in __init__, making them visible and testable:
class RefreshSessionService:
def __init__(
self,
settings: RefreshSessionServiceSettings,
refresh_session_model: type[BaseRefreshSession],
) -> None:
self._settings = settings
self._refresh_session_model = refresh_session_model
4. Interface Segregation¶
Controllers implement only what they need: