vega-framework 0.1.34__tar.gz → 0.2.0__tar.gz

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.
Files changed (102) hide show
  1. {vega_framework-0.1.34 → vega_framework-0.2.0}/PKG-INFO +10 -9
  2. {vega_framework-0.1.34 → vega_framework-0.2.0}/README.md +8 -7
  3. {vega_framework-0.1.34 → vega_framework-0.2.0}/pyproject.toml +28 -2
  4. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/commands/add.py +9 -10
  5. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/commands/init.py +9 -8
  6. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/main.py +4 -4
  7. vega_framework-0.2.0/vega/cli/scaffolds/__init__.py +13 -0
  8. vega_framework-0.2.0/vega/cli/scaffolds/vega_web.py +109 -0
  9. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/__init__.py +34 -8
  10. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/components.py +29 -13
  11. vega_framework-0.2.0/vega/cli/templates/web/app.py.j2 +15 -0
  12. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/health_route.py.j2 +2 -2
  13. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/router.py.j2 +2 -2
  14. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/routes_init_autodiscovery.py.j2 +2 -2
  15. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/users_route.py.j2 +2 -2
  16. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/discovery/routes.py +13 -13
  17. vega_framework-0.2.0/vega/web/__init__.py +100 -0
  18. vega_framework-0.2.0/vega/web/application.py +234 -0
  19. vega_framework-0.2.0/vega/web/builtin_middlewares.py +288 -0
  20. vega_framework-0.2.0/vega/web/exceptions.py +151 -0
  21. vega_framework-0.2.0/vega/web/middleware.py +185 -0
  22. vega_framework-0.2.0/vega/web/request.py +120 -0
  23. vega_framework-0.2.0/vega/web/response.py +220 -0
  24. vega_framework-0.2.0/vega/web/route_middleware.py +266 -0
  25. vega_framework-0.2.0/vega/web/router.py +350 -0
  26. vega_framework-0.2.0/vega/web/routing.py +347 -0
  27. vega_framework-0.1.34/vega/cli/scaffolds/__init__.py +0 -9
  28. vega_framework-0.1.34/vega/cli/templates/web/app.py.j2 +0 -15
  29. {vega_framework-0.1.34 → vega_framework-0.2.0}/LICENSE +0 -0
  30. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/__init__.py +0 -0
  31. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/__init__.py +0 -0
  32. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/commands/__init__.py +0 -0
  33. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/commands/generate.py +0 -0
  34. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/commands/migrate.py +0 -0
  35. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/commands/update.py +0 -0
  36. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/commands/web.py +0 -0
  37. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/scaffolds/fastapi.py +0 -0
  38. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/scaffolds/sqlalchemy.py +0 -0
  39. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/cli/command.py.j2 +0 -0
  40. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/cli/command_simple.py.j2 +0 -0
  41. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/cli/commands_init.py.j2 +0 -0
  42. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/domain/entity.py.j2 +0 -0
  43. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/domain/event.py.j2 +0 -0
  44. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/domain/event_handler.py.j2 +0 -0
  45. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/domain/interactor.py.j2 +0 -0
  46. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/domain/mediator.py.j2 +0 -0
  47. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/domain/repository_interface.py.j2 +0 -0
  48. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/domain/service_interface.py.j2 +0 -0
  49. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/infrastructure/model.py.j2 +0 -0
  50. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/infrastructure/repository_impl.py.j2 +0 -0
  51. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/infrastructure/service_impl.py.j2 +0 -0
  52. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/loader.py +0 -0
  53. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/.env.example +0 -0
  54. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/.gitignore +0 -0
  55. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/ARCHITECTURE.md.j2 +0 -0
  56. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/README.md.j2 +0 -0
  57. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/config.py.j2 +0 -0
  58. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/events_init.py.j2 +0 -0
  59. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/main.py.j2 +0 -0
  60. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/main_fastapi.py.j2 +0 -0
  61. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/main_standard.py.j2 +0 -0
  62. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/pyproject.toml.j2 +0 -0
  63. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/project/settings.py.j2 +0 -0
  64. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/sqlalchemy/alembic.ini.j2 +0 -0
  65. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/sqlalchemy/database_manager.py.j2 +0 -0
  66. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/sqlalchemy/env.py.j2 +0 -0
  67. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/sqlalchemy/script.py.mako +0 -0
  68. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/__init__.py.j2 +0 -0
  69. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/main.py.j2 +0 -0
  70. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/middleware.py.j2 +0 -0
  71. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/models_init.py.j2 +0 -0
  72. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/request_model.py.j2 +0 -0
  73. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/response_model.py.j2 +0 -0
  74. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/routes_init.py.j2 +0 -0
  75. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/templates/web/user_models.py.j2 +0 -0
  76. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/utils/__init__.py +0 -0
  77. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/utils/async_support.py +0 -0
  78. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/utils/messages.py +0 -0
  79. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/utils/naming.py +0 -0
  80. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/cli/utils/validators.py +0 -0
  81. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/di/__init__.py +0 -0
  82. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/di/container.py +0 -0
  83. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/di/decorators.py +0 -0
  84. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/di/errors.py +0 -0
  85. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/di/scope.py +0 -0
  86. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/discovery/__init__.py +0 -0
  87. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/discovery/commands.py +0 -0
  88. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/discovery/events.py +0 -0
  89. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/events/README.md +0 -0
  90. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/events/SYNTAX_GUIDE.md +0 -0
  91. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/events/__init__.py +0 -0
  92. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/events/bus.py +0 -0
  93. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/events/decorators.py +0 -0
  94. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/events/event.py +0 -0
  95. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/events/middleware.py +0 -0
  96. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/patterns/__init__.py +0 -0
  97. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/patterns/interactor.py +0 -0
  98. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/patterns/mediator.py +0 -0
  99. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/patterns/repository.py +0 -0
  100. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/patterns/service.py +0 -0
  101. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/settings/__init__.py +0 -0
  102. {vega_framework-0.1.34 → vega_framework-0.2.0}/vega/settings/base.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: vega-framework
