vega-framework 0.1.15__py3-none-any.whl → 0.1.17__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- vega/cli/__init__.py +7 -1
- vega/cli/commands/generate.py +138 -0
- vega/cli/commands/migrate.py +3 -2
- vega/cli/main.py +5 -2
- vega/cli/templates/__init__.py +4 -0
- vega/cli/templates/cli/command.py.j2 +40 -0
- vega/cli/templates/cli/command_simple.py.j2 +19 -0
- vega/cli/templates/components.py +48 -0
- vega/cli/templates/project/ARCHITECTURE.md.j2 +267 -1
- vega/cli/templates/project/README.md.j2 +133 -14
- vega/cli/templates/project/config.py.j2 +2 -0
- vega/cli/templates/project/main_fastapi.py.j2 +28 -0
- vega/cli/templates/project/main_standard.py.j2 +25 -1
- vega/cli/utils/__init__.py +3 -0
- vega/cli/utils/async_support.py +55 -0
- vega_framework-0.1.17.dist-info/METADATA +483 -0
- {vega_framework-0.1.15.dist-info → vega_framework-0.1.17.dist-info}/RECORD +20 -17
- vega_framework-0.1.15.dist-info/METADATA +0 -158
- {vega_framework-0.1.15.dist-info → vega_framework-0.1.17.dist-info}/WHEEL +0 -0
- {vega_framework-0.1.15.dist-info → vega_framework-0.1.17.dist-info}/entry_points.txt +0 -0
- {vega_framework-0.1.15.dist-info → vega_framework-0.1.17.dist-info}/licenses/LICENSE +0 -0
@@ -20,15 +20,11 @@ Vega Framework application with Clean Architecture.
|
|
20
20
|
│ └── services/ # Service implementations
|
21
21
|
│
|
22
22
|
├── presentation/ # Delivery mechanisms
|
23
|
-
|
24
|
-
│ ├── web/ # FastAPI web interface
|
23
|
+
│ ├── web/ # FastAPI web interface (if added)
|
25
24
|
│ │ ├── routes/ # HTTP endpoints
|
26
25
|
│ │ ├── app.py # FastAPI app factory
|
27
26
|
│ │ └── main.py # ASGI entrypoint
|
28
|
-
│ └── cli/ # CLI commands (if needed)
|
29
|
-
{% else -%}
|
30
27
|
│ └── cli/ # CLI commands
|
31
|
-
{% endif -%}
|
32
28
|
│
|
33
29
|
├── config.py # Dependency injection setup
|
34
30
|
├── settings.py # Application configuration
|
@@ -45,25 +41,148 @@ poetry install
|
|
45
41
|
cp .env.example .env
|
46
42
|
# Edit .env with your configuration
|
47
43
|
|
48
|
-
#
|
49
|
-
|
50
|
-
|
51
|
-
|
44
|
+
# Run CLI commands
|
45
|
+
python main.py hello
|
46
|
+
python main.py greet --name John
|
47
|
+
|
48
|
+
# If using FastAPI template, run the web server
|
49
|
+
python main.py web
|
50
|
+
python main.py web --reload # With auto-reload
|
51
|
+
# Visit http://localhost:8000/api/health/status
|
52
52
|
|
53
53
|
# Run tests
|
54
54
|
poetry run pytest
|
55
55
|
```
|
56
56
|
|
57
|
+
## Development with Vega CLI
|
58
|
+
|
59
|
+
### Generate Components
|
60
|
+
|
61
|
+
Generate Clean Architecture components quickly:
|
62
|
+
|
63
|
+
```bash
|
64
|
+
# Domain layer
|
65
|
+
vega generate entity Product
|
66
|
+
vega generate repository ProductRepository --impl memory
|
67
|
+
vega generate service EmailService
|
68
|
+
vega generate interactor CreateProduct
|
69
|
+
|
70
|
+
# Application layer
|
71
|
+
vega generate mediator CheckoutFlow
|
72
|
+
|
73
|
+
# Presentation layer (web)
|
74
|
+
vega generate router Product
|
75
|
+
vega generate middleware Logging
|
76
|
+
|
77
|
+
# Presentation layer (CLI)
|
78
|
+
vega generate command CreateUser
|
79
|
+
vega generate command ListUsers --impl sync
|
80
|
+
```
|
81
|
+
|
82
|
+
### Add Features
|
83
|
+
|
84
|
+
Add FastAPI web support to your project:
|
85
|
+
|
86
|
+
```bash
|
87
|
+
vega add web
|
88
|
+
```
|
89
|
+
|
90
|
+
### Add Database Support
|
91
|
+
|
92
|
+
Add SQLAlchemy and Alembic for database management:
|
93
|
+
|
94
|
+
```bash
|
95
|
+
vega add sqlalchemy # or: vega add db
|
96
|
+
```
|
97
|
+
|
98
|
+
Then manage your database:
|
99
|
+
|
100
|
+
```bash
|
101
|
+
# Initialize database
|
102
|
+
vega migrate init
|
103
|
+
|
104
|
+
# Create migrations
|
105
|
+
vega migrate create -m "Add users table"
|
106
|
+
|
107
|
+
# Apply migrations
|
108
|
+
vega migrate upgrade
|
109
|
+
|
110
|
+
# Rollback migrations
|
111
|
+
vega migrate downgrade
|
112
|
+
```
|
113
|
+
|
114
|
+
### Generate Database Models
|
115
|
+
|
116
|
+
After adding SQLAlchemy support:
|
117
|
+
|
118
|
+
```bash
|
119
|
+
vega generate model User
|
120
|
+
vega generate model Product
|
121
|
+
```
|
122
|
+
|
123
|
+
## Using Async Commands
|
124
|
+
|
125
|
+
Vega Framework supports async/await in CLI commands, allowing you to execute interactors seamlessly:
|
126
|
+
|
127
|
+
```python
|
128
|
+
import click
|
129
|
+
from vega.cli.utils import async_command
|
130
|
+
|
131
|
+
@click.command()
|
132
|
+
@click.option('--name', required=True)
|
133
|
+
@async_command
|
134
|
+
async def create_user(name: str):
|
135
|
+
"""Create a user using an interactor"""
|
136
|
+
import config # Initialize DI container
|
137
|
+
from domain.interactors.create_user import CreateUser
|
138
|
+
|
139
|
+
user = await CreateUser(name=name)
|
140
|
+
click.echo(f"Created: {user.name}")
|
141
|
+
```
|
142
|
+
|
143
|
+
This allows the same async business logic to work in both CLI and web contexts (FastAPI).
|
144
|
+
|
145
|
+
## Project Commands Quick Reference
|
146
|
+
|
147
|
+
```bash
|
148
|
+
# Component generation
|
149
|
+
vega generate entity <Name>
|
150
|
+
vega generate repository <Name> [--impl memory|sql]
|
151
|
+
vega generate interactor <Name>
|
152
|
+
vega generate mediator <Name>
|
153
|
+
vega generate command <Name> [--impl sync]
|
154
|
+
|
155
|
+
# Feature management
|
156
|
+
vega add web
|
157
|
+
vega add sqlalchemy
|
158
|
+
|
159
|
+
# Database management (requires SQLAlchemy)
|
160
|
+
vega migrate init
|
161
|
+
vega migrate create -m "message"
|
162
|
+
vega migrate upgrade
|
163
|
+
vega migrate downgrade
|
164
|
+
|
165
|
+
# Project validation
|
166
|
+
vega doctor
|
167
|
+
|
168
|
+
# Framework updates
|
169
|
+
vega update
|
170
|
+
vega update --check
|
171
|
+
```
|
172
|
+
|
57
173
|
## Vega Framework
|
58
174
|
|
59
|
-
This project uses [Vega Framework](https://github.com/
|
175
|
+
This project uses [Vega Framework](https://github.com/robertosixty1/vega-framework) for Clean Architecture:
|
60
176
|
|
61
|
-
- Automatic Dependency Injection
|
62
|
-
- Clean Architecture patterns (4 layers: Domain, Application, Infrastructure, Presentation)
|
63
|
-
- Type-safe with Python type hints
|
64
|
-
-
|
177
|
+
- ✅ Automatic Dependency Injection
|
178
|
+
- ✅ Clean Architecture patterns (4 layers: Domain, Application, Infrastructure, Presentation)
|
179
|
+
- ✅ Type-safe with Python type hints
|
180
|
+
- ✅ Async/await support for CLI and web
|
181
|
+
- ✅ Easy to test and maintain
|
182
|
+
- ✅ Framework-agnostic business logic
|
65
183
|
|
66
184
|
## Documentation
|
67
185
|
|
68
186
|
- [Vega Framework Docs](https://vega-framework.readthedocs.io/)
|
69
187
|
- [Clean Architecture](https://blog.cleancoder.com/uncle-bob/2012/08/13/the-clean-architecture.html)
|
188
|
+
- [Vega CLI Reference](https://github.com/robertosixty1/vega-framework#cli-commands)
|
@@ -10,6 +10,8 @@ from vega.di import Container, set_container
|
|
10
10
|
# from {{ project_name }}.infrastructure.repositories.memory_user_repository import MemoryUserRepository
|
11
11
|
|
12
12
|
# Uncomment and configure database manager if using SQLAlchemy
|
13
|
+
|
14
|
+
# from settings import settings
|
13
15
|
# from infrastructure.database_manager import DatabaseManager
|
14
16
|
# db_manager = DatabaseManager(url=settings.database_url)
|
15
17
|
|
@@ -1,7 +1,11 @@
|
|
1
1
|
"""Main entry point for {{ project_name }}"""
|
2
2
|
import click
|
3
|
+
from vega.cli.utils import async_command
|
3
4
|
import config # noqa: F401 - Import to initialize DI container
|
4
5
|
|
6
|
+
# Import your use cases here
|
7
|
+
# from domain.interactors.create_user import CreateUser
|
8
|
+
|
5
9
|
|
6
10
|
@click.group()
|
7
11
|
def cli():
|
@@ -34,6 +38,30 @@ def hello():
|
|
34
38
|
click.echo("Add your CLI commands in presentation/cli/commands/")
|
35
39
|
|
36
40
|
|
41
|
+
@cli.command()
|
42
|
+
@click.option('--name', required=True, help='User name')
|
43
|
+
@click.option('--email', required=True, help='User email')
|
44
|
+
@async_command
|
45
|
+
async def create_user(name: str, email: str):
|
46
|
+
"""
|
47
|
+
Example async CLI command that uses an interactor.
|
48
|
+
|
49
|
+
This demonstrates how to use async/await with Click commands
|
50
|
+
to execute interactors and other async operations.
|
51
|
+
|
52
|
+
Usage:
|
53
|
+
python main.py create-user --name="John Doe" --email="john@example.com"
|
54
|
+
"""
|
55
|
+
# Import your interactor
|
56
|
+
# from domain.interactors.create_user import CreateUser
|
57
|
+
# user = await CreateUser(name=name, email=email)
|
58
|
+
# click.echo(f"Created user: {user.id} - {user.name}")
|
59
|
+
|
60
|
+
# Placeholder implementation
|
61
|
+
click.echo(f"Creating user: {name} ({email})")
|
62
|
+
click.echo("Note: Replace this with your actual CreateUser interactor")
|
63
|
+
|
64
|
+
|
37
65
|
# Add more CLI commands here or import them from presentation/cli/commands/
|
38
66
|
|
39
67
|
|
@@ -1,6 +1,6 @@
|
|
1
1
|
"""Main entry point for {{ project_name }}"""
|
2
|
-
import asyncio
|
3
2
|
import click
|
3
|
+
from vega.cli.utils import async_command
|
4
4
|
import config # noqa: F401 - Import to initialize DI container
|
5
5
|
|
6
6
|
# Import your use cases here
|
@@ -27,6 +27,30 @@ def greet(name: str):
|
|
27
27
|
click.echo(f"Hello, {name}!")
|
28
28
|
|
29
29
|
|
30
|
+
@cli.command()
|
31
|
+
@click.option('--name', required=True, help='User name')
|
32
|
+
@click.option('--email', required=True, help='User email')
|
33
|
+
@async_command
|
34
|
+
async def create_user(name: str, email: str):
|
35
|
+
"""
|
36
|
+
Example async command that uses an interactor.
|
37
|
+
|
38
|
+
This demonstrates how to use async/await with Click commands
|
39
|
+
to execute interactors and other async operations.
|
40
|
+
|
41
|
+
Usage:
|
42
|
+
python main.py create-user --name="John Doe" --email="john@example.com"
|
43
|
+
"""
|
44
|
+
# Import your interactor
|
45
|
+
# from domain.interactors.create_user import CreateUser
|
46
|
+
# user = await CreateUser(name=name, email=email)
|
47
|
+
# click.echo(f"Created user: {user.id} - {user.name}")
|
48
|
+
|
49
|
+
# Placeholder implementation
|
50
|
+
click.echo(f"Creating user: {name} ({email})")
|
51
|
+
click.echo("Note: Replace this with your actual CreateUser interactor")
|
52
|
+
|
53
|
+
|
30
54
|
# Uncomment this block if you enable FastAPI support
|
31
55
|
# @cli.command()
|
32
56
|
# @click.option('--host', default='0.0.0.0', help='Host to bind')
|
vega/cli/utils/__init__.py
CHANGED
@@ -2,10 +2,13 @@
|
|
2
2
|
from .naming import NamingConverter
|
3
3
|
from .messages import CLIMessages
|
4
4
|
from .validators import validate_project_name, validate_path_exists
|
5
|
+
from .async_support import async_command, coro
|
5
6
|
|
6
7
|
__all__ = [
|
7
8
|
"NamingConverter",
|
8
9
|
"CLIMessages",
|
9
10
|
"validate_project_name",
|
10
11
|
"validate_path_exists",
|
12
|
+
"async_command",
|
13
|
+
"coro",
|
11
14
|
]
|
@@ -0,0 +1,55 @@
|
|
1
|
+
"""Async support utilities for Click CLI commands"""
|
2
|
+
import asyncio
|
3
|
+
import functools
|
4
|
+
from typing import TypeVar, Callable, Any
|
5
|
+
|
6
|
+
import click
|
7
|
+
|
8
|
+
F = TypeVar('F', bound=Callable[..., Any])
|
9
|
+
|
10
|
+
|
11
|
+
def async_command(f: F) -> F:
|
12
|
+
"""
|
13
|
+
Decorator to make Click commands support async functions.
|
14
|
+
|
15
|
+
This allows you to define async Click commands that can call
|
16
|
+
async interactors and other async operations.
|
17
|
+
|
18
|
+
Example:
|
19
|
+
@click.command()
|
20
|
+
@click.option('--name', required=True)
|
21
|
+
@async_command
|
22
|
+
async def create_user(name: str):
|
23
|
+
# Import config to initialize DI container
|
24
|
+
import config # noqa: F401
|
25
|
+
from domain.interactors.create_user import CreateUser
|
26
|
+
|
27
|
+
user = await CreateUser(name=name)
|
28
|
+
click.echo(f"Created user: {user.name}")
|
29
|
+
|
30
|
+
Usage in Click groups:
|
31
|
+
@cli.command()
|
32
|
+
@click.argument('user_id')
|
33
|
+
@async_command
|
34
|
+
async def get_user(user_id: str):
|
35
|
+
user = await GetUser(user_id=user_id)
|
36
|
+
click.echo(f"User: {user.name}")
|
37
|
+
"""
|
38
|
+
@functools.wraps(f)
|
39
|
+
def wrapper(*args: Any, **kwargs: Any) -> Any:
|
40
|
+
return asyncio.run(f(*args, **kwargs))
|
41
|
+
return wrapper # type: ignore
|
42
|
+
|
43
|
+
|
44
|
+
def coro(f: F) -> F:
|
45
|
+
"""
|
46
|
+
Alias for async_command. Shorter name for convenience.
|
47
|
+
|
48
|
+
Example:
|
49
|
+
@click.command()
|
50
|
+
@coro
|
51
|
+
async def my_command():
|
52
|
+
result = await MyInteractor()
|
53
|
+
click.echo(result)
|
54
|
+
"""
|
55
|
+
return async_command(f)
|