flaskion 2.0.0a1__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (51) hide show
  1. flaskion/__init__.py +18 -0
  2. flaskion/application.py +49 -0
  3. flaskion/errors.py +14 -0
  4. flaskion/mcp/__init__.py +10 -0
  5. flaskion/mcp/_compat.py +12 -0
  6. flaskion/mcp/errors.py +6 -0
  7. flaskion/mcp/server.py +91 -0
  8. flaskion/mcp/testing.py +53 -0
  9. flaskion-2.0.0a1.dist-info/METADATA +215 -0
  10. flaskion-2.0.0a1.dist-info/RECORD +51 -0
  11. flaskion-2.0.0a1.dist-info/WHEEL +5 -0
  12. flaskion-2.0.0a1.dist-info/entry_points.txt +2 -0
  13. flaskion-2.0.0a1.dist-info/top_level.txt +2 -0
  14. flaskion_cli/__init__.py +0 -0
  15. flaskion_cli/cli.py +451 -0
  16. flaskion_cli/cli_templates/api_controller_template.py.jinja +33 -0
  17. flaskion_cli/cli_templates/api_route_template.py.jinja +30 -0
  18. flaskion_cli/cli_templates/auth_controller_template.py.jinja +51 -0
  19. flaskion_cli/cli_templates/controller_template.py.jinja +30 -0
  20. flaskion_cli/cli_templates/html/auth/dashboard.html.jinja +71 -0
  21. flaskion_cli/cli_templates/html/auth/login.html.jinja +118 -0
  22. flaskion_cli/cli_templates/html/auth/register.html.jinja +124 -0
  23. flaskion_cli/cli_templates/model_template.py.jinja +9 -0
  24. flaskion_cli/cli_templates/schema_template.py.jinja +15 -0
  25. flaskion_cli/cli_templates/user_model_template.py.jinja +12 -0
  26. flaskion_cli/cli_templates/user_schema_template.py.jinja +6 -0
  27. flaskion_cli/cli_templates/web_route_template.py.jinja +30 -0
  28. flaskion_cli/flaskion_template/.env.example +7 -0
  29. flaskion_cli/flaskion_template/.gitattributes +2 -0
  30. flaskion_cli/flaskion_template/.gitignore +37 -0
  31. flaskion_cli/flaskion_template/app/__init__.py +34 -0
  32. flaskion_cli/flaskion_template/app/application.py +6 -0
  33. flaskion_cli/flaskion_template/app/config.py +20 -0
  34. flaskion_cli/flaskion_template/app/controllers/__init__.py +0 -0
  35. flaskion_cli/flaskion_template/app/controllers/api_controller.py +4 -0
  36. flaskion_cli/flaskion_template/app/controllers/hello_controller.py +6 -0
  37. flaskion_cli/flaskion_template/app/extensions.py +6 -0
  38. flaskion_cli/flaskion_template/app/models/__init__.py +7 -0
  39. flaskion_cli/flaskion_template/app/models/example.py +16 -0
  40. flaskion_cli/flaskion_template/app/models/mixin.py +13 -0
  41. flaskion_cli/flaskion_template/app/routes/__init__.py +7 -0
  42. flaskion_cli/flaskion_template/app/routes/api_routes.py +11 -0
  43. flaskion_cli/flaskion_template/app/routes/web_routes.py +11 -0
  44. flaskion_cli/flaskion_template/app/schemas/__init__.py +1 -0
  45. flaskion_cli/flaskion_template/app/schemas/example_schema.py +14 -0
  46. flaskion_cli/flaskion_template/app/static/css/style.css +66 -0
  47. flaskion_cli/flaskion_template/app/static/images/logo.png +0 -0
  48. flaskion_cli/flaskion_template/app/templates/base.html +27 -0
  49. flaskion_cli/flaskion_template/app/templates/hello.html +10 -0
  50. flaskion_cli/flaskion_template/requirements.txt +8 -0
  51. flaskion_cli/flaskion_template/run.py +7 -0