3
- Version: 0.1.34
3
+ Version: 0.2.0
4
4
  Summary: Enterprise-ready Python framework that enforces Clean Architecture for building maintainable and scalable applications.
5
5
  License: MIT
6
6
  License-File: LICENSE
@@ -19,10 +19,10 @@ Classifier: Programming Language :: Python :: 3.14
19
19
  Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
20
20
  Classifier: Topic :: Software Development :: Libraries :: Python Modules
21
21
  Requires-Dist: click (>=8.0,<9.0)
22
- Requires-Dist: fastapi (>=0.109,<0.110)
23
22
  Requires-Dist: jinja2 (>=3.1,<4.0)
24
23
  Requires-Dist: pydantic (>=2.0,<3.0)
25
24
  Requires-Dist: pydantic-settings (>=2.0,<3.0)
25
+ Requires-Dist: starlette (>=0.37,<0.38)
26
26
  Requires-Dist: toml (>=0.10,<0.11)
27
27
  Requires-Dist: uvicorn (>=0.27,<0.28)
28
28
  Project-URL: Documentation, https://vega-framework.readthedocs.io
@@ -43,7 +43,7 @@ Traditional Python frameworks show you **how to build** but don't enforce **how
43
43
  - ✅ **Business Logic First** - Pure, testable, framework-independent
44
44
  - ✅ **CLI Scaffolding** - Generate entire projects and components
45
45
  - ✅ **Async Support** - Full async/await for CLI and web
46
- - ✅ **FastAPI & SQLAlchemy** - Built-in integrations when needed
46
+ - ✅ **Vega Web (Starlette) & SQLAlchemy** - Built-in integrations when needed
47
47
 
48
48
  **[Read the Philosophy →](docs/explanation/philosophy.md)** to understand why architecture matters.
49
49
 
