flaskion 2.0.0a1__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.
- flaskion-2.0.0a1/MANIFEST.in +6 -0
- flaskion-2.0.0a1/PKG-INFO +215 -0
- flaskion-2.0.0a1/README.md +194 -0
- flaskion-2.0.0a1/docs/FLASKION_2_ARCHITECTURE.md +453 -0
- flaskion-2.0.0a1/docs/FLASKION_2_ROADMAP.md +318 -0
- flaskion-2.0.0a1/docs/MCP_ARCHITECTURE.md +346 -0
- flaskion-2.0.0a1/examples/__init__.py +1 -0
- flaskion-2.0.0a1/examples/task_list/README.md +63 -0
- flaskion-2.0.0a1/examples/task_list/__init__.py +6 -0
- flaskion-2.0.0a1/examples/task_list/application.py +52 -0
- flaskion-2.0.0a1/examples/task_list/bootstrap.py +16 -0
- flaskion-2.0.0a1/examples/task_list/cli.py +48 -0
- flaskion-2.0.0a1/examples/task_list/domain.py +18 -0
- flaskion-2.0.0a1/examples/task_list/http.py +42 -0
- flaskion-2.0.0a1/examples/task_list/mcp.py +48 -0
- flaskion-2.0.0a1/examples/task_list/mcp_server.py +9 -0
- flaskion-2.0.0a1/examples/task_list/persistence.py +62 -0
- flaskion-2.0.0a1/examples/task_list/presentation.py +5 -0
- flaskion-2.0.0a1/examples/task_list/run.py +3 -0
- flaskion-2.0.0a1/flaskion.egg-info/PKG-INFO +215 -0
- flaskion-2.0.0a1/flaskion.egg-info/SOURCES.txt +79 -0
- flaskion-2.0.0a1/flaskion.egg-info/dependency_links.txt +1 -0
- flaskion-2.0.0a1/flaskion.egg-info/entry_points.txt +2 -0
- flaskion-2.0.0a1/flaskion.egg-info/requires.txt +6 -0
- flaskion-2.0.0a1/flaskion.egg-info/top_level.txt +2 -0
- flaskion-2.0.0a1/flaskion_cli/__init__.py +0 -0
- flaskion-2.0.0a1/flaskion_cli/cli.py +451 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/api_controller_template.py.jinja +33 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/api_route_template.py.jinja +30 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/auth_controller_template.py.jinja +51 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/controller_template.py.jinja +30 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/html/auth/dashboard.html.jinja +71 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/html/auth/login.html.jinja +118 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/html/auth/register.html.jinja +124 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/model_template.py.jinja +9 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/schema_template.py.jinja +15 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/user_model_template.py.jinja +12 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/user_schema_template.py.jinja +6 -0
- flaskion-2.0.0a1/flaskion_cli/cli_templates/web_route_template.py.jinja +30 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/.env.example +7 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/.gitattributes +2 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/.gitignore +37 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/__init__.py +34 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/application.py +6 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/config.py +20 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/controllers/__init__.py +0 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/controllers/api_controller.py +4 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/controllers/hello_controller.py +6 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/extensions.py +6 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/models/__init__.py +7 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/models/example.py +16 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/models/mixin.py +13 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/routes/__init__.py +7 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/routes/api_routes.py +11 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/routes/web_routes.py +11 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/schemas/__init__.py +1 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/schemas/example_schema.py +14 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/static/css/style.css +66 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/static/images/logo.png +0 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/templates/base.html +27 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/app/templates/hello.html +10 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/requirements.txt +8 -0
- flaskion-2.0.0a1/flaskion_cli/flaskion_template/run.py +7 -0
- flaskion-2.0.0a1/pyproject.toml +74 -0
- flaskion-2.0.0a1/setup.cfg +4 -0
- flaskion-2.0.0a1/src/flaskion/__init__.py +18 -0
- flaskion-2.0.0a1/src/flaskion/application.py +49 -0
- flaskion-2.0.0a1/src/flaskion/errors.py +14 -0
- flaskion-2.0.0a1/src/flaskion/mcp/__init__.py +10 -0
- flaskion-2.0.0a1/src/flaskion/mcp/_compat.py +12 -0
- flaskion-2.0.0a1/src/flaskion/mcp/errors.py +6 -0
- flaskion-2.0.0a1/src/flaskion/mcp/server.py +91 -0
- flaskion-2.0.0a1/src/flaskion/mcp/testing.py +53 -0
- flaskion-2.0.0a1/tests/__init__.py +1 -0
- flaskion-2.0.0a1/tests/test_application.py +40 -0
- flaskion-2.0.0a1/tests/test_architecture.py +51 -0
- flaskion-2.0.0a1/tests/test_cli.py +139 -0
- flaskion-2.0.0a1/tests/test_mcp.py +80 -0
- flaskion-2.0.0a1/tests/test_task_list.py +82 -0
- flaskion-2.0.0a1/tests/test_task_list_mcp.py +72 -0
- flaskion-2.0.0a1/tests/test_task_list_mcp_remote.py +113 -0
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: flaskion
|
|
3
|
+
Version: 2.0.0a1
|
|
4
|
+
Summary: An opinionated application framework and scaffolder for Flask
|
|
5
|
+
Author-email: Graham Patrick <graham@skyaisoftware.com>
|
|
6
|
+
Project-URL: Homepage, https://github.com/GrahamMorbyDev/flaskion
|
|
7
|
+
Project-URL: Issues, https://github.com/GrahamMorbyDev/flaskion/issues
|
|
8
|
+
Classifier: Programming Language :: Python :: 3
|
|
9
|
+
Classifier: Programming Language :: Python :: 3 :: Only
|
|
10
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Requires-Python: >=3.11
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: click>=8.1
|
|
17
|
+
Requires-Dist: flask>=3.1
|
|
18
|
+
Requires-Dist: jinja2>=3.1
|
|
19
|
+
Provides-Extra: mcp
|
|
20
|
+
Requires-Dist: fastmcp<5,>=4; extra == "mcp"
|
|
21
|
+
|
|
22
|
+
# Flaskion
|
|
23
|
+
|
|
24
|
+
Flaskion is a Laravel-inspired application framework and project scaffolder for Flask. The `2.0.0a1` runtime adds a small interface-independent use-case boundary while retaining the Flask project generators from Phase 1.
|
|
25
|
+
|
|
26
|
+
Flaskion 2 is being designed as an AI-native application framework. The
|
|
27
|
+
generic Task List uses Flaskion's optional MCP API as a third adapter beside
|
|
28
|
+
HTTP and CLI; authentication and remote deployment integration remain future
|
|
29
|
+
work.
|
|
30
|
+
|
|
31
|
+
## Current features
|
|
32
|
+
|
|
33
|
+
- Flask application factory and explicit extension initialization
|
|
34
|
+
- `flaskion.Application` for registering and invoking plain Python use cases
|
|
35
|
+
- Constructor-based service and repository dependencies without a DI container
|
|
36
|
+
- Optional `flaskion.mcp` API backed by FastMCP 4
|
|
37
|
+
- Local stdio and remote Streamable HTTP serving with MCP test support
|
|
38
|
+
- Separate web and JSON API blueprints
|
|
39
|
+
- SQLite, MySQL, or PostgreSQL project configuration
|
|
40
|
+
- SQLAlchemy and Flask-Migrate
|
|
41
|
+
- Conflict-safe model, controller, schema, resource, and authentication generators
|
|
42
|
+
- Session authentication scaffold with CSRF-protected forms
|
|
43
|
+
- Cross-platform virtual-environment invocation
|
|
44
|
+
|
|
45
|
+
## Installation
|
|
46
|
+
|
|
47
|
+
```bash
|
|
48
|
+
pipx install flaskion
|
|
49
|
+
# or
|
|
50
|
+
pip install flaskion
|
|
51
|
+
# Optional MCP adapter support
|
|
52
|
+
pip install "flaskion[mcp]"
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
Flaskion requires Python 3.11 or newer. The core package and optional MCP
|
|
56
|
+
integration share the same supported Python floor.
|
|
57
|
+
|
|
58
|
+
## Create a project
|
|
59
|
+
|
|
60
|
+
```bash
|
|
61
|
+
flaskion make:new myproject --db=sqlite
|
|
62
|
+
cd myproject
|
|
63
|
+
source .venv/bin/activate
|
|
64
|
+
flask run
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
On Windows, activate the environment with `.venv\Scripts\activate`.
|
|
68
|
+
|
|
69
|
+
Use `--db=mysql` or `--db=postgres` to install and configure the matching SQLAlchemy driver. Use `--no-install` to create files without creating an environment or installing dependencies.
|
|
70
|
+
|
|
71
|
+
The default creation flow:
|
|
72
|
+
|
|
73
|
+
1. builds the project in a staging directory;
|
|
74
|
+
2. writes a random development secret and a database URL to `.env`;
|
|
75
|
+
3. initializes Git;
|
|
76
|
+
4. creates `.venv` and installs dependencies;
|
|
77
|
+
5. initializes the Alembic migration repository;
|
|
78
|
+
6. moves the complete project into its final directory.
|
|
79
|
+
|
|
80
|
+
If a setup command fails, Flaskion reports the command and removes the incomplete staging directory.
|
|
81
|
+
|
|
82
|
+
## Generated project structure
|
|
83
|
+
|
|
84
|
+
```text
|
|
85
|
+
myproject/
|
|
86
|
+
├── app/
|
|
87
|
+
│ ├── __init__.py # Application factory
|
|
88
|
+
│ ├── application.py # Interface-independent use-case registration
|
|
89
|
+
│ ├── config.py # Environment-backed configuration
|
|
90
|
+
│ ├── extensions.py # Unbound Flask extensions
|
|
91
|
+
│ ├── controllers/
|
|
92
|
+
│ ├── models/
|
|
93
|
+
│ ├── routes/
|
|
94
|
+
│ ├── schemas/
|
|
95
|
+
│ ├── static/
|
|
96
|
+
│ └── templates/
|
|
97
|
+
├── migrations/ # Created by `flask db init`
|
|
98
|
+
├── .env.example
|
|
99
|
+
├── requirements.txt
|
|
100
|
+
└── run.py
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
## Commands
|
|
104
|
+
|
|
105
|
+
| Command | Description |
|
|
106
|
+
|---|---|
|
|
107
|
+
| `flaskion make:new NAME` | Create a project; accepts `--db` and `--no-install` |
|
|
108
|
+
| `flaskion make:model NAME` | Create and explicitly register a SQLAlchemy model |
|
|
109
|
+
| `flaskion make:schema NAME` | Create a Marshmallow SQLAlchemy schema |
|
|
110
|
+
| `flaskion make:controller NAME` | Create a web controller; accepts `--api` for JSON stubs |
|
|
111
|
+
| `flaskion make:resource NAME` | Atomically create model, controller, schema, and routes; accepts `--api` |
|
|
112
|
+
| `flaskion make:auth` | Create session authentication and CSRF-protected templates |
|
|
113
|
+
|
|
114
|
+
Generators refuse to overwrite existing files. Multi-file generation is planned before writing, so a conflict does not leave a partially changed project. Names such as `CardGrader`, `card-grader`, and `card_grader` normalize to consistent Python module and class names.
|
|
115
|
+
|
|
116
|
+
Generated API controller methods return explicit `501 Not Implemented` JSON until application behavior is supplied. Flaskion does not generate pretend persistence logic.
|
|
117
|
+
|
|
118
|
+
## Database migrations
|
|
119
|
+
|
|
120
|
+
The normal project-creation flow runs `flask db init`. Create and apply revisions with:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
flask db migrate -m "Initial schema"
|
|
124
|
+
flask db upgrade
|
|
125
|
+
```
|
|
126
|
+
|
|
127
|
+
When a project is created with `--no-install`, install its dependencies and run `flask db init` yourself before creating the first revision.
|
|
128
|
+
|
|
129
|
+
## Authentication scaffold
|
|
130
|
+
|
|
131
|
+
```bash
|
|
132
|
+
flaskion make:auth
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
This creates a user model, schema, controller, and login/register/dashboard templates. Forms carry Flask-WTF CSRF tokens, login clears prior session data, passwords must contain at least 12 characters, and logout is POST-only.
|
|
136
|
+
|
|
137
|
+
This remains starter authentication, not a complete identity product. Production applications still need requirements appropriate to their threat model, such as email verification, password reset, rate limiting, secure-cookie deployment settings, and authorization policies.
|
|
138
|
+
|
|
139
|
+
## Development
|
|
140
|
+
|
|
141
|
+
Install the development dependency group with a compatible environment manager, then run:
|
|
142
|
+
|
|
143
|
+
```bash
|
|
144
|
+
python -m unittest discover -v
|
|
145
|
+
ruff check .
|
|
146
|
+
python -m build
|
|
147
|
+
```
|
|
148
|
+
|
|
149
|
+
When running directly from a source checkout with the `src/` layout, use an editable install or set `PYTHONPATH=src:.`.
|
|
150
|
+
|
|
151
|
+
## Runtime usage
|
|
152
|
+
|
|
153
|
+
Use cases do not inherit from Flaskion classes. Register a plain function, bound service method, or callable object against any message type:
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from dataclasses import dataclass
|
|
157
|
+
|
|
158
|
+
from flaskion import Application
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@dataclass(frozen=True)
|
|
162
|
+
class Greet:
|
|
163
|
+
name: str
|
|
164
|
+
|
|
165
|
+
|
|
166
|
+
application = Application()
|
|
167
|
+
application.register(Greet, lambda message: f"Hello, {message.name}")
|
|
168
|
+
|
|
169
|
+
assert application.handle(Greet("Ada")) == "Hello, Ada"
|
|
170
|
+
```
|
|
171
|
+
|
|
172
|
+
The decorator form `@application.use_case(Greet)` is available but optional. Services and repository protocols are application-owned; Flaskion does not require base classes or a universal repository abstraction.
|
|
173
|
+
|
|
174
|
+
## Task List example
|
|
175
|
+
|
|
176
|
+
The canonical example is under [`examples/task_list`](examples/task_list). It implements create, list, and complete through one `TaskService`, a repository protocol, and a SQLite adapter. HTTP, CLI, and MCP receive the same `Application` instance and invoke the same handlers.
|
|
177
|
+
|
|
178
|
+
```bash
|
|
179
|
+
PYTHONPATH=src:. flask --app examples.task_list.run run
|
|
180
|
+
PYTHONPATH=src:. python -m examples.task_list.cli create "Write documentation"
|
|
181
|
+
PYTHONPATH=src:. python -m examples.task_list.cli list
|
|
182
|
+
PYTHONPATH=src:. python -m examples.task_list.cli complete 1
|
|
183
|
+
PYTHONPATH=src:. flaskion mcp:serve --app examples.task_list.mcp_server:mcp
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
Install the MCP adapter with `pip install -e '.[mcp]'`. MCP remains optional:
|
|
187
|
+
FastMCP is imported only by
|
|
188
|
+
`flaskion.mcp`'s private compatibility boundary, never by Task List code.
|
|
189
|
+
|
|
190
|
+
For a remotely connectable development endpoint, use Streamable HTTP:
|
|
191
|
+
|
|
192
|
+
```bash
|
|
193
|
+
PYTHONPATH=src:. flaskion mcp:serve \
|
|
194
|
+
--app examples.task_list.mcp_server:mcp \
|
|
195
|
+
--transport http --host 127.0.0.1 --port 8000
|
|
196
|
+
```
|
|
197
|
+
|
|
198
|
+
The MCP endpoint is `http://127.0.0.1:8000/mcp`. Inspect it locally with:
|
|
199
|
+
|
|
200
|
+
```bash
|
|
201
|
+
npx -y @modelcontextprotocol/inspector --web http://127.0.0.1:8000/mcp
|
|
202
|
+
```
|
|
203
|
+
|
|
204
|
+
Loopback is the safe default. Binding to a public interface exposes an
|
|
205
|
+
unauthenticated MCP endpoint until Flaskion's remote authentication boundary is
|
|
206
|
+
implemented; use network controls and do not treat the development command as
|
|
207
|
+
a production deployment configuration.
|
|
208
|
+
|
|
209
|
+
The example intentionally does not include jobs, events, authentication policy, generic middleware, or a dependency-injection container.
|
|
210
|
+
|
|
211
|
+
## Architecture documents
|
|
212
|
+
|
|
213
|
+
- [Flaskion 2 architecture](docs/FLASKION_2_ARCHITECTURE.md)
|
|
214
|
+
- [Flaskion 2 roadmap](docs/FLASKION_2_ROADMAP.md)
|
|
215
|
+
- [MCP architecture](docs/MCP_ARCHITECTURE.md)
|
|
@@ -0,0 +1,194 @@
|
|
|
1
|
+
# Flaskion
|
|
2
|
+
|
|
3
|
+
Flaskion is a Laravel-inspired application framework and project scaffolder for Flask. The `2.0.0a1` runtime adds a small interface-independent use-case boundary while retaining the Flask project generators from Phase 1.
|
|
4
|
+
|
|
5
|
+
Flaskion 2 is being designed as an AI-native application framework. The
|
|
6
|
+
generic Task List uses Flaskion's optional MCP API as a third adapter beside
|
|
7
|
+
HTTP and CLI; authentication and remote deployment integration remain future
|
|
8
|
+
work.
|
|
9
|
+
|
|
10
|
+
## Current features
|
|
11
|
+
|
|
12
|
+
- Flask application factory and explicit extension initialization
|
|
13
|
+
- `flaskion.Application` for registering and invoking plain Python use cases
|
|
14
|
+
- Constructor-based service and repository dependencies without a DI container
|
|
15
|
+
- Optional `flaskion.mcp` API backed by FastMCP 4
|
|
16
|
+
- Local stdio and remote Streamable HTTP serving with MCP test support
|
|
17
|
+
- Separate web and JSON API blueprints
|
|
18
|
+
- SQLite, MySQL, or PostgreSQL project configuration
|
|
19
|
+
- SQLAlchemy and Flask-Migrate
|
|
20
|
+
- Conflict-safe model, controller, schema, resource, and authentication generators
|
|
21
|
+
- Session authentication scaffold with CSRF-protected forms
|
|
22
|
+
- Cross-platform virtual-environment invocation
|
|
23
|
+
|
|
24
|
+
## Installation
|
|
25
|
+
|
|
26
|
+
```bash
|
|
27
|
+
pipx install flaskion
|
|
28
|
+
# or
|
|
29
|
+
pip install flaskion
|
|
30
|
+
# Optional MCP adapter support
|
|
31
|
+
pip install "flaskion[mcp]"
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
Flaskion requires Python 3.11 or newer. The core package and optional MCP
|
|
35
|
+
integration share the same supported Python floor.
|
|
36
|
+
|
|
37
|
+
## Create a project
|
|
38
|
+
|
|
39
|
+
```bash
|
|
40
|
+
flaskion make:new myproject --db=sqlite
|
|
41
|
+
cd myproject
|
|
42
|
+
source .venv/bin/activate
|
|
43
|
+
flask run
|
|
44
|
+
```
|
|
45
|
+
|
|
46
|
+
On Windows, activate the environment with `.venv\Scripts\activate`.
|
|
47
|
+
|
|
48
|
+
Use `--db=mysql` or `--db=postgres` to install and configure the matching SQLAlchemy driver. Use `--no-install` to create files without creating an environment or installing dependencies.
|
|
49
|
+
|
|
50
|
+
The default creation flow:
|
|
51
|
+
|
|
52
|
+
1. builds the project in a staging directory;
|
|
53
|
+
2. writes a random development secret and a database URL to `.env`;
|
|
54
|
+
3. initializes Git;
|
|
55
|
+
4. creates `.venv` and installs dependencies;
|
|
56
|
+
5. initializes the Alembic migration repository;
|
|
57
|
+
6. moves the complete project into its final directory.
|
|
58
|
+
|
|
59
|
+
If a setup command fails, Flaskion reports the command and removes the incomplete staging directory.
|
|
60
|
+
|
|
61
|
+
## Generated project structure
|
|
62
|
+
|
|
63
|
+
```text
|
|
64
|
+
myproject/
|
|
65
|
+
├── app/
|
|
66
|
+
│ ├── __init__.py # Application factory
|
|
67
|
+
│ ├── application.py # Interface-independent use-case registration
|
|
68
|
+
│ ├── config.py # Environment-backed configuration
|
|
69
|
+
│ ├── extensions.py # Unbound Flask extensions
|
|
70
|
+
│ ├── controllers/
|
|
71
|
+
│ ├── models/
|
|
72
|
+
│ ├── routes/
|
|
73
|
+
│ ├── schemas/
|
|
74
|
+
│ ├── static/
|
|
75
|
+
│ └── templates/
|
|
76
|
+
├── migrations/ # Created by `flask db init`
|
|
77
|
+
├── .env.example
|
|
78
|
+
├── requirements.txt
|
|
79
|
+
└── run.py
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
## Commands
|
|
83
|
+
|
|
84
|
+
| Command | Description |
|
|
85
|
+
|---|---|
|
|
86
|
+
| `flaskion make:new NAME` | Create a project; accepts `--db` and `--no-install` |
|
|
87
|
+
| `flaskion make:model NAME` | Create and explicitly register a SQLAlchemy model |
|
|
88
|
+
| `flaskion make:schema NAME` | Create a Marshmallow SQLAlchemy schema |
|
|
89
|
+
| `flaskion make:controller NAME` | Create a web controller; accepts `--api` for JSON stubs |
|
|
90
|
+
| `flaskion make:resource NAME` | Atomically create model, controller, schema, and routes; accepts `--api` |
|
|
91
|
+
| `flaskion make:auth` | Create session authentication and CSRF-protected templates |
|
|
92
|
+
|
|
93
|
+
Generators refuse to overwrite existing files. Multi-file generation is planned before writing, so a conflict does not leave a partially changed project. Names such as `CardGrader`, `card-grader`, and `card_grader` normalize to consistent Python module and class names.
|
|
94
|
+
|
|
95
|
+
Generated API controller methods return explicit `501 Not Implemented` JSON until application behavior is supplied. Flaskion does not generate pretend persistence logic.
|
|
96
|
+
|
|
97
|
+
## Database migrations
|
|
98
|
+
|
|
99
|
+
The normal project-creation flow runs `flask db init`. Create and apply revisions with:
|
|
100
|
+
|
|
101
|
+
```bash
|
|
102
|
+
flask db migrate -m "Initial schema"
|
|
103
|
+
flask db upgrade
|
|
104
|
+
```
|
|
105
|
+
|
|
106
|
+
When a project is created with `--no-install`, install its dependencies and run `flask db init` yourself before creating the first revision.
|
|
107
|
+
|
|
108
|
+
## Authentication scaffold
|
|
109
|
+
|
|
110
|
+
```bash
|
|
111
|
+
flaskion make:auth
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
This creates a user model, schema, controller, and login/register/dashboard templates. Forms carry Flask-WTF CSRF tokens, login clears prior session data, passwords must contain at least 12 characters, and logout is POST-only.
|
|
115
|
+
|
|
116
|
+
This remains starter authentication, not a complete identity product. Production applications still need requirements appropriate to their threat model, such as email verification, password reset, rate limiting, secure-cookie deployment settings, and authorization policies.
|
|
117
|
+
|
|
118
|
+
## Development
|
|
119
|
+
|
|
120
|
+
Install the development dependency group with a compatible environment manager, then run:
|
|
121
|
+
|
|
122
|
+
```bash
|
|
123
|
+
python -m unittest discover -v
|
|
124
|
+
ruff check .
|
|
125
|
+
python -m build
|
|
126
|
+
```
|
|
127
|
+
|
|
128
|
+
When running directly from a source checkout with the `src/` layout, use an editable install or set `PYTHONPATH=src:.`.
|
|
129
|
+
|
|
130
|
+
## Runtime usage
|
|
131
|
+
|
|
132
|
+
Use cases do not inherit from Flaskion classes. Register a plain function, bound service method, or callable object against any message type:
|
|
133
|
+
|
|
134
|
+
```python
|
|
135
|
+
from dataclasses import dataclass
|
|
136
|
+
|
|
137
|
+
from flaskion import Application
|
|
138
|
+
|
|
139
|
+
|
|
140
|
+
@dataclass(frozen=True)
|
|
141
|
+
class Greet:
|
|
142
|
+
name: str
|
|
143
|
+
|
|
144
|
+
|
|
145
|
+
application = Application()
|
|
146
|
+
application.register(Greet, lambda message: f"Hello, {message.name}")
|
|
147
|
+
|
|
148
|
+
assert application.handle(Greet("Ada")) == "Hello, Ada"
|
|
149
|
+
```
|
|
150
|
+
|
|
151
|
+
The decorator form `@application.use_case(Greet)` is available but optional. Services and repository protocols are application-owned; Flaskion does not require base classes or a universal repository abstraction.
|
|
152
|
+
|
|
153
|
+
## Task List example
|
|
154
|
+
|
|
155
|
+
The canonical example is under [`examples/task_list`](examples/task_list). It implements create, list, and complete through one `TaskService`, a repository protocol, and a SQLite adapter. HTTP, CLI, and MCP receive the same `Application` instance and invoke the same handlers.
|
|
156
|
+
|
|
157
|
+
```bash
|
|
158
|
+
PYTHONPATH=src:. flask --app examples.task_list.run run
|
|
159
|
+
PYTHONPATH=src:. python -m examples.task_list.cli create "Write documentation"
|
|
160
|
+
PYTHONPATH=src:. python -m examples.task_list.cli list
|
|
161
|
+
PYTHONPATH=src:. python -m examples.task_list.cli complete 1
|
|
162
|
+
PYTHONPATH=src:. flaskion mcp:serve --app examples.task_list.mcp_server:mcp
|
|
163
|
+
```
|
|
164
|
+
|
|
165
|
+
Install the MCP adapter with `pip install -e '.[mcp]'`. MCP remains optional:
|
|
166
|
+
FastMCP is imported only by
|
|
167
|
+
`flaskion.mcp`'s private compatibility boundary, never by Task List code.
|
|
168
|
+
|
|
169
|
+
For a remotely connectable development endpoint, use Streamable HTTP:
|
|
170
|
+
|
|
171
|
+
```bash
|
|
172
|
+
PYTHONPATH=src:. flaskion mcp:serve \
|
|
173
|
+
--app examples.task_list.mcp_server:mcp \
|
|
174
|
+
--transport http --host 127.0.0.1 --port 8000
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
The MCP endpoint is `http://127.0.0.1:8000/mcp`. Inspect it locally with:
|
|
178
|
+
|
|
179
|
+
```bash
|
|
180
|
+
npx -y @modelcontextprotocol/inspector --web http://127.0.0.1:8000/mcp
|
|
181
|
+
```
|
|
182
|
+
|
|
183
|
+
Loopback is the safe default. Binding to a public interface exposes an
|
|
184
|
+
unauthenticated MCP endpoint until Flaskion's remote authentication boundary is
|
|
185
|
+
implemented; use network controls and do not treat the development command as
|
|
186
|
+
a production deployment configuration.
|
|
187
|
+
|
|
188
|
+
The example intentionally does not include jobs, events, authentication policy, generic middleware, or a dependency-injection container.
|
|
189
|
+
|
|
190
|
+
## Architecture documents
|
|
191
|
+
|
|
192
|
+
- [Flaskion 2 architecture](docs/FLASKION_2_ARCHITECTURE.md)
|
|
193
|
+
- [Flaskion 2 roadmap](docs/FLASKION_2_ROADMAP.md)
|
|
194
|
+
- [MCP architecture](docs/MCP_ARCHITECTURE.md)
|