CLI tool for generating DDD architecture in Python projects
Project description
PyConstructor ๐๏ธ
PyConstructor is a command-line tool that helps developers quickly create a project structure following Domain-Driven Design (DDD) principles. The tool generates architecture based on a YAML configuration that defines bounded contexts, entities, repositories, services, use cases, and other DDD elements.
๐ Quick Start
Installation
# Install via pip
pip install pyconstructor
# Install via uv
uv add pyconstructor
# Generate YAML file with example data
pyc init
# Edit the generated ddd-config.yaml file
# ...
# Generate structure
pyc run
Basic Usage
- Initialize a new project with a preset configuration:
pyc init --preset <PresetType(Optional argument, default to Standard)>
- Validate your configuration (Optional command):
pyc validate
- Preview the project structure (Optional command):
pyc preview --file <file_name> (Optional argument)
- Generate the project:
pyc run --file <file_name> (Optional argument)
๐ Available Commands
Core Commands
| Command | Description | Example |
|---|---|---|
init |
Initialize a new project with a preset configuration | pyc init --preset standard |
validate |
Validate your YAML configuration | pyc validate --file custom-config.yaml |
preview |
Preview the project structure without generating files | pyc preview --file custom-config.yaml |
run |
Generate the project structure | pyc run --file custom-config.yaml |
Command Options
init Command
# Create project with standard preset
pyc init --preset standard
# Force overwrite existing config
pyc init --preset standard --force
validate Command
# Validate default config (ddd-config.yaml)
pyc validate
# Validate specific config file
pyc validate --file custom-config.yaml
preview Command
# Preview default config
pyc preview
# Preview specific config
pyc preview --file custom-config.yaml
Output:
- Displays the project structure tree in the console
- Generates a
structure.mdfile with the same tree view for future reference
Example output:
app/
โโโ domain/
โ โโโ user/
โ โ โโโ entities/
โ โ โ โโโ user.py
โ โ โโโ value_objects/
โ โ โโโ email.py
โ โโโ catalog/
โ โโโ entities/
โ โโโ product.py
โโโ application/
โ โโโ user/
โ โโโ use_cases/
โ โโโ register_user.py
โโโ infrastructure/
โโโ repositories/
โโโ user_repository.py
run Command
# Generate from default config
pyc run
# Generate from specific config
pyc run --file custom-config.yaml
Architecture Presets
PyConstructor comes with three built-in presets:
Simple Preset
Basic DDD structure without bounded contexts:
pyc init --preset simple
Standard Preset
Default preset with bounded contexts:
pyc init --preset standard
Advanced Preset
Complex structure with nested contexts:
pyc init --preset advanced
Configuration
The tool uses YAML configuration files to define your project structure.
Example configurations are provided in the src/templates/config_templates directory.
Configuration Reference
Settings Section
settings:
preset: "standard" # One of: "simple", "standard", "advanced"
use_contexts: true # Whether to use bounded contexts
contexts_layout: "flat" # One of: "flat", "nested"
group_components: true # Group similar components in directories
init_imports: false # Initialize imports in __init__.py files
root_name: "src" # Root directory name
Simple Configuration Example
settings:
preset: "simple"
layers:
domain:
entities: User, Product
value_objects: Email, Price
Standard Configuration Example
settings:
preset: "standard"
layers:
domain:
contexts:
- name: user
entities: [User, Profile]
value_objects: [Email, Password]
- name: catalog
entities: [Product, Category]
Advanced Configuration Example (for microservice architecture)
settings:
preset: "advanced"
layers:
contexts:
- name: user_context
domain:
entities: User
value_objects: Email
application:
use_cases: CreateUser
infrastructure:
repositories: UserRepository
- name: payment_context
domain:
entities: Payment
application:
use_cases: ProcessPayment
infrastructure:
repositories: TransactionRepository
Complete Configuration Example
Here's a complete example showing all available options:
settings:
preset: "advanced"
use_contexts: true
contexts_layout: "nested"
group_components: true
init_imports: true
root_name: "src"
layers:
contexts:
- name: user_context
domain:
entities: User, Profile
value_objects: Email, Password, UserRole
aggregates: UserAggregate
repositories: UserRepository
services: UserService
application:
use_cases: CreateUser, UpdateUser, DeleteUser
commands: CreateUserCommand, UpdateUserCommand
queries: GetUserQuery, ListUsersQuery
events: UserCreatedEvent, UserUpdatedEvent
dtos: UserDTO, UserCreateDTO
mappers: UserMapper
infrastructure:
repositories: UserRepositoryImpl
services: UserServiceImpl
interface:
controllers: [UserController]
middleware: AuthMiddleware
- name: order_context
domain:
entities: Order, OrderItem
value_objects: Money, OrderStatus
aggregates: OrderAggregate
repositories: OrderRepository
services: OrderService
application:
use_cases: CreateOrder, UpdateOrder
commands: CreateOrderCommand
queries: GetOrderQuery
events: OrderCreatedEvent
dtos: OrderDTO
mappers: OrderMapper
infrastructure:
repositories: OrderRepositoryImpl
interface:
controllers: OrderController
Generated Structure
When using the advanced configuration above, the tool will generate a structure like this:
src/
โโโ user_context/
โ โโโ domain/
โ โ โโโ entities/
โ โ โ โโโ user.py
โ โ โ โโโ profile.py
โ โ โโโ value_objects/
โ โ โ โโโ email.py
โ โ โ โโโ password.py
โ โ โ โโโ user_role.py
โ โ โโโ aggregates/
โ โ โ โโโ user_aggregate.py
โ โ โโโ repositories/
โ โ โ โโโ user_repository.py
โ โ โโโ services/
โ โ โโโ user_service.py
โ โโโ application/
โ โ โโโ use_cases/
โ โ โ โโโ create_user.py
โ โ โ โโโ update_user.py
โ โ โ โโโ delete_user.py
โ โ โโโ commands/
โ โ โ โโโ create_user_command.py
โ โ โ โโโ update_user_command.py
โ โ โโโ queries/
โ โ โ โโโ get_user_query.py
โ โ โ โโโ list_users_query.py
โ โ โโโ events/
โ โ โ โโโ user_created_event.py
โ โ โ โโโ user_updated_event.py
โ โ โโโ dtos/
โ โ โ โโโ user_dto.py
โ โ โ โโโ user_create_dto.py
โ โ โโโ mappers/
โ โ โโโ user_mapper.py
โ โโโ infrastructure/
โ โ โโโ repositories/
โ โ โ โโโ user_repository_impl.py
โ โ โโโ services/
โ โ โโโ user_service_impl.py
โ โโโ interface/
โ โโโ controllers/
โ โ โโโ user_controller.py
โ โโโ middleware/
โ โโโ auth_middleware.py
โโโ order_context/
โโโ ... (similar structure)
Customizing Templates
You can customize the generated files by modifying the templates in the src/templates directory. Each component type has its own template file that you can modify to suit your needs.
FAQ
Getting Started
Q: Which preset should I choose for my project? A:
- Simple: Perfect for learning DDD or small projects without complex contexts
- Standard: Best for most real-world projects with clear bounded contexts
- Advanced: Use for microservices architecture or when you need maximum flexibility
Q: What happens if files already exist in my project? A: PyConstructor adds new files and directories to your existing structure without touching existing files. This means:
- New components will be created alongside existing ones
- Existing
__init__.pyfiles won't be modified - You can safely run it on existing projects
Q: Can I see what will be generated before actually creating files? A: Yes! Use the preview command:
pyc preview
# or
pyc preview --file your-config.yaml
This shows the complete directory structure in console and generates a structure.md file.
Configuration
Q: How do I add more components after initial generation? A: Simply:
- Edit your YAML configuration file to add new components
- Run
pyc runagain - it will add only the new components - Existing files remain untouched
Q: Can I customize the generated code templates?
A: Yes, but it's not officially supported yet. Templates are located in src/templates/. Modifying them directly will affect all generations. Official template customization API is planned.
Q: What's the difference between 'flat' and 'nested' context layouts? A:
- Flat:
src/domain/user_context/entities/(contexts inside layers) - Nested:
src/user_context/domain/entities/(layers inside contexts)
Troubleshooting
Q: I get "Configuration file not found" error
A: Make sure you have a ddd-config.yaml file in your current directory, or specify the path:
pyc run --file path/to/your/config.yaml
Q: YAML validation fails with cryptic errors A: Common issues:
- Incorrect indentation (use spaces, not tabs)
- Missing quotes around special characters
- Empty values should be written as
[]or omitted entirely
Q: Generated code doesn't follow my coding standards A: Currently, PyConstructor generates basic templates. You can:
- Modify templates in
src/templates/(advanced users) - Use code formatters (black, ruff) after generation
Integration
Q: Can I use this with existing projects? A: Yes! PyConstructor safely adds new structure to existing projects:
- Creates new directories and files without touching existing ones
- Preserves your current codebase
- Perfect for gradually introducing DDD structure
- Just make sure your config doesn't conflict with existing file names
Roadmap & Limitations
Q: What features are planned for future releases? A:
- Custom template support
- Framework-specific generators (FastAPI, Django)
- Interactive configuration builder
- Migration tools for existing codebases
- Advanced DDD patterns support
๐ค Contributing
Contributions are welcome. Please feel free to submit a Pull Request.
- Fork the repository
- Create your feature branch (
git switch -c feature/amazing-feature) - Run tests (
pytest) - Commit your changes (
git commit -m 'Add amazing feature') - Push to the branch (
git push origin feature/amazing-feature) - Open a Pull Request
๐ License
This project is licensed under the MIT Licenseโsee the LICENSE file for details.
๐ค Author
Grigoriy Sokolov (Sokolov_Gr@proton.me)
Project details
Release history Release notifications | RSS feed
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 pyconstructor-0.2.2.tar.gz.
File metadata
- Download URL: pyconstructor-0.2.2.tar.gz
- Upload date:
- Size: 12.7 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1ff67e11d91c80040c784f8ed0cbaa3bde4b6fd36de9231735ac49c6c5e82571
|
|
| MD5 |
01050c0595e5e57b581d41e315ad672f
|
|
| BLAKE2b-256 |
1e4e1f3011d902f04f6d121c56d7eee5515b148d7e1f55c99d0063db2a9565fa
|
Provenance
The following attestation bundles were made for pyconstructor-0.2.2.tar.gz:
Publisher:
publish.yaml on SokolovG/PyConstruct
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyconstructor-0.2.2.tar.gz -
Subject digest:
1ff67e11d91c80040c784f8ed0cbaa3bde4b6fd36de9231735ac49c6c5e82571 - Sigstore transparency entry: 231332289
- Sigstore integration time:
-
Permalink:
SokolovG/PyConstruct@22a92f7aa5136a63783a121a10563ca05bf7d04c -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/SokolovG
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@22a92f7aa5136a63783a121a10563ca05bf7d04c -
Trigger Event:
release
-
Statement type:
File details
Details for the file pyconstructor-0.2.2-py3-none-any.whl.
File metadata
- Download URL: pyconstructor-0.2.2-py3-none-any.whl
- Upload date:
- Size: 8.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.12.9
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
edf23dc26d1ef6f023130a37cd3c81350e5004daacf06d2d6f742a07d21b5ad0
|
|
| MD5 |
68b49a9c3ac3873c605d622fa198feee
|
|
| BLAKE2b-256 |
746169b586a48548f728c08d768632a888393ea8e57640dea6574337a8281a83
|
Provenance
The following attestation bundles were made for pyconstructor-0.2.2-py3-none-any.whl:
Publisher:
publish.yaml on SokolovG/PyConstruct
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
pyconstructor-0.2.2-py3-none-any.whl -
Subject digest:
edf23dc26d1ef6f023130a37cd3c81350e5004daacf06d2d6f742a07d21b5ad0 - Sigstore transparency entry: 231332302
- Sigstore integration time:
-
Permalink:
SokolovG/PyConstruct@22a92f7aa5136a63783a121a10563ca05bf7d04c -
Branch / Tag:
refs/tags/v0.2.2 - Owner: https://github.com/SokolovG
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yaml@22a92f7aa5136a63783a121a10563ca05bf7d04c -
Trigger Event:
release
-
Statement type: