vega-framework 0.1.35__tar.gz → 0.2.1__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.35 → vega_framework-0.2.1}/PKG-INFO +10 -9
  2. {vega_framework-0.1.35 → vega_framework-0.2.1}/README.md +8 -7
  3. {vega_framework-0.1.35 → vega_framework-0.2.1}/pyproject.toml +28 -2
  4. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/commands/add.py +9 -10
  5. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/commands/generate.py +15 -15
  6. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/commands/init.py +9 -8
  7. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/commands/web.py +8 -7
  8. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/main.py +4 -4
  9. vega_framework-0.2.1/vega/cli/scaffolds/__init__.py +13 -0
  10. vega_framework-0.2.1/vega/cli/scaffolds/vega_web.py +109 -0
  11. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/__init__.py +34 -8
  12. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/components.py +29 -13
  13. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/ARCHITECTURE.md.j2 +13 -13
  14. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/README.md.j2 +5 -5
  15. vega_framework-0.2.1/vega/cli/templates/web/app.py.j2 +15 -0
  16. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/health_route.py.j2 +2 -2
  17. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/main.py.j2 +2 -3
  18. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/middleware.py.j2 +3 -3
  19. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/router.py.j2 +2 -2
  20. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/routes_init.py.j2 +3 -3
  21. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/routes_init_autodiscovery.py.j2 +2 -2
  22. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/users_route.py.j2 +2 -2
  23. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/discovery/routes.py +13 -13
  24. vega_framework-0.2.1/vega/web/__init__.py +100 -0
  25. vega_framework-0.2.1/vega/web/application.py +234 -0
  26. vega_framework-0.2.1/vega/web/builtin_middlewares.py +288 -0
  27. vega_framework-0.2.1/vega/web/exceptions.py +151 -0
  28. vega_framework-0.2.1/vega/web/middleware.py +185 -0
  29. vega_framework-0.2.1/vega/web/request.py +120 -0
  30. vega_framework-0.2.1/vega/web/response.py +220 -0
  31. vega_framework-0.2.1/vega/web/route_middleware.py +266 -0
  32. vega_framework-0.2.1/vega/web/router.py +350 -0
  33. vega_framework-0.2.1/vega/web/routing.py +347 -0
  34. vega_framework-0.1.35/vega/cli/scaffolds/__init__.py +0 -9
  35. vega_framework-0.1.35/vega/cli/templates/web/app.py.j2 +0 -15
  36. {vega_framework-0.1.35 → vega_framework-0.2.1}/LICENSE +0 -0
  37. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/__init__.py +0 -0
  38. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/__init__.py +0 -0
  39. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/commands/__init__.py +0 -0
  40. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/commands/migrate.py +0 -0
  41. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/commands/update.py +0 -0
  42. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/scaffolds/fastapi.py +0 -0
  43. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/scaffolds/sqlalchemy.py +0 -0
  44. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/cli/command.py.j2 +0 -0
  45. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/cli/command_simple.py.j2 +0 -0
  46. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/cli/commands_init.py.j2 +0 -0
  47. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/domain/entity.py.j2 +0 -0
  48. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/domain/event.py.j2 +0 -0
  49. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/domain/event_handler.py.j2 +0 -0
  50. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/domain/interactor.py.j2 +0 -0
  51. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/domain/mediator.py.j2 +0 -0
  52. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/domain/repository_interface.py.j2 +0 -0
  53. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/domain/service_interface.py.j2 +0 -0
  54. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/infrastructure/model.py.j2 +0 -0
  55. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/infrastructure/repository_impl.py.j2 +0 -0
  56. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/infrastructure/service_impl.py.j2 +0 -0
  57. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/loader.py +0 -0
  58. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/.env.example +0 -0
  59. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/.gitignore +0 -0
  60. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/config.py.j2 +0 -0
  61. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/events_init.py.j2 +0 -0
  62. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/main.py.j2 +0 -0
  63. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/main_fastapi.py.j2 +0 -0
  64. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/main_standard.py.j2 +0 -0
  65. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/pyproject.toml.j2 +0 -0
  66. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/project/settings.py.j2 +0 -0
  67. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/sqlalchemy/alembic.ini.j2 +0 -0
  68. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/sqlalchemy/database_manager.py.j2 +0 -0
  69. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/sqlalchemy/env.py.j2 +0 -0
  70. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/sqlalchemy/script.py.mako +0 -0
  71. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/__init__.py.j2 +0 -0
  72. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/models_init.py.j2 +0 -0
  73. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/request_model.py.j2 +0 -0
  74. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/response_model.py.j2 +0 -0
  75. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/templates/web/user_models.py.j2 +0 -0
  76. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/utils/__init__.py +0 -0
  77. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/utils/async_support.py +0 -0
  78. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/utils/messages.py +0 -0
  79. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/utils/naming.py +0 -0
  80. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/cli/utils/validators.py +0 -0
  81. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/di/__init__.py +0 -0
  82. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/di/container.py +0 -0
  83. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/di/decorators.py +0 -0
  84. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/di/errors.py +0 -0
  85. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/di/scope.py +0 -0
  86. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/discovery/__init__.py +0 -0
  87. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/discovery/commands.py +0 -0
  88. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/discovery/events.py +0 -0
  89. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/events/README.md +0 -0
  90. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/events/SYNTAX_GUIDE.md +0 -0
  91. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/events/__init__.py +0 -0
  92. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/events/bus.py +0 -0
  93. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/events/decorators.py +0 -0
  94. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/events/event.py +0 -0
  95. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/events/middleware.py +0 -0
  96. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/patterns/__init__.py +0 -0
  97. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/patterns/interactor.py +0 -0
  98. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/patterns/mediator.py +0 -0
  99. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/patterns/repository.py +0 -0
  100. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/patterns/service.py +0 -0
  101. {vega_framework-0.1.35 → vega_framework-0.2.1}/vega/settings/__init__.py +0 -0
  102. {vega_framework-0.1.35 → vega_framework-0.2.1}/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.35