flaskion/__init__.py ADDED
@@ -0,0 +1,18 @@
1
+ """Public Flaskion runtime API.
2
+
3
+ The runtime deliberately exposes only the small application boundary needed by
4
+ interface adapters. Application code can use ordinary dataclasses, functions,
5
+ services, and repository protocols without inheriting from framework classes.
6
+ """
7
+
8
+ from flaskion.application import Application
9
+ from flaskion.errors import DuplicateUseCase, FlaskionError, UseCaseNotRegistered
10
+
11
+ __all__ = [
12
+ "Application",
13
+ "DuplicateUseCase",
14
+ "FlaskionError",
15
+ "UseCaseNotRegistered",
16
+ ]
17
+
18
+ __version__ = "2.0.0a1"
@@ -0,0 +1,49 @@
1
+ from collections.abc import Callable
2
+ from typing import Any, TypeVar
3
+
4
+ from flaskion.errors import DuplicateUseCase, UseCaseNotRegistered
5
+
6
+ Message = TypeVar("Message")
7
+ Result = TypeVar("Result")
8
+ Handler = Callable[[Any], Any]
9
+
10
+
11
+ class Application:
12
+ """Register and invoke application use cases by message type.
13
+
14
+ A message can be any Python object, normally a small dataclass. A handler
15
+ can be a function, a bound service method, or any callable object. Flaskion
16
+ imposes no base classes on messages, handlers, services, or repositories.
17
+ """
18
+
19
+ def __init__(self) -> None:
20
+ self._handlers: dict[type[Any], Handler] = {}
21
+
22
+ def register(self, message_type: type[Message], handler: Callable[[Message], Result]) -> None:
23
+ """Register one handler for a message type."""
24
+ if message_type in self._handlers:
25
+ raise DuplicateUseCase(message_type)
26
+ self._handlers[message_type] = handler
27
+
28
+ def use_case(
29
+ self, message_type: type[Message]
30
+ ) -> Callable[[Callable[[Message], Result]], Callable[[Message], Result]]:
31
+ """Optionally register a function with decorator syntax."""
32
+
33
+ def register(handler: Callable[[Message], Result]) -> Callable[[Message], Result]:
34
+ self.register(message_type, handler)
35
+ return handler
36
+
37
+ return register
38
+
39
+ def handle(self, message: Message) -> Any:
40
+ """Invoke the handler registered for the message's concrete type."""
41
+ try:
42
+ handler = self._handlers[type(message)]
43
+ except KeyError as exc:
44
+ raise UseCaseNotRegistered(type(message)) from exc
45
+ return handler(message)
46
+
47
+ def registered_messages(self) -> tuple[type[Any], ...]:
48
+ """Return registered message types for diagnostics and tests."""
49
+ return tuple(self._handlers)
flaskion/errors.py ADDED
@@ -0,0 +1,14 @@
1
+ class FlaskionError(Exception):
2
+ """Base class for errors raised by the Flaskion runtime itself."""
3
+
4
+
5
+ class UseCaseNotRegistered(FlaskionError):
6
+ def __init__(self, message_type: type[object]) -> None:
7
+ self.message_type = message_type
8
+ super().__init__(f"No use case is registered for {message_type.__name__}")
9
+
10
+
11
+ class DuplicateUseCase(FlaskionError):
12
+ def __init__(self, message_type: type[object]) -> None:
13
+ self.message_type = message_type
14
+ super().__init__(f"A use case is already registered for {message_type.__name__}")
@@ -0,0 +1,10 @@
1
+ """Optional MCP adapter support for Flaskion applications.
2
+
3
+ Install ``flaskion[mcp]`` before importing this package. Importing the
4
+ main :mod:`flaskion` package does not load FastMCP.
5
+ """
6
+
7
+ from flaskion.mcp.errors import MCPTransportError
8
+ from flaskion.mcp.server import MCPServer, ToolAnnotations
9
+
10
+ __all__ = ["MCPServer", "MCPTransportError", "ToolAnnotations"]
@@ -0,0 +1,12 @@
1
+ """The deliberately small boundary around version-sensitive FastMCP imports."""
2
+
3
+ try:
4
+ from fastmcp import Client, FastMCP
5
+ from fastmcp.exceptions import ToolError
6
+ except ImportError as exc: # pragma: no cover - exercised without the optional extra
7
+ raise ImportError(
8
+ "Flaskion MCP support requires the optional dependency. "
9
+ 'Install it with `pip install "flaskion[mcp]"`.'
10
+ ) from exc
11
+
12
+ __all__ = ["Client", "FastMCP", "ToolError"]
flaskion/mcp/errors.py ADDED
@@ -0,0 +1,6 @@
1
+ from flaskion.errors import FlaskionError
2
+
3
+
4
+ class MCPTransportError(FlaskionError):
5
+ """A safe error raised when an MCP client cannot establish a transport."""
6
+
flaskion/mcp/server.py ADDED
@@ -0,0 +1,91 @@
1
+ from collections.abc import Callable, Iterable
2
+ from dataclasses import dataclass
3
+ from typing import Any, Literal, TypeVar
4
+
5
+ from flaskion import Application
6
+ from flaskion.mcp._compat import FastMCP, ToolError
7
+
8
+ Function = TypeVar("Function", bound=Callable[..., Any])
9
+
10
+
11
+ @dataclass(frozen=True)
12
+ class ToolAnnotations:
13
+ """Stable, commonly useful behavior hints for an MCP tool."""
14
+
15
+ read_only: bool = False
16
+ destructive: bool = True
17
+ idempotent: bool = False
18
+ open_world: bool = True
19
+
20
+ def as_fastmcp(self) -> dict[str, bool]:
21
+ return {
22
+ "readOnlyHint": self.read_only,
23
+ "destructiveHint": self.destructive,
24
+ "idempotentHint": self.idempotent,
25
+ "openWorldHint": self.open_world,
26
+ }
27
+
28
+
29
+ class MCPServer:
30
+ """Expose a Flaskion application through an optional FastMCP adapter.
31
+
32
+ Tool functions remain explicit adapter code. They construct application
33
+ messages, call :meth:`handle`, and map results to transport-safe values.
34
+ """
35
+
36
+ def __init__(
37
+ self,
38
+ name: str,
39
+ application: Application,
40
+ *,
41
+ application_errors: Iterable[type[Exception]] = (),
42
+ ) -> None:
43
+ self.application = application
44
+ self.application_errors = tuple(application_errors)
45
+ self._server = FastMCP(name)
46
+
47
+ def handle(self, message: object) -> Any:
48
+ """Invoke a use case and translate declared application errors safely."""
49
+ try:
50
+ return self.application.handle(message)
51
+ except self.application_errors as exc:
52
+ raise ToolError(str(exc)) from exc
53
+
54
+ def tool(
55
+ self,
56
+ *,
57
+ name: str,
58
+ description: str | None = None,
59
+ annotations: ToolAnnotations | None = None,
60
+ ) -> Callable[[Function], Function]:
61
+ """Register a typed function as a tool without exposing FastMCP."""
62
+
63
+ def register(function: Function) -> Function:
64
+ self._server.tool(
65
+ name=name,
66
+ description=description,
67
+ annotations=annotations.as_fastmcp() if annotations else None,
68
+ )(function)
69
+ return function
70
+
71
+ return register
72
+
73
+ def run(
74
+ self,
75
+ transport: Literal["stdio", "http"] = "stdio",
76
+ *,
77
+ host: str = "127.0.0.1",
78
+ port: int = 8000,
79
+ ) -> None:
80
+ """Run over local stdio or Streamable HTTP at ``/mcp``."""
81
+ if transport == "stdio":
82
+ self._server.run(transport="stdio")
83
+ return
84
+ if transport != "http":
85
+ raise ValueError("MCP transport must be 'stdio' or 'http'")
86
+ self._server.run(transport="http", host=host, port=port)
87
+
88
+ @property
89
+ def native(self) -> Any:
90
+ """Return the underlying server for advanced adapter-only extensions."""
91
+ return self._server
@@ -0,0 +1,53 @@
1
+ from typing import Any
2
+
3
+ from flaskion.mcp._compat import Client, ToolError
4
+ from flaskion.mcp.errors import MCPTransportError
5
+ from flaskion.mcp.server import MCPServer
6
+
7
+
8
+ class MCPTestClient:
9
+ """An in-memory client for testing a Flaskion MCP server."""
10
+
11
+ def __init__(self, server: MCPServer | str) -> None:
12
+ self._remote = isinstance(server, str)
13
+ self._client = Client(server if self._remote else server.native)
14
+
15
+ @classmethod
16
+ def remote(cls, url: str) -> "MCPTestClient":
17
+ """Connect to a Streamable HTTP endpoint for network integration tests."""
18
+ return cls(url)
19
+
20
+ async def __aenter__(self) -> "MCPTestClient":
21
+ try:
22
+ await self._client.__aenter__()
23
+ except Exception as exc:
24
+ if not self._remote:
25
+ raise
26
+ raise MCPTransportError("Unable to connect to the MCP server.") from exc
27
+ return self
28
+
29
+ async def __aexit__(self, *args: object) -> None:
30
+ await self._client.__aexit__(*args)
31
+
32
+ async def list_tools(self) -> Any:
33
+ try:
34
+ return await self._client.list_tools()
35
+ except Exception as exc:
36
+ self._raise_transport_error(exc)
37
+
38
+ async def call_tool(
39
+ self, name: str, arguments: dict[str, Any] | None = None, *, raise_on_error: bool = True
40
+ ) -> Any:
41
+ try:
42
+ return await self._client.call_tool(
43
+ name, arguments or {}, raise_on_error=raise_on_error
44
+ )
45
+ except ToolError:
46
+ raise
47
+ except Exception as exc:
48
+ self._raise_transport_error(exc)
49
+
50
+ def _raise_transport_error(self, error: Exception) -> None:
51
+ if not self._remote:
52
+ raise error
53
+ raise MCPTransportError("MCP transport request failed.") from error
@@ -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,51 @@
1
+ flaskion/__init__.py,sha256=oc7ko6xL4Q8Ir3ZXI6oEixqG69pMRMjyeBSCU_Thyak,532
2
+ flaskion/application.py,sha256=WuET75beWgzBIMp7EjWQ_ujifiWQIW9BKohrUgj4vMo,1827
3
+ flaskion/errors.py,sha256=BYwUhpEYVf6lkSVxh84za07Qbzv2ddreKuzPuoes8po,564
4
+ flaskion/mcp/__init__.py,sha256=FbMENzMH4tATJXfNynO6cB1tdYzoSYMNI22S9xgOdGg,362
5
+ flaskion/mcp/_compat.py,sha256=5JCdiz8kO6rH2JwOL0hYddz_pjjuTvAXZnVtjKheUXg,464
6
+ flaskion/mcp/errors.py,sha256=1XAnF4idmrdiEhnRqR6QZW5QKG7rjlFv_6DlOOMjJNs,164
7
+ flaskion/mcp/server.py,sha256=qfLiqT8gs_k12TXFmKI0FPhdYJ2pV1T1nLkz65VnL5o,2841
8
+ flaskion/mcp/testing.py,sha256=B2nA8tbzmOJzRnITEcuVZylDPkh8Rrcg1-FRFLg0fgw,1789
9
+ flaskion_cli/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
10
+ flaskion_cli/cli.py,sha256=NsGe6cBb4Xx-iuOsnsVfVIcJQ3DucYzRMziIswoHvfU,15442
11
+ flaskion_cli/cli_templates/api_controller_template.py.jinja,sha256=bZUx5CbPUsaMTRG1kTANiTZ7l5wMfszCnLwHGu49KRY,818
12
+ flaskion_cli/cli_templates/api_route_template.py.jinja,sha256=fSZ4aWP85RjUF4bcA7WEyTt4EO5cfU8pQ25CabMQoA8,875
13
+ flaskion_cli/cli_templates/auth_controller_template.py.jinja,sha256=SL_fCorysK30_blgpUIPYPQ6UNYvn62HK9NhWXMWqF4,2141
14
+ flaskion_cli/cli_templates/controller_template.py.jinja,sha256=rNx6Bzp5dOYtrC1JiY2qDRRMWyoIoPJGFv0nGbxzRgQ,760
15
+ flaskion_cli/cli_templates/model_template.py.jinja,sha256=-9r9E9x8PwwZQtMUhDs-vDrdeLFE5C7TRCP9ok3X_2k,242
16
+ flaskion_cli/cli_templates/schema_template.py.jinja,sha256=kXSVa_z6IEdIuRKNPgk_n8qetAFRaM20_gAlSIaYH-o,506
17
+ flaskion_cli/cli_templates/user_model_template.py.jinja,sha256=WitpGhhttKKlQc3XwwZ1B64QMnQzbSFqbMzVkh1O9hY,386
18
+ flaskion_cli/cli_templates/user_schema_template.py.jinja,sha256=iyZkzOx3CRWCTb2CqZ7oMmLTZBnKNHiaFfyrtClbwu0,149
19
+ flaskion_cli/cli_templates/web_route_template.py.jinja,sha256=kJpuVC266SWTMQZk3K3shkm6NCdz_bivDyl2CrJ02Y4,894
20
+ flaskion_cli/cli_templates/html/auth/dashboard.html.jinja,sha256=SgwHQryDgGsV5XVpUo8ZNSDcq9fyVOHu3bpvWRem4-w,1829
21
+ flaskion_cli/cli_templates/html/auth/login.html.jinja,sha256=M0Bi-_o9wPs2wn77IlNIT8CkGfP9d_Ir7_4SA_pwjwI,2967
22
+ flaskion_cli/cli_templates/html/auth/register.html.jinja,sha256=tJGSMiEaj8Pa41rww41ipew4_Q-pLwLugehScKAJ9jk,2867
23
+ flaskion_cli/flaskion_template/.env.example,sha256=Z2UjA6vBL4xUtx4nxfM8OC8x6nAkZ0z3mui8gXFwRus,161
24
+ flaskion_cli/flaskion_template/.gitattributes,sha256=Gh2-F2vCM7SZ01pX23UT8pQcmauXWfF3gwyRSb6ZAFs,66
25
+ flaskion_cli/flaskion_template/.gitignore,sha256=Z3xGk7_aeueVvLKemX1jvtuY0oxLCjzx0TG4DYVegoQ,399
26
+ flaskion_cli/flaskion_template/requirements.txt,sha256=brmAW2hNofJ0APKGCEm-_3D0Ukm4nRXk2X2Ta2L08_k,150
27
+ flaskion_cli/flaskion_template/run.py,sha256=THqClv-8M4OWaX9dQJnr9SlsWHbkRLhRRE2m7f4bEP4,150
28
+ flaskion_cli/flaskion_template/app/__init__.py,sha256=DOK-AZEFJYeL6utJFVBamjLad2rEzYnaJDEJOSok0eE,960
29
+ flaskion_cli/flaskion_template/app/application.py,sha256=aJFjiGgbuxaSnyTYK87KCqqTOm2iZMT1slnY8zy-Sas,169
30
+ flaskion_cli/flaskion_template/app/config.py,sha256=Y3h3XRIB-zMGZgfUgEzqSlvVR1KYd7K8XPve8Dsejcw,522
31
+ flaskion_cli/flaskion_template/app/extensions.py,sha256=NHDG1iGGDiVhTL0Edan1qORxGbbTuZiMR59AmUtWSPs,120
32
+ flaskion_cli/flaskion_template/app/controllers/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
33
+ flaskion_cli/flaskion_template/app/controllers/api_controller.py,sha256=r_iK1axSLva0EWEHi4rCnb4rIaKMcqpW4cTzXZxAjWs,103
34
+ flaskion_cli/flaskion_template/app/controllers/hello_controller.py,sha256=nfG8zcgZho4nnjgopmhnpM-TFiVLJ-uPNGU6umpguzs,138
35
+ flaskion_cli/flaskion_template/app/models/__init__.py,sha256=SOZuzAzL6-PvI1BwHBij3iZvIzxoCewBo19iZBbLfd8,268
36
+ flaskion_cli/flaskion_template/app/models/example.py,sha256=HDP-_gJIW6x8wj42tHaVIndiVxZXatlV_N5Uhm2sKok,716
37
+ flaskion_cli/flaskion_template/app/models/mixin.py,sha256=PSyGkcFcd6IboPgWidF7Og0d6-BUC9iPfBe3vVtJDTM,419
38
+ flaskion_cli/flaskion_template/app/routes/__init__.py,sha256=XkOW1lzN8c2Hmu2QTaW1hbFAJQAj39MQb_-fYucXVmk,225
39
+ flaskion_cli/flaskion_template/app/routes/api_routes.py,sha256=cXfn9Fs1N-QpFJ2r7d0tD313aq1AC_5P9uUO1dBrMQY,336
40
+ flaskion_cli/flaskion_template/app/routes/web_routes.py,sha256=S1B4lnhVFg1iOajcJsLraKGJnNDBPviE3UPq4peWD6E,288
41
+ flaskion_cli/flaskion_template/app/schemas/__init__.py,sha256=5KNtQtkzlhCsJHGgi-fd9bAL81HUR29if7YfJUiG-E8,49
42
+ flaskion_cli/flaskion_template/app/schemas/example_schema.py,sha256=_zkucaMYnCzeSlOxxN0XM3mSTYCejmAlOdFa-jVBjDI,463
43
+ flaskion_cli/flaskion_template/app/static/css/style.css,sha256=RIf-YAJxf_l8h_14sN43nWkhv8tNAzh9xVFiq5KjcKE,1078
44
+ flaskion_cli/flaskion_template/app/static/images/logo.png,sha256=-kob2gwFL63ddvePWqwMqBjxTDUrHuhxSsVwJsdMcnM,243656
45
+ flaskion_cli/flaskion_template/app/templates/base.html,sha256=xP0Sh70Nj59BPSg0OcNNYn1Fo-ivNRNlHQDWZOjm4-U,654
46
+ flaskion_cli/flaskion_template/app/templates/hello.html,sha256=nzQbSAxkY-mkRO4IZgbQaw17OZ7m6IcaqAgCfroy0WE,425
47
+ flaskion-2.0.0a1.dist-info/METADATA,sha256=OHiNQbe0wD2soyk197L3Yei9YSWeJSYSXiF0pPhaWmw,8336
48
+ flaskion-2.0.0a1.dist-info/WHEEL,sha256=YVMoNqKzERt-wjUZwJ33xBGAwnFl-4cqbYkTtWa4itE,91
49
+ flaskion-2.0.0a1.dist-info/entry_points.txt,sha256=9jiIsU12_kGt5smQfLBKBSWQaNXSFpmX1RhfGApl40A,50
50
+ flaskion-2.0.0a1.dist-info/top_level.txt,sha256=fr3p2GQtTgwP4tZW12G6FvAH-yBI--ywcskqopvKONo,22
51
+ flaskion-2.0.0a1.dist-info/RECORD,,
@@ -0,0 +1,5 @@
1
+ Wheel-Version: 1.0
2
+ Generator: setuptools (84.0.0)
3
+ Root-Is-Purelib: true
4
+ Tag: py3-none-any
5
+
@@ -0,0 +1,2 @@
1
+ [console_scripts]
2
+ flaskion = flaskion_cli.cli:cli
@@ -0,0 +1,2 @@
1
+ flaskion
2
+ flaskion_cli
File without changes