vflask 0.1.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.
- vflask-0.1.0/PKG-INFO +401 -0
- vflask-0.1.0/README.md +390 -0
- vflask-0.1.0/pyproject.toml +31 -0
- vflask-0.1.0/setup.cfg +4 -0
- vflask-0.1.0/tests/test_cli.py +34 -0
- vflask-0.1.0/vflask/__init__.py +5 -0
- vflask-0.1.0/vflask/cli/__init__.py +5 -0
- vflask-0.1.0/vflask/cli/main.py +55 -0
- vflask-0.1.0/vflask/cli/watch.py +15 -0
- vflask-0.1.0/vflask/core/__init__.py +7 -0
- vflask-0.1.0/vflask/core/docgen.py +49 -0
- vflask-0.1.0/vflask/core/scaffolder.py +203 -0
- vflask-0.1.0/vflask/core/watcher.py +68 -0
- vflask-0.1.0/vflask/templates/module/__init__.py.j2 +1 -0
- vflask-0.1.0/vflask/templates/module/docs.md.j2 +43 -0
- vflask-0.1.0/vflask/templates/module/handlers.py.j2 +73 -0
- vflask-0.1.0/vflask/templates/module/models.py.j2 +32 -0
- vflask-0.1.0/vflask/templates/module/routes.py.j2 +58 -0
- vflask-0.1.0/vflask/templates/module/services.py.j2 +100 -0
- vflask-0.1.0/vflask/templates/module/test_module.py.j2 +0 -0
- vflask-0.1.0/vflask/templates/project/README.md.j2 +47 -0
- vflask-0.1.0/vflask/templates/project/app/cli.py.j2 +57 -0
- vflask-0.1.0/vflask/templates/project/app/templates/base.html.j2 +42 -0
- vflask-0.1.0/vflask/templates/project/app/templates/logs.html.j2 +23 -0
- vflask-0.1.0/vflask/templates/project/app/watcher.py.j2 +60 -0
- vflask-0.1.0/vflask/templates/project/migrations/env.py.j2 +49 -0
- vflask-0.1.0/vflask/templates/project/scripts/build.sh.j2 +26 -0
- vflask-0.1.0/vflask/templates/project/scripts/dev.sh.j2 +25 -0
- vflask-0.1.0/vflask/templates/project/scripts/help.sh.j2 +11 -0
- vflask-0.1.0/vflask/templates/project/scripts/push.sh.j2 +16 -0
- vflask-0.1.0/vflask/templates/project/scripts/setup.sh.j2 +37 -0
- vflask-0.1.0/vflask/templates/project/scripts/start.sh.j2 +32 -0
- vflask-0.1.0/vflask/templates/project/tests/conftest.py.j2 +53 -0
- vflask-0.1.0/vflask/templates/project/tests/helpers.py.j2 +18 -0
- vflask-0.1.0/vflask.egg-info/PKG-INFO +401 -0
- vflask-0.1.0/vflask.egg-info/SOURCES.txt +38 -0
- vflask-0.1.0/vflask.egg-info/dependency_links.txt +1 -0
- vflask-0.1.0/vflask.egg-info/entry_points.txt +2 -0
- vflask-0.1.0/vflask.egg-info/requires.txt +4 -0
- vflask-0.1.0/vflask.egg-info/top_level.txt +1 -0
vflask-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,401 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: vflask
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Modern typed Flask project scaffolder with blueprints, RBAC, and local module generation.
|
|
5
|
+
Requires-Python: >=3.11
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: click>=8.1.7
|
|
8
|
+
Requires-Dist: jinja2>=3.1.4
|
|
9
|
+
Requires-Dist: watchdog>=4.0.1
|
|
10
|
+
Requires-Dist: rich>=13.0.0
|
|
11
|
+
|
|
12
|
+
# vflask
|
|
13
|
+
|
|
14
|
+
vflask is a typed Flask project scaffolder and module generator designed to feel like a lightweight Django-style workflow without requiring a full ORM abstraction layer or a rigid app structure. It creates runnable Flask applications with PostgreSQL defaults, Redis support, JWT auth, role-based access control, and generated module scaffolds for CRUD-style features.
|
|
15
|
+
|
|
16
|
+
This repository includes both:
|
|
17
|
+
|
|
18
|
+
- the reusable Python scaffolding library itself
|
|
19
|
+
- the CLI used to generate full starter projects and modules
|
|
20
|
+
|
|
21
|
+
The most important thing to understand is that vflask is not only a command-line generator. It is also a Python library with explicit scaffolding primitives you can call directly.
|
|
22
|
+
|
|
23
|
+
## 1. Installation
|
|
24
|
+
|
|
25
|
+
From a virtual environment:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
python3 -m venv .venv
|
|
29
|
+
source .venv/bin/activate
|
|
30
|
+
python -m pip install --upgrade pip
|
|
31
|
+
python -m pip install -e .
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
After installation, the CLI is available as:
|
|
35
|
+
|
|
36
|
+
```bash
|
|
37
|
+
vflask --help
|
|
38
|
+
```
|
|
39
|
+
|
|
40
|
+
## 2. CLI usage
|
|
41
|
+
|
|
42
|
+
### Create a project
|
|
43
|
+
|
|
44
|
+
```bash
|
|
45
|
+
vflask new myapp
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
Optional destination:
|
|
49
|
+
|
|
50
|
+
```bash
|
|
51
|
+
vflask new myapp --path /path/to/workspace
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
This creates a new project directory with a Flask app factory, config, extensions, base utilities, default RBAC models, Docker Compose setup, and scripts.
|
|
55
|
+
|
|
56
|
+
### Create a module inside an existing project
|
|
57
|
+
|
|
58
|
+
```bash
|
|
59
|
+
cd myapp
|
|
60
|
+
vflask module create sales \
|
|
61
|
+
-f name:string:required \
|
|
62
|
+
-f amount:float \
|
|
63
|
+
-f status:string:index \
|
|
64
|
+
-r admin \
|
|
65
|
+
-r editor
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
The field format is:
|
|
69
|
+
|
|
70
|
+
```text
|
|
71
|
+
name:type[:flag]
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Examples:
|
|
75
|
+
|
|
76
|
+
- `name:string`
|
|
77
|
+
- `amount:float`
|
|
78
|
+
- `status:string:index`
|
|
79
|
+
- `is_active:boolean:required`
|
|
80
|
+
- `email:string:unique`
|
|
81
|
+
- `created_at:datetime`
|
|
82
|
+
|
|
83
|
+
Flags supported by the field parser:
|
|
84
|
+
|
|
85
|
+
- `required` / `notnull` / `nonnullable`
|
|
86
|
+
- `unique`
|
|
87
|
+
- `index`
|
|
88
|
+
- `default=value`
|
|
89
|
+
- `nullable`
|
|
90
|
+
|
|
91
|
+
### Watch generated module files
|
|
92
|
+
|
|
93
|
+
```bash
|
|
94
|
+
vflask watch --project-root .
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
The watcher observes module changes and regenerates module docs automatically when a module's handlers change.
|
|
98
|
+
|
|
99
|
+
## 3. Python library usage
|
|
100
|
+
|
|
101
|
+
The library layer is the core of vflask. You can use it directly without invoking the terminal.
|
|
102
|
+
|
|
103
|
+
```python
|
|
104
|
+
from pathlib import Path
|
|
105
|
+
|
|
106
|
+
from vflask.core.scaffolder import (
|
|
107
|
+
FieldSpec,
|
|
108
|
+
ModuleScaffolder,
|
|
109
|
+
ProjectScaffolder,
|
|
110
|
+
parse_field_spec,
|
|
111
|
+
)
|
|
112
|
+
|
|
113
|
+
# Create a project programmatically
|
|
114
|
+
ProjectScaffolder.render_project("demoapp", Path("."))
|
|
115
|
+
|
|
116
|
+
# Parse a field definition
|
|
117
|
+
field = parse_field_spec("name:string:required")
|
|
118
|
+
print(field)
|
|
119
|
+
# {'name': 'name', 'type': 'string', 'nullable': False, 'unique': False, 'index': False, 'default': None}
|
|
120
|
+
|
|
121
|
+
# Create a module inside that project
|
|
122
|
+
ModuleScaffolder.create_module(
|
|
123
|
+
"/path/to/demoapp",
|
|
124
|
+
"sales",
|
|
125
|
+
[
|
|
126
|
+
parse_field_spec("name:string:required"),
|
|
127
|
+
parse_field_spec("amount:float"),
|
|
128
|
+
parse_field_spec("status:string:index"),
|
|
129
|
+
],
|
|
130
|
+
["admin", "editor"],
|
|
131
|
+
)
|
|
132
|
+
```
|
|
133
|
+
|
|
134
|
+
### FieldSpec and datatype mapping
|
|
135
|
+
|
|
136
|
+
The library includes a `FieldSpec` dataclass and SQLAlchemy type mapping. This is how generated models decide the underlying database column type.
|
|
137
|
+
|
|
138
|
+
Examples:
|
|
139
|
+
|
|
140
|
+
```python
|
|
141
|
+
from vflask.core.scaffolder import FieldSpec
|
|
142
|
+
|
|
143
|
+
field = FieldSpec(name="price", type="decimal")
|
|
144
|
+
print(field.sqlalchemy_type)
|
|
145
|
+
# db.Numeric(10, 2)
|
|
146
|
+
```
|
|
147
|
+
|
|
148
|
+
Supported type mappings include:
|
|
149
|
+
|
|
150
|
+
- `string` → `db.String(255)`
|
|
151
|
+
- `text` → `db.Text`
|
|
152
|
+
- `integer` / `int` → `db.Integer`
|
|
153
|
+
- `float` → `db.Float`
|
|
154
|
+
- `decimal` → `db.Numeric(10, 2)`
|
|
155
|
+
- `boolean` / `bool` → `db.Boolean`
|
|
156
|
+
- `date` → `db.Date`
|
|
157
|
+
- `datetime` → `db.DateTime`
|
|
158
|
+
- `json` → `db.JSON`
|
|
159
|
+
- `uuid` → `db.String(36)`
|
|
160
|
+
|
|
161
|
+
## 4. Mechanics of the scaffolder
|
|
162
|
+
|
|
163
|
+
### Project scaffolding flow
|
|
164
|
+
|
|
165
|
+
`ProjectScaffolder.render_project()` does the following:
|
|
166
|
+
|
|
167
|
+
1. validates the project name
|
|
168
|
+
2. creates the project directory
|
|
169
|
+
3. loads the Jinja2 templates from `vflask/templates`
|
|
170
|
+
4. renders each template into the generated app
|
|
171
|
+
5. writes core files such as:
|
|
172
|
+
- `app/__init__.py`
|
|
173
|
+
- `app/config.py`
|
|
174
|
+
- `app/extensions.py`
|
|
175
|
+
- `app/base.py`
|
|
176
|
+
- `app/shared/models.py`
|
|
177
|
+
- `app/modules/__init__.py`
|
|
178
|
+
- `requirements.txt`
|
|
179
|
+
- `docker-compose.yml`
|
|
180
|
+
- `.env.example`
|
|
181
|
+
6. marks generated shell scripts executable
|
|
182
|
+
|
|
183
|
+
The project is generated from template files stored in:
|
|
184
|
+
|
|
185
|
+
- `vflask/templates/project/...`
|
|
186
|
+
- `vflask/templates/module/...`
|
|
187
|
+
|
|
188
|
+
This keeps the generated output deterministic and easy to extend.
|
|
189
|
+
|
|
190
|
+
### Module generation flow
|
|
191
|
+
|
|
192
|
+
`ModuleScaffolder.create_module()` does the following:
|
|
193
|
+
|
|
194
|
+
1. normalizes the module name to a safe Python identifier
|
|
195
|
+
2. creates the module folder under `app/modules`
|
|
196
|
+
3. builds a module metadata context with:
|
|
197
|
+
- class names
|
|
198
|
+
- table names
|
|
199
|
+
- URL prefix
|
|
200
|
+
- field definitions
|
|
201
|
+
- roles
|
|
202
|
+
4. renders template files for:
|
|
203
|
+
- `__init__.py`
|
|
204
|
+
- `models.py`
|
|
205
|
+
- `service.py`
|
|
206
|
+
- `handlers.py`
|
|
207
|
+
- `routes.py`
|
|
208
|
+
- `docs.md`
|
|
209
|
+
- `test_module.py`
|
|
210
|
+
|
|
211
|
+
### Why the system is structured this way
|
|
212
|
+
|
|
213
|
+
The design intentionally separates:
|
|
214
|
+
|
|
215
|
+
- project generation
|
|
216
|
+
- module generation
|
|
217
|
+
- file watching
|
|
218
|
+
- documentation generation
|
|
219
|
+
|
|
220
|
+
This makes it easy to add new template conventions or extend the generated project structure without rewriting the whole tool.
|
|
221
|
+
|
|
222
|
+
## 5. Generated project behavior and conventions
|
|
223
|
+
|
|
224
|
+
The generated project is intentionally opinionated and production-minded.
|
|
225
|
+
|
|
226
|
+
### App factory pattern
|
|
227
|
+
|
|
228
|
+
Generated apps use a Flask app factory:
|
|
229
|
+
|
|
230
|
+
```python
|
|
231
|
+
from app import create_app
|
|
232
|
+
app = create_app()
|
|
233
|
+
```
|
|
234
|
+
|
|
235
|
+
This is great for tests, multiple configs, and environment-specific startup behavior.
|
|
236
|
+
|
|
237
|
+
### PostgreSQL by default
|
|
238
|
+
|
|
239
|
+
The generated `requirements.txt` includes:
|
|
240
|
+
|
|
241
|
+
```text
|
|
242
|
+
Flask==3.1.0
|
|
243
|
+
Flask-SQLAlchemy==3.1.1
|
|
244
|
+
Flask-Migrate==4.0.7
|
|
245
|
+
Flask-JWT-Extended==4.7.1
|
|
246
|
+
Flask-Cors==5.0.0
|
|
247
|
+
psycopg[binary]==3.3.6
|
|
248
|
+
```
|
|
249
|
+
|
|
250
|
+
The default database URL uses PostgreSQL:
|
|
251
|
+
|
|
252
|
+
```env
|
|
253
|
+
DATABASE_URL=postgresql+psycopg://app:app@localhost:5432/app
|
|
254
|
+
```
|
|
255
|
+
|
|
256
|
+
The generated `docker-compose.yml` includes:
|
|
257
|
+
|
|
258
|
+
- Postgres service on port `5432`
|
|
259
|
+
- Redis service on port `6379`
|
|
260
|
+
|
|
261
|
+
### Redis and environment config
|
|
262
|
+
|
|
263
|
+
The generated project ships with `.env.example` containing variables like:
|
|
264
|
+
|
|
265
|
+
```env
|
|
266
|
+
FLASK_APP=app:create_app
|
|
267
|
+
FLASK_DEBUG=1
|
|
268
|
+
SECRET_KEY=changeme
|
|
269
|
+
DATABASE_URL=postgresql+psycopg://app:app@localhost:5432/app
|
|
270
|
+
JWT_SECRET_KEY=super-secret
|
|
271
|
+
REDIS_URL=redis://localhost:6379/0
|
|
272
|
+
PORT=5000
|
|
273
|
+
```
|
|
274
|
+
|
|
275
|
+
These values are intended for local development and container-based infrastructure.
|
|
276
|
+
|
|
277
|
+
### JWT + RBAC defaults
|
|
278
|
+
|
|
279
|
+
The generated app includes:
|
|
280
|
+
|
|
281
|
+
- `JWTManager`
|
|
282
|
+
- `Role` model
|
|
283
|
+
- `User` model
|
|
284
|
+
- `user_roles` association table
|
|
285
|
+
- `RBACService` helpers
|
|
286
|
+
|
|
287
|
+
This gives generated projects a base security layer with role assignment and check utilities.
|
|
288
|
+
|
|
289
|
+
### Shared utilities
|
|
290
|
+
|
|
291
|
+
The generated project creates shared convenience code:
|
|
292
|
+
|
|
293
|
+
- `app/base.py` for API helpers and decorators
|
|
294
|
+
- `app/shared/models.py` for role and user primitives
|
|
295
|
+
- `app/shared/mixins.py` for timestamp and soft-delete behavior
|
|
296
|
+
|
|
297
|
+
The decorators support patterns such as:
|
|
298
|
+
|
|
299
|
+
```python
|
|
300
|
+
@auth_required
|
|
301
|
+
def profile():
|
|
302
|
+
...
|
|
303
|
+
|
|
304
|
+
@role_required("admin")
|
|
305
|
+
def admin_only():
|
|
306
|
+
...
|
|
307
|
+
```
|
|
308
|
+
|
|
309
|
+
### Module system
|
|
310
|
+
|
|
311
|
+
Every generated module includes:
|
|
312
|
+
|
|
313
|
+
- `models.py`
|
|
314
|
+
- `service.py`
|
|
315
|
+
- `handlers.py`
|
|
316
|
+
- `routes.py`
|
|
317
|
+
- `docs.md`
|
|
318
|
+
- `test_module.py`
|
|
319
|
+
|
|
320
|
+
The `app/modules/__init__.py` loader discovers subfolders and registers route modules automatically.
|
|
321
|
+
|
|
322
|
+
### Docs generation and watcher
|
|
323
|
+
|
|
324
|
+
The watcher monitors `app/modules/**/handlers.py` and regenerates module docs using `DocGenerator` when handlers change.
|
|
325
|
+
|
|
326
|
+
This supports a low-friction workflow in which endpoints and business logic can be changed quickly while documentation stays in sync.
|
|
327
|
+
|
|
328
|
+
## 6. Local workflow for the repo itself
|
|
329
|
+
|
|
330
|
+
This repository also includes root-level helper scripts for local development and release flow:
|
|
331
|
+
|
|
332
|
+
```bash
|
|
333
|
+
./scripts/start.sh
|
|
334
|
+
./scripts/help.sh
|
|
335
|
+
./scripts/push.sh "feat: add module generator"
|
|
336
|
+
```
|
|
337
|
+
|
|
338
|
+
These are meant to keep the tool’s own working flow simple:
|
|
339
|
+
|
|
340
|
+
- `start.sh` sets up the local venv, installs the package, and shows CLI help
|
|
341
|
+
- `help.sh` prints the minimal command list
|
|
342
|
+
- `push.sh` stages, commits, and pushes changes
|
|
343
|
+
|
|
344
|
+
## 7. Publishing to PyPI
|
|
345
|
+
|
|
346
|
+
The project includes a GitHub Action for publishing to PyPI on repository pushes and manual workflow dispatch:
|
|
347
|
+
|
|
348
|
+
```yaml
|
|
349
|
+
# .github/workflows/publish.yml
|
|
350
|
+
```
|
|
351
|
+
|
|
352
|
+
The normal release flow is:
|
|
353
|
+
|
|
354
|
+
```bash
|
|
355
|
+
git add .
|
|
356
|
+
git commit -m "release: v0.1.0"
|
|
357
|
+
git push origin main
|
|
358
|
+
git tag v0.1.0
|
|
359
|
+
git push origin v0.1.0
|
|
360
|
+
```
|
|
361
|
+
|
|
362
|
+
This triggers the GitHub Action, which builds the package and publishes it through PyPI Trusted Publishing.
|
|
363
|
+
|
|
364
|
+
## 8. Typical development workflow
|
|
365
|
+
|
|
366
|
+
A typical vflask workflow looks like this:
|
|
367
|
+
|
|
368
|
+
```bash
|
|
369
|
+
python3 -m venv .venv
|
|
370
|
+
source .venv/bin/activate
|
|
371
|
+
python -m pip install -e .
|
|
372
|
+
|
|
373
|
+
vflask new myapp
|
|
374
|
+
cd myapp
|
|
375
|
+
vflask module create sales -f name:string:required -f amount:float -f status:string:index -r admin -r editor
|
|
376
|
+
vflask watch --project-root .
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
Then in the generated project:
|
|
380
|
+
|
|
381
|
+
```bash
|
|
382
|
+
./scripts/start.sh
|
|
383
|
+
```
|
|
384
|
+
|
|
385
|
+
The result is a generated Flask app that already includes a practical foundation for:
|
|
386
|
+
|
|
387
|
+
- Postgres-backed data models
|
|
388
|
+
- JWT authentication
|
|
389
|
+
- role checks and RBAC patterns
|
|
390
|
+
- module-based organization
|
|
391
|
+
- local Docker-based database services
|
|
392
|
+
- doc generation and watch-driven iteration
|
|
393
|
+
|
|
394
|
+
## 9. Summary
|
|
395
|
+
|
|
396
|
+
vflask combines two useful layers:
|
|
397
|
+
|
|
398
|
+
- a Python scaffolding library with explicit generation hooks
|
|
399
|
+
- a CLI that turns those hooks into working Flask apps and modules
|
|
400
|
+
|
|
401
|
+
It is intended for developers who want a structured, semantically typed, Django-like starter while still staying close to the Flask ecosystem and Python code they can customize directly.
|