3
+ Version: 0.2.1
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.35"
3
+ version = "0.2.1"
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")
@@ -394,13 +394,13 @@ def _register_router_in_init(project_root: Path, resource_file: str, resource_na
394
394
 
395
395
 
396
396
  def _generate_router(project_root: Path, project_name: str, name: str) -> None:
397
- """Generate a FastAPI router for a resource"""
397
+ """Generate a Vega Web router for a resource"""
398
398
 
399
399
  # Check if web folder exists
400
400
  web_path = project_root / "presentation" / "web"
401
401
  if not web_path.exists():
402
402
  click.echo(click.style("ERROR: Web module not found", fg='red'))
403
- click.echo(" Router generation requires FastAPI web module")
403
+ click.echo(" Router generation requires Vega Web module")
404
404
  click.echo(" Install it with: vega add web")
405
405
  return
406
406
 
@@ -440,13 +440,13 @@ def _generate_router(project_root: Path, project_name: str, name: str) -> None:
440
440
 
441
441
 
442
442
  def _generate_web_models(project_root: Path, project_name: str, name: str, is_request: bool, is_response: bool) -> None:
443
- """Generate Pydantic request or response model for FastAPI"""
443
+ """Generate Pydantic request or response model for Vega Web"""
444
444
 
445
445
  # Check if web folder exists
446
446
  web_path = project_root / "presentation" / "web"
447
447
  if not web_path.exists():
448
448
  click.echo(click.style("ERROR: Web module not found", fg='red'))
449
- click.echo(" Model generation requires FastAPI web module")
449
+ click.echo(" Model generation requires Vega Web module")
450
450
  click.echo(" Install it with: vega add web")
451
451
  return
452
452
 
@@ -531,13 +531,13 @@ def _generate_web_models(project_root: Path, project_name: str, name: str, is_re
531
531
 
532
532
 
533
533
  def _generate_middleware(project_root: Path, project_name: str, class_name: str, file_name: str) -> None:
534
- """Generate a FastAPI middleware"""
534
+ """Generate a Vega Web middleware"""
535
535
 
536
536
  # Check if web folder exists
537
537
  web_path = project_root / "presentation" / "web"
538
538
  if not web_path.exists():
539
539
  click.echo(click.style("ERROR: Web module not found", fg='red'))
540
- click.echo(" Middleware generation requires FastAPI web module")
540
+ click.echo(" Middleware generation requires Vega Web module")
541
541
  click.echo(" Install it with: vega add web")
542
542
  return
543
543
 
@@ -554,7 +554,7 @@ def _generate_middleware(project_root: Path, project_name: str, class_name: str,
554
554
  # Check if __init__.py exists
555
555
  init_file = middleware_path / "__init__.py"
556
556
  if not init_file.exists():
557
- init_file.write_text('"""FastAPI Middlewares"""\n')
557
+ init_file.write_text('"""Vega Web Middlewares"""\n')
558
558
  click.echo(f"+ Created {click.style(str(init_file.relative_to(project_root)), fg='green')}")
559
559
 
560
560
  # Generate middleware file
@@ -589,8 +589,8 @@ def _register_middleware_in_app(project_root: Path, class_name: str, file_name:
589
589
  click.echo(click.style(f'''
590
590
  from .middleware.{file_name} import {class_name}Middleware
591
591
 
592
- def create_app() -> FastAPI:
593
- app = FastAPI(...)
592
+ def create_app() -> VegaApp:
593
+ app = VegaApp(...)
594
594
  app.add_middleware({class_name}Middleware)
595
595
  app.include_router(get_api_router())
596
596
  return app
@@ -619,9 +619,9 @@ def create_app() -> FastAPI:
619
619
  break
620
620
 
621
621
  if not import_added:
622
- # Fallback: add after FastAPI import
622
+ # Fallback: add after VegaApp import
623
623
  for i, line in enumerate(lines):
624
- if 'from fastapi import' in line:
624
+ if 'from vega.web import' in line:
625
625
  lines.insert(i + 1, middleware_import)
626
626
  lines.insert(i + 2, '')
627
627
  break
@@ -629,8 +629,8 @@ def create_app() -> FastAPI:
629
629
  # Find create_app function and add middleware registration
630
630
  middleware_added = False
631
631
  for i, line in enumerate(lines):
632
- if 'app = FastAPI(' in line:
633
- # Find the end of FastAPI initialization
632
+ if 'app = VegaApp(' in line:
633
+ # Find the end of VegaApp initialization
634
634
  j = i + 1
635
635
  while j < len(lines) and not lines[j].strip().startswith('app.include_router'):
636
636
  j += 1
@@ -649,8 +649,8 @@ def create_app() -> FastAPI:
649
649
  click.echo(click.style(f'''
650
650
  from .middleware.{file_name} import {class_name}Middleware
651
651
 
652
- def create_app() -> FastAPI:
653
- app = FastAPI(...)
652
+ def create_app() -> VegaApp:
653
+ app = VegaApp(...)
654
654
  app.add_middleware({class_name}Middleware)
655
655
  app.include_router(get_api_router())
656
656
  return app
@@ -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")
@@ -1,4 +1,4 @@
1
- """Web command - Manage FastAPI web server"""
1
+ """Web command - Manage Vega Web server"""
2
2
  import sys
3
3
  from pathlib import Path
4
4
 
@@ -7,7 +7,7 @@ import click
7
7
 
8
8
  @click.group()
9
9
  def web():
10
- """Manage FastAPI web server
10
+ """Manage Vega Web server
11
11
 
12
12
  Commands to manage the web server for your Vega project.
13
13
  The web module must be added to the project first using 'vega add web'.
@@ -21,7 +21,7 @@ def web():
21
21
  @click.option('--reload', is_flag=True, help='Enable auto-reload')
22
22
  @click.option('--path', default='.', help='Path to Vega project (default: current directory)')
23
23
  def run(host: str, port: int, reload: bool, path: str):
24
- """Start the FastAPI web server
24
+ """Start the Vega Web server
25
25
 
26
26
  Examples:
27
27
  vega web run
@@ -42,7 +42,7 @@ def run(host: str, port: int, reload: bool, path: str):
42
42
  web_main = project_path / "presentation" / "web" / "main.py"
43
43
  if not web_main.exists():
44
44
  click.echo(click.style("ERROR: Web module not found", fg='red'))
45
- click.echo("\nThe FastAPI web module is not available in this project.")
45
+ click.echo("\nThe Vega Web module is not available in this project.")
46
46
  click.echo("Add it using:")
47
47
  click.echo(click.style(" vega add web", fg='cyan', bold=True))
48
48
  sys.exit(1)
@@ -56,8 +56,9 @@ def run(host: str, port: int, reload: bool, path: str):
56
56
  import uvicorn
57
57
  except ImportError:
58
58
  click.echo(click.style("ERROR: uvicorn not installed", fg='red'))
59
- click.echo("\nInstall FastAPI dependencies:")
60
- click.echo(click.style(" poetry add fastapi uvicorn[standard]", fg='cyan', bold=True))
59
+ click.echo("\nUvicorn is required but not installed.")
60
+ click.echo("It should be included with vega-framework, but you can also install it with:")
61
+ click.echo(click.style(" poetry add uvicorn[standard]", fg='cyan', bold=True))
61
62
  sys.exit(1)
62
63
 
63
64
  # Initialize DI container first
@@ -73,7 +74,7 @@ def run(host: str, port: int, reload: bool, path: str):
73
74
  try:
74
75
  from presentation.web.main import app
75
76
  except ImportError as e:
76
- click.echo(click.style("ERROR: Failed to import FastAPI app", fg='red'))
77
+ click.echo(click.style("ERROR: Failed to import Vega Web app", fg='red'))
77
78
  click.echo(f"\nDetails: {e}")
78
79
  click.echo("\nMake sure:")
79
80
  click.echo(" 1. You are in the project directory or use --path")
@@ -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