@@ -152,7 +152,7 @@ container = Container({
152
152
 
153
153
  ```bash
154
154
  vega init my-app # Create new project
155
- vega init my-api --template fastapi # Create with FastAPI
155
+ vega init my-api --template web # Create with Vega Web
156
156
  vega doctor # Validate architecture
157
157
  vega update # Update framework
158
158
  ```
@@ -169,7 +169,7 @@ vega generate interactor CreateProduct
169
169
  vega generate mediator CheckoutWorkflow
170
170
 
171
171
  # Presentation layer
172
- vega generate router Product # FastAPI (requires: vega add web)
172
+ vega generate router Product # Vega Web (requires: vega add web)
173
173
  vega generate command create-product # CLI
174
174
 
175
175
  # Infrastructure
@@ -179,7 +179,7 @@ vega generate model Product # SQLAlchemy (requires: vega add db)
179
179
  ### Add Features
180
180
 
181
181
  ```bash
182
- vega add web # Add FastAPI web support
182
+ vega add web # Add Vega Web support
183
183
  vega add sqlalchemy # Add database support
184
184
  ```
185
185
 
@@ -232,6 +232,7 @@ await UserCreated(user_id="123", email="test@test.com").publish()
232
232
  - [Patterns](docs/explanation/patterns/interactor.md) - Interactor, Mediator, Repository, Service
233
233
 
234
234
  ### Guides
235
+ - [Use Vega Web](docs/how-to/use-vega-web.md) - Build HTTP APIs with Vega's router and middleware
235
236
  - [Building Domain Layer](docs/how-to/build-domain-layer.md) - Business logic first
236
237
  - [CLI Reference](docs/reference/cli/overview.md) - All CLI commands
237
238
  - [Events System](docs/explanation/events/overview.md) - Event-driven architecture
@@ -268,7 +269,7 @@ my-app/
268
269
  │ └── services/ # API integrations
269
270
  ├── presentation/ # User interfaces
270
271
  │ ├── cli/ # CLI commands
271
- │ └── web/ # FastAPI routes
272
+ │ └── web/ # Vega Web routes
272
273
  ├── config.py # Dependency injection
273
274
  ├── settings.py # Configuration
274
275
  └── main.py # Entry point
@@ -289,7 +290,7 @@ async def create_order(request: Request):
289
290
  ```
290
291
 
291
292
  **Problems:**
292
- - Can't test without FastAPI, database, and Stripe
293
+ - Can't test without the web framework, database, and Stripe
293
294
  - Can't reuse for CLI or other interfaces
294
295
  - Business rules are unclear
295
296
  - Tightly coupled to specific technologies
@@ -309,7 +310,7 @@ class PlaceOrder(Interactor[Order]):
309
310
  await payment_service.charge(...)
310
311
  return await order_repo.save(order)
311
312
 
312
- # ✅ FastAPI route (Presentation) - just wiring
313
+ # ✅ Vega Web route (Presentation) - just wiring
313
314
  @router.post("/orders")
314
315
  async def create_order_api(request: CreateOrderRequest):
315
316
  return await PlaceOrder(...)
@@ -11,7 +11,7 @@ Traditional Python frameworks show you **how to build** but don't enforce **how
11
11
  - ✅ **Business Logic First** - Pure, testable, framework-independent
12
12
  - ✅ **CLI Scaffolding** - Generate entire projects and components
13
13
  - ✅ **Async Support** - Full async/await for CLI and web
14
- - ✅ **FastAPI & SQLAlchemy** - Built-in integrations when needed
14
+ - ✅ **Vega Web (Starlette) & SQLAlchemy** - Built-in integrations when needed
15
15
 
16
16
  **[Read the Philosophy →](docs/explanation/philosophy.md)** to understand why architecture matters.
17
17
 
@@ -120,7 +120,7 @@ container = Container({
120
120
 
121
121
  ```bash
122
122
  vega init my-app # Create new project
123
- vega init my-api --template fastapi # Create with FastAPI
123
+ vega init my-api --template web # Create with Vega Web
124
124
  vega doctor # Validate architecture
125
125
  vega update # Update framework
126
126
  ```
@@ -137,7 +137,7 @@ vega generate interactor CreateProduct
137
137
  vega generate mediator CheckoutWorkflow
138
138
 
139
139
  # Presentation layer
140
- vega generate router Product # FastAPI (requires: vega add web)
140
+ vega generate router Product # Vega Web (requires: vega add web)
141
141
  vega generate command create-product # CLI
142
142
 
143
143
  # Infrastructure
@@ -147,7 +147,7 @@ vega generate model Product # SQLAlchemy (requires: vega add db)
147
147
  ### Add Features
148
148
 
149
149
  ```bash
150
- vega add web # Add FastAPI web support
150
+ vega add web # Add Vega Web support
151
151
  vega add sqlalchemy # Add database support
152
152
  ```
153
153
 
@@ -200,6 +200,7 @@ await UserCreated(user_id="123", email="test@test.com").publish()
200
200
  - [Patterns](docs/explanation/patterns/interactor.md) - Interactor, Mediator, Repository, Service
201
201
 
202
202
  ### Guides
203
+ - [Use Vega Web](docs/how-to/use-vega-web.md) - Build HTTP APIs with Vega's router and middleware
203
204
  - [Building Domain Layer](docs/how-to/build-domain-layer.md) - Business logic first
204
205
  - [CLI Reference](docs/reference/cli/overview.md) - All CLI commands
205
206
  - [Events System](docs/explanation/events/overview.md) - Event-driven architecture
@@ -236,7 +237,7 @@ my-app/
236
237
  │ └── services/ # API integrations
237
238
  ├── presentation/ # User interfaces
238
239
  │ ├── cli/ # CLI commands
239
- │ └── web/ # FastAPI routes
240
+ │ └── web/ # Vega Web routes
240
241
  ├── config.py # Dependency injection
241
242
  ├── settings.py # Configuration
242
243
  └── main.py # Entry point
@@ -257,7 +258,7 @@ async def create_order(request: Request):
257
258
  ```
258
259
 
259
260
  **Problems:**
260
- - Can't test without FastAPI, database, and Stripe
261
+ - Can't test without the web framework, database, and Stripe
261
262
  - Can't reuse for CLI or other interfaces
262
263
  - Business rules are unclear
263
264
  - Tightly coupled to specific technologies
@@ -277,7 +278,7 @@ class PlaceOrder(Interactor[Order]):
277
278
  await payment_service.charge(...)
278
279
  return await order_repo.save(order)
279
280
 
280
- # ✅ FastAPI route (Presentation) - just wiring
281
+ # ✅ Vega Web route (Presentation) - just wiring
281
282
  @router.post("/orders")
282
283
  async def create_order_api(request: CreateOrderRequest):
283
284
  return await PlaceOrder(...)
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "vega-framework"
3
- version = "0.1.34"
3
+ version = "0.2.0"
4
4
  description = "Enterprise-ready Python framework that enforces Clean Architecture for building maintainable and scalable applications."
5
5
  authors = ["Roberto Ferro"]
6
6
  license = "MIT"
@@ -43,7 +43,7 @@ click = "^8.0"
43
43
  jinja2 = "^3.1"
44
44
  toml = "^0.10"
45
45
  uvicorn = "^0.27"
46
- fastapi = "^0.109"
46
+ starlette = "^0.37"
47
47
 
48
48
  [tool.poetry.group.dev.dependencies]
49
49
  pytest = "^7.0"
@@ -53,6 +53,7 @@ black = "^23.0"
53
53
  isort = "^5.0"
54
54
  mypy = "^1.0"
55
55
  ruff = "^0.1"
56
+ httpx = "^0.28.1"
56
57
 
57
58
  [tool.poetry.scripts]
58
59
  vega = "vega.cli.main:cli"
@@ -81,6 +82,31 @@ testpaths = ["tests"]
81
82
  python_files = ["test_*.py"]
82
83
  python_classes = ["Test*"]
83
84
  python_functions = ["test_*"]
85
+ # Test markers
86
+ markers = [
87
+ "unit: Unit tests for individual components",
88
+ "functional: Functional tests for features and workflows",
89
+ "integration: Integration tests for component interactions",
90
+ "slow: Tests that take significant time to run",
91
+ "web: Web framework related tests",
92
+ "di: Dependency injection related tests",
93
+ "events: Event system related tests",
94
+ ]
95
+ # Coverage settings
96
+ addopts = [
97
+ "--strict-markers",
98
+ "--tb=short",
99
+ "--cov=vega",
100
+ "--cov-report=term-missing",
101
+ "--cov-report=html:htmlcov",
102
+ "--cov-report=xml",
103
+ ]
104
+ # Filter warnings
105
+ filterwarnings = [
106
+ "error",
107
+ "ignore::UserWarning",
108
+ "ignore::DeprecationWarning",
109
+ ]
84
110
 
85
111
  [tool.ruff]
86
112
  line-length = 100
@@ -3,7 +3,7 @@ from pathlib import Path
3
3
 
4
4
  import click
5
5
 
6
- from vega.cli.scaffolds import create_fastapi_scaffold, create_sqlalchemy_scaffold
6
+ from vega.cli.scaffolds import create_vega_web_scaffold, create_sqlalchemy_scaffold
7
7
 
8
8
 
9
9
  @click.command()
@@ -13,7 +13,7 @@ def add(feature: str, path: str):
13
13
  """Add features to an existing Vega project
14
14
 
15
15
  Features:
16
- web - Add FastAPI web scaffold to the project
16
+ web - Add Vega Web scaffold to the project
17
17
  sqlalchemy - Add SQLAlchemy database support (alias: db)
18
18
  db - Alias for sqlalchemy
19
19
 
@@ -40,13 +40,13 @@ def add(feature: str, path: str):
40
40
 
41
41
 
42
42
  def add_web_feature(project_path: Path, project_name: str):
43
- """Add FastAPI web scaffold to existing project"""
44
- click.echo(f"\n[*] Adding FastAPI web scaffold to: {click.style(project_name, fg='green', bold=True)}\n")
43
+ """Add Vega Web scaffold to existing project"""
44
+ click.echo(f"\n[*] Adding Vega Web scaffold to: {click.style(project_name, fg='green', bold=True)}\n")
45
45
 
46
46
  # Check if presentation/web already exists
47
47
  web_dir = project_path / "presentation" / "web"
48
48
  if web_dir.exists() and (web_dir / "main.py").exists():
49
- click.echo(click.style("WARNING: FastAPI scaffold already exists!", fg='yellow'))
49
+ click.echo(click.style("WARNING: Web scaffold already exists!", fg='yellow'))
50
50
  if not click.confirm("Do you want to overwrite existing files?"):
51
51
  click.echo("Aborted.")
52
52
  return
@@ -60,13 +60,12 @@ def add_web_feature(project_path: Path, project_name: str):
60
60
  presentation_dir.mkdir(parents=True, exist_ok=True)
61
61
  click.echo(f" + Created presentation/")
62
62
 
63
- # Create FastAPI scaffold
64
- create_fastapi_scaffold(project_path, project_name, overwrite=overwrite)
63
+ # Create Vega Web scaffold
64
+ create_vega_web_scaffold(project_path, project_name, overwrite=overwrite)
65
65
 
66
- click.echo(f"\n{click.style('SUCCESS: FastAPI web scaffold added!', fg='green', bold=True)}\n")
66
+ click.echo(f"\n{click.style('SUCCESS: Vega Web scaffold added!', fg='green', bold=True)}\n")
67
67
  click.echo("Next steps:")
68
- click.echo(" 1. Add FastAPI dependencies:")
69
- click.echo(" poetry add fastapi uvicorn[standard]")
68
+ click.echo(" 1. Dependencies are already included in vega-framework")
70
69
  click.echo(" 2. Run the server:")
71
70
  click.echo(" vega web run --reload")
72
71
  click.echo(" 3. Visit http://localhost:8000/api/health/status")
@@ -5,7 +5,7 @@ from pathlib import Path
5
5
 
6
6
  import click
7
7
 
8
- from vega.cli.scaffolds import create_fastapi_scaffold
8
+ from vega.cli.scaffolds import create_vega_web_scaffold
9
9
  from vega.cli.templates.loader import render_template
10
10
  import vega
11
11
 
@@ -104,14 +104,15 @@ def init_project(project_name: str, template: str, parent_path: str):
104
104
  click.echo(f" + Created ARCHITECTURE.md")
105
105
 
106
106
  # Create main.py based on template
107
- if template == "fastapi":
108
- click.echo("\n[*] Adding FastAPI scaffold (presentation/web/)")
109
- create_fastapi_scaffold(project_path, project_name)
107
+ # Support both "web" and "fastapi" (backward compat)
108
+ if template in ["web", "fastapi"]:
109
+ click.echo("\n[*] Adding Vega Web scaffold (presentation/web/)")
110
+ create_vega_web_scaffold(project_path, project_name)
110
111
 
111
- # Create main.py for FastAPI project
112
+ # Create main.py for web project
112
113
  main_content = render_template("main.py.j2", project_name=project_name, template="fastapi")
113
114
  (project_path / "main.py").write_text(main_content)
114
- click.echo(f" + Created main.py (FastAPI entrypoint)")
115
+ click.echo(f" + Created main.py (Vega Web entrypoint)")
115
116
  else:
116
117
  # Create standard main.py
117
118
  main_content = render_template("main.py.j2", project_name=project_name, template="standard")
@@ -126,9 +127,9 @@ def init_project(project_name: str, template: str, parent_path: str):
126
127
  click.echo(f" poetry install")
127
128
  click.echo(f" cp .env.example .env")
128
129
 
129
- if template == "fastapi":
130
+ if template in ["web", "fastapi"]:
130
131
  click.echo(f"\nRun commands:")
131
- click.echo(f" vega web run # Start FastAPI server (http://localhost:8000)")
132
+ click.echo(f" vega web run # Start Vega Web server (http://localhost:8000)")
132
133
  click.echo(f" vega web run --reload # Start with auto-reload")
133
134
  click.echo(f" python main.py hello # Run CLI command")
134
135
  click.echo(f" python main.py --help # Show all commands")
@@ -34,7 +34,7 @@ def cli():
34
34
 
35
35
  @cli.command()
36
36
  @click.argument('project_name')
37
- @click.option('--template', default='basic', help='Project template (basic, fastapi, ai-rag)')
37
+ @click.option('--template', default='basic', help='Project template (basic, web, ai-rag)')
38
38
  @click.option('--path', default='.', help='Parent directory for project')
39
39
  def init(project_name, template, path):
40
40
  """
@@ -49,7 +49,7 @@ def init(project_name, template, path):
49
49
 
50
50
  Examples:
51
51
  vega init my-app
52
- vega init my-api --template=fastapi
52
+ vega init my-api --template=web
53
53
  vega init my-ai --template=ai-rag --path=./projects
54
54
  """
55
55
  init_project(project_name, template, path)
@@ -88,8 +88,8 @@ def generate(component_type, name, path, impl, request, response):
88
88
  service - Service interface (domain layer)
89
89
  interactor - Use case (business logic)
90
90
  mediator - Workflow (orchestrates use cases)
91
- router - FastAPI router (requires web module)
92
- middleware - FastAPI middleware (requires web module)
91
+ router - Vega Web router (requires web module)
92
+ middleware - Vega Web middleware (requires web module)
93
93
  webmodel - Pydantic request/response models (requires web module)
94
94
  model - SQLAlchemy model (requires sqlalchemy module)
95
95
  command - CLI command (async by default)
@@ -0,0 +1,13 @@
1
+ """Scaffolding helpers for Vega CLI."""
2
+
3
+ from .vega_web import create_vega_web_scaffold
4
+ from .sqlalchemy import create_sqlalchemy_scaffold
5
+
6
+ # Backward compatibility alias
7
+ create_fastapi_scaffold = create_vega_web_scaffold
8
+
9
+ __all__ = [
10
+ "create_vega_web_scaffold",
11
+ "create_fastapi_scaffold", # Deprecated: use create_vega_web_scaffold
12
+ "create_sqlalchemy_scaffold",
13
+ ]
@@ -0,0 +1,109 @@
1
+ """Vega Web scaffolding for new projects"""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from typing import Callable, Iterable
7
+
8
+ import click
9
+
10
+ from vega.cli.templates import (
11
+ render_vega_app,
12
+ render_vega_health_route,
13
+ render_vega_main,
14
+ render_vega_routes_init_autodiscovery,
15
+ render_vega_user_route,
16
+ render_pydantic_models_init,
17
+ render_pydantic_user_models,
18
+ render_web_package_init,
19
+ )
20
+
21
+
22
+ def create_vega_web_scaffold(
23
+ project_root: Path,
24
+ project_name: str,
25
+ *,
26
+ overwrite: bool = False,
27
+ echo: Callable[[str], None] | None = None,
28
+ ) -> list[Path]:
29
+ """
30
+ Create Vega Web scaffolding under the project presentation/web/ directory.
31
+
32
+ This creates a complete web application structure using Vega's built-in
33
+ web framework (built on Starlette).
34
+
35
+ Args:
36
+ project_root: Root directory of the project
37
+ project_name: Name of the project
38
+ overwrite: Whether to overwrite existing files
39
+ echo: Function to print messages (defaults to click.echo)
40
+
41
+ Returns:
42
+ List of created file paths
43
+ """
44
+ if echo is None:
45
+ echo = click.echo
46
+
47
+ created: list[Path] = []
48
+ web_dir = project_root / "presentation" / "web"
49
+ routes_dir = web_dir / "routes"
50
+ models_dir = web_dir / "models"
51
+
52
+ files: Iterable[tuple[Path, str]] = (
53
+ (web_dir / "__init__.py", render_web_package_init()),
54
+ (web_dir / "app.py", render_vega_app(project_name)),
55
+ (web_dir / "main.py", render_vega_main(project_name)),
56
+ (routes_dir / "__init__.py", render_vega_routes_init_autodiscovery()),
57
+ (routes_dir / "health.py", render_vega_health_route()),
58
+ (routes_dir / "users.py", render_vega_user_route()),
59
+ (models_dir / "__init__.py", render_pydantic_models_init()),
60
+ (models_dir / "user_models.py", render_pydantic_user_models()),
61
+ )
62
+
63
+ web_dir.mkdir(parents=True, exist_ok=True)
64
+ routes_dir.mkdir(parents=True, exist_ok=True)
65
+ models_dir.mkdir(parents=True, exist_ok=True)
66
+
67
+ for path, content in files:
68
+ rel_path = path.relative_to(project_root)
69
+ if path.exists() and not overwrite:
70
+ echo(
71
+ click.style(
72
+ f"WARNING: {rel_path} already exists. Skipping.",
73
+ fg="yellow",
74
+ )
75
+ )
76
+ continue
77
+
78
+ path.parent.mkdir(parents=True, exist_ok=True)
79
+ path.write_text(content, encoding="utf-8")
80
+ created.append(rel_path)
81
+ echo(f"+ Created {click.style(str(rel_path), fg='green')}")
82
+
83
+ echo("\n[TIP] Vega Web scaffold ready:")
84
+ echo(" 1. poetry install # sync dependencies (or poetry update)")
85
+ echo(" 2. poetry run vega web run --reload")
86
+ echo(" 3. Or: poetry run uvicorn presentation.web.main:app --reload")
87
+
88
+ return created
89
+
90
+
91
+ def _ensure_dependency_line(lines: list[str], name: str, spec: str) -> bool:
92
+ """Insert dependency assignment into [tool.poetry.dependencies] if missing."""
93
+ header = "[tool.poetry.dependencies]"
94
+ try:
95
+ start = next(i for i, line in enumerate(lines) if line.strip() == header)
96
+ except StopIteration:
97
+ return False
98
+
99
+ end = start + 1
100
+ while end < len(lines) and not lines[end].startswith("["):
101
+ end += 1
102
+
103
+ block = lines[start + 1:end]
104
+ if any(line.strip().startswith(f"{name} =") for line in block):
105
+ return False
106
+
107
+ insertion = f"{name} = \"{spec}\"\n"
108
+ lines.insert(end, insertion)
109
+ return True
@@ -7,18 +7,32 @@ from .components import (
7
7
  render_repository_interface,
8
8
  render_service_interface,
9
9
  render_web_package_init,
10
+ # New Vega Web functions
11
+ render_vega_app,
12
+ render_vega_routes_init,
13
+ render_vega_health_route,
14
+ render_vega_user_route,
15
+ render_vega_dependencies,
16
+ render_vega_main,
17
+ render_vega_project_main,
18
+ render_vega_router,
19
+ render_vega_middleware,
20
+ render_vega_routes_init_autodiscovery,
21
+ # Backward compatibility (deprecated)
10
22
  render_fastapi_app,
11
23
  render_fastapi_routes_init,
12
24
  render_fastapi_health_route,
13
25
  render_fastapi_user_route,
14
26
  render_fastapi_dependencies,
15
27
  render_fastapi_main,
16
- render_standard_main,
17
28
  render_fastapi_project_main,
18
- render_pydantic_models_init,
19
- render_pydantic_user_models,
20
29
  render_fastapi_router,
21
30
  render_fastapi_middleware,
31
+ render_fastapi_routes_init_autodiscovery,
32
+ # Common
33
+ render_standard_main,
34
+ render_pydantic_models_init,
35
+ render_pydantic_user_models,
22
36
  render_database_manager,
23
37
  render_alembic_ini,
24
38
  render_alembic_env,
@@ -27,7 +41,6 @@ from .components import (
27
41
  render_cli_command,
28
42
  render_cli_command_simple,
29
43
  render_cli_commands_init,
30
- render_fastapi_routes_init_autodiscovery,
31
44
  render_event,
32
45
  render_event_handler,
33
46
  render_events_init,
@@ -43,18 +56,32 @@ __all__ = [
43
56
  "render_infrastructure_repository",
44
57
  "render_infrastructure_service",
45
58
  "render_web_package_init",
59
+ # Vega Web
60
+ "render_vega_app",
61
+ "render_vega_routes_init",
62
+ "render_vega_health_route",
63
+ "render_vega_user_route",
64
+ "render_vega_dependencies",
65
+ "render_vega_main",
66
+ "render_vega_project_main",
67
+ "render_vega_router",
68
+ "render_vega_middleware",
69
+ "render_vega_routes_init_autodiscovery",
70
+ # Backward compat (deprecated)
46
71
  "render_fastapi_app",
47
72
  "render_fastapi_routes_init",
48
73
  "render_fastapi_health_route",
49
74
  "render_fastapi_user_route",
50
75
  "render_fastapi_dependencies",
51
76
  "render_fastapi_main",
52
- "render_standard_main",
53
77
  "render_fastapi_project_main",
54
- "render_pydantic_models_init",
55
- "render_pydantic_user_models",
56
78
  "render_fastapi_router",
57
79
  "render_fastapi_middleware",
80
+ "render_fastapi_routes_init_autodiscovery",
81
+ # Common
82
+ "render_standard_main",
83
+ "render_pydantic_models_init",
84
+ "render_pydantic_user_models",
58
85
  "render_database_manager",
59
86
  "render_alembic_ini",
60
87
  "render_alembic_env",
@@ -63,7 +90,6 @@ __all__ = [
63
90
  "render_cli_command",
64
91
  "render_cli_command_simple",
65
92
  "render_cli_commands_init",
66
- "render_fastapi_routes_init_autodiscovery",
67
93
  "render_event",
68
94
  "render_event_handler",
69
95
  "render_events_init",
@@ -84,27 +84,27 @@ def render_web_package_init() -> str:
84
84
  return render_template("__init__.py.j2", subfolder="web")
85
85
 
86
86
 
87
- def render_fastapi_app(project_name: str) -> str:
87
+ def render_vega_app(project_name: str) -> str:
88
88
  """Return the template for web/app.py"""
89
89
  return render_template("app.py.j2", subfolder="web", project_name=project_name)
90
90
 
91
91
 
92
- def render_fastapi_routes_init() -> str:
92
+ def render_vega_routes_init() -> str:
93
93
  """Return the template for web/routes/__init__.py"""
94
94
  return render_template("routes_init.py.j2", subfolder="web")
95
95
 
96
96
 
97
- def render_fastapi_health_route() -> str:
97
+ def render_vega_health_route() -> str:
98
98
  """Return the template for web/routes/health.py"""
99
99
  return render_template("health_route.py.j2", subfolder="web")
100
100
 
101
101
 
102
- def render_fastapi_dependencies() -> str:
102
+ def render_vega_dependencies() -> str:
103
103
  """Return the template for web/dependencies.py"""
104
104
  return render_template("dependencies.py.j2", subfolder="web")
105
105
 
106
106
 
107
- def render_fastapi_main(project_name: str) -> str:
107
+ def render_vega_main(project_name: str) -> str:
108
108
  """Return the template for presentation/web/main.py"""
109
109
  return render_template("main.py.j2", subfolder="web", project_name=project_name)
110
110
 
@@ -116,8 +116,8 @@ def render_standard_main(project_name: str) -> str:
116
116
  )
117
117
 
118
118
 
119
- def render_fastapi_project_main(project_name: str) -> str:
120
- """Return the template for main.py (FastAPI project with Web and CLI)"""
119
+ def render_vega_project_main(project_name: str) -> str:
120
+ """Return the template for main.py (Vega Web project with Web and CLI)"""
121
121
  return render_template(
122
122
  "main_fastapi.py.j2", subfolder="project", project_name=project_name
123
123
  )
@@ -133,13 +133,13 @@ def render_pydantic_user_models() -> str:
133
133
  return render_template("user_models.py.j2", subfolder="web")
134
134
 
135
135
 
136
- def render_fastapi_user_route() -> str:
136
+ def render_vega_user_route() -> str:
137
137
  """Return the template for web/routes/users.py"""
138
138
  return render_template("users_route.py.j2", subfolder="web")
139
139
 
140
140
 
141
- def render_fastapi_router(resource_name: str, resource_file: str, project_name: str) -> str:
142
- """Return the template for a FastAPI router"""
141
+ def render_vega_router(resource_name: str, resource_file: str, project_name: str) -> str:
142
+ """Return the template for a Vega Web router"""
143
143
  return render_template(
144
144
  "router.py.j2",
145
145
  subfolder="web",
@@ -149,8 +149,8 @@ def render_fastapi_router(resource_name: str, resource_file: str, project_name:
149
149
  )
150
150
 
151
151
 
152
- def render_fastapi_middleware(class_name: str, file_name: str) -> str:
153
- """Return the template for a FastAPI middleware"""
152
+ def render_vega_middleware(class_name: str, file_name: str) -> str:
153
+ """Return the template for a Vega Web middleware"""
154
154
  return render_template(
155
155
  "middleware.py.j2",
156
156
  subfolder="web",
@@ -159,6 +159,18 @@ def render_fastapi_middleware(class_name: str, file_name: str) -> str:
159
159
  )
160
160
 
161
161
 
162
+ # Backward compatibility aliases (deprecated)
163
+ render_fastapi_app = render_vega_app
164
+ render_fastapi_routes_init = render_vega_routes_init
165
+ render_fastapi_health_route = render_vega_health_route
166
+ render_fastapi_dependencies = render_vega_dependencies
167
+ render_fastapi_main = render_vega_main
168
+ render_fastapi_project_main = render_vega_project_main
169
+ render_fastapi_user_route = render_vega_user_route
170
+ render_fastapi_router = render_vega_router
171
+ render_fastapi_middleware = render_vega_middleware
172
+
173
+
162
174
  def render_database_manager() -> str:
163
175
  """Return the template for database_manager.py"""
164
176
  return render_template("database_manager.py.j2", subfolder="sqlalchemy")
@@ -244,11 +256,15 @@ def render_cli_commands_init() -> str:
244
256
  return render_template("commands_init.py.j2", subfolder="cli")
245
257
 
246
258
 
247
- def render_fastapi_routes_init_autodiscovery() -> str:
259
+ def render_vega_routes_init_autodiscovery() -> str:
248
260
  """Return the template for web/routes/__init__.py with auto-discovery"""
249
261
  return render_template("routes_init_autodiscovery.py.j2", subfolder="web")
250
262
 
251
263
 
264
+ # Backward compatibility alias
265
+ render_fastapi_routes_init_autodiscovery = render_vega_routes_init_autodiscovery
266
+
267
+
252
268
  def render_event(class_name: str, fields: list[dict]) -> str:
253
269
  """Return the template for a domain event"""
254
270
  return render_template(
@@ -0,0 +1,15 @@
1
+ """Vega Web application factory for {{ project_name }}"""
2
+ from vega.web import VegaApp
3
+
4
+ from .routes import get_api_router
5
+
6
+
7
+ APP_TITLE = "{{ project_name.replace('-', ' ').replace('_', ' ').title() }}"
8
+ APP_VERSION = "0.1.0"
9
+
10
+
11
+ def create_app() -> VegaApp:
12
+ """Create and configure Vega Web application"""
13
+ app = VegaApp(title=APP_TITLE, version=APP_VERSION)
14
+ app.include_router(get_api_router())
15
+ return app