fluxium 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.
Files changed (76) hide show
  1. fluxium-0.1.0/CODE_OF_CONDUCT.md +30 -0
  2. fluxium-0.1.0/CONTRIBUTING.md +92 -0
  3. fluxium-0.1.0/LICENSE +21 -0
  4. fluxium-0.1.0/MANIFEST.in +8 -0
  5. fluxium-0.1.0/PKG-INFO +408 -0
  6. fluxium-0.1.0/README.md +371 -0
  7. fluxium-0.1.0/docs/architecture.md +205 -0
  8. fluxium-0.1.0/docs/getting_started.md +368 -0
  9. fluxium-0.1.0/docs/internals.md +198 -0
  10. fluxium-0.1.0/examples/example_app.py +234 -0
  11. fluxium-0.1.0/examples/fullstack_app.py +250 -0
  12. fluxium-0.1.0/examples/taskflow_demo.py +1238 -0
  13. fluxium-0.1.0/flux/__init__.py +54 -0
  14. fluxium-0.1.0/flux/__main__.py +4 -0
  15. fluxium-0.1.0/flux/auth/__init__.py +14 -0
  16. fluxium-0.1.0/flux/auth/auth.py +332 -0
  17. fluxium-0.1.0/flux/benchmarking.py +290 -0
  18. fluxium-0.1.0/flux/cli.py +199 -0
  19. fluxium-0.1.0/flux/client/__init__.py +16 -0
  20. fluxium-0.1.0/flux/client/client.py +165 -0
  21. fluxium-0.1.0/flux/client/response.py +104 -0
  22. fluxium-0.1.0/flux/client/retry.py +80 -0
  23. fluxium-0.1.0/flux/client/session.py +315 -0
  24. fluxium-0.1.0/flux/config/__init__.py +4 -0
  25. fluxium-0.1.0/flux/config/settings.py +189 -0
  26. fluxium-0.1.0/flux/core/__init__.py +36 -0
  27. fluxium-0.1.0/flux/core/connection.py +214 -0
  28. fluxium-0.1.0/flux/core/headers.py +147 -0
  29. fluxium-0.1.0/flux/core/json.py +84 -0
  30. fluxium-0.1.0/flux/core/parser.py +388 -0
  31. fluxium-0.1.0/flux/core/pool.py +209 -0
  32. fluxium-0.1.0/flux/core/streaming.py +168 -0
  33. fluxium-0.1.0/flux/observability/__init__.py +18 -0
  34. fluxium-0.1.0/flux/observability/metrics.py +257 -0
  35. fluxium-0.1.0/flux/openapi/__init__.py +4 -0
  36. fluxium-0.1.0/flux/openapi/generator.py +215 -0
  37. fluxium-0.1.0/flux/orm/__init__.py +13 -0
  38. fluxium-0.1.0/flux/orm/migrations.py +112 -0
  39. fluxium-0.1.0/flux/orm/model.py +517 -0
  40. fluxium-0.1.0/flux/plugins/__init__.py +10 -0
  41. fluxium-0.1.0/flux/plugins/plugin.py +194 -0
  42. fluxium-0.1.0/flux/py.typed +0 -0
  43. fluxium-0.1.0/flux/scaffold.py +285 -0
  44. fluxium-0.1.0/flux/schema/__init__.py +4 -0
  45. fluxium-0.1.0/flux/schema/schema.py +404 -0
  46. fluxium-0.1.0/flux/security/__init__.py +20 -0
  47. fluxium-0.1.0/flux/security/security.py +254 -0
  48. fluxium-0.1.0/flux/server/__init__.py +39 -0
  49. fluxium-0.1.0/flux/server/app.py +319 -0
  50. fluxium-0.1.0/flux/server/context.py +62 -0
  51. fluxium-0.1.0/flux/server/di.py +191 -0
  52. fluxium-0.1.0/flux/server/middleware.py +153 -0
  53. fluxium-0.1.0/flux/server/request.py +180 -0
  54. fluxium-0.1.0/flux/server/response.py +281 -0
  55. fluxium-0.1.0/flux/server/router.py +163 -0
  56. fluxium-0.1.0/flux/tasks/__init__.py +4 -0
  57. fluxium-0.1.0/flux/tasks/queue.py +262 -0
  58. fluxium-0.1.0/flux/templates/__init__.py +15 -0
  59. fluxium-0.1.0/flux/templates/engine.py +184 -0
  60. fluxium-0.1.0/flux/websocket/__init__.py +4 -0
  61. fluxium-0.1.0/flux/websocket/websocket.py +258 -0
  62. fluxium-0.1.0/fluxium.egg-info/PKG-INFO +408 -0
  63. fluxium-0.1.0/fluxium.egg-info/SOURCES.txt +75 -0
  64. fluxium-0.1.0/fluxium.egg-info/dependency_links.txt +1 -0
  65. fluxium-0.1.0/fluxium.egg-info/entry_points.txt +3 -0
  66. fluxium-0.1.0/fluxium.egg-info/requires.txt +16 -0
  67. fluxium-0.1.0/fluxium.egg-info/top_level.txt +1 -0
  68. fluxium-0.1.0/pyproject.toml +62 -0
  69. fluxium-0.1.0/setup.cfg +7 -0
  70. fluxium-0.1.0/tests/test_auth.py +74 -0
  71. fluxium-0.1.0/tests/test_integration.py +184 -0
  72. fluxium-0.1.0/tests/test_middleware.py +88 -0
  73. fluxium-0.1.0/tests/test_orm.py +140 -0
  74. fluxium-0.1.0/tests/test_parser.py +70 -0
  75. fluxium-0.1.0/tests/test_router.py +79 -0
  76. fluxium-0.1.0/tests/test_schema.py +100 -0
@@ -0,0 +1,30 @@
1
+ # Code of Conduct
2
+
3
+ ## Our Pledge
4
+
5
+ We are committed to making participation in this project a welcoming experience for everyone, regardless of background, experience level, gender, identity, nationality, ethnicity, religion, or any other personal characteristic.
6
+
7
+ ## Our Standards
8
+
9
+ **Positive behaviour includes:**
10
+
11
+ - Using welcoming and inclusive language
12
+ - Being respectful of differing viewpoints and experience
13
+ - Gracefully accepting constructive feedback
14
+ - Focusing on what is best for the community
15
+ - Showing empathy toward other community members
16
+
17
+ **Unacceptable behaviour includes:**
18
+
19
+ - Harassment or discriminatory language of any kind
20
+ - Personal attacks or insults
21
+ - Trolling or deliberately disruptive behaviour
22
+ - Publishing others' private information without permission
23
+
24
+ ## Enforcement
25
+
26
+ Instances of unacceptable behaviour may be reported by opening a private issue or contacting the maintainers directly. All reports will be reviewed and addressed promptly.
27
+
28
+ ## Attribution
29
+
30
+ This Code of Conduct is adapted from the [Contributor Covenant](https://www.contributor-covenant.org), version 2.1.
@@ -0,0 +1,92 @@
1
+ # Contributing to Fluxium
2
+
3
+ Fluxium is primarily a learning project, but contributions are welcome. If you have found a bug, want to improve performance, or want to add something useful, open an issue first so we can talk through the approach before you write code.
4
+
5
+ ---
6
+
7
+ ## Getting started
8
+
9
+ Fork the repository and clone it:
10
+
11
+ ```bash
12
+ git clone https://github.com/sidx0/fluxium
13
+ cd fluxium
14
+ ```
15
+
16
+ Set up a virtual environment:
17
+
18
+ ```bash
19
+ python -m venv venv
20
+ source venv/bin/activate # Windows: venv\Scripts\activate
21
+ pip install -e ".[dev]"
22
+ ```
23
+
24
+ Run the tests to confirm everything is working:
25
+
26
+ ```bash
27
+ pytest tests/ -v
28
+ ```
29
+
30
+ ---
31
+
32
+ ## What to work on
33
+
34
+ Bug fixes are always welcome, especially in the HTTP parser, ORM, or DI system. If you have a performance improvement, include benchmarks before and after so the change can be evaluated. New layers should follow the pattern of existing ones — zero mandatory dependencies, testable in isolation.
35
+
36
+ If you want to add a feature, open an issue describing what problem it solves before writing code. That way you do not spend time on something that might not fit the project's direction.
37
+
38
+ ---
39
+
40
+ ## Making a change
41
+
42
+ Create a branch:
43
+
44
+ ```bash
45
+ git checkout -b fix/describe-the-fix
46
+ ```
47
+
48
+ Write tests for your change. Tests are in `tests/` and use pytest-asyncio for async cases:
49
+
50
+ ```python
51
+ import pytest
52
+ from flux import Flux
53
+
54
+ @pytest.mark.asyncio
55
+ async def test_something():
56
+ app = Flux()
57
+ ...
58
+ ```
59
+
60
+ Make sure the full test suite passes before submitting:
61
+
62
+ ```bash
63
+ pytest tests/ -v
64
+ ```
65
+
66
+ ---
67
+
68
+ ## Pull request checklist
69
+
70
+ - Tests pass
71
+ - New behaviour has test coverage
72
+ - No new mandatory dependencies
73
+ - The PR description explains what the change does and why
74
+
75
+ ---
76
+
77
+ ## Reporting bugs
78
+
79
+ Open an issue with:
80
+
81
+ - Fluxium version (`fluxium version`)
82
+ - Python version and OS
83
+ - A minimal example that reproduces the problem
84
+ - The full traceback if there is one
85
+
86
+ ---
87
+
88
+ ## Code style
89
+
90
+ Type hints on all public functions. `async def` for anything that does I/O. Keep modules focused — each file should do one thing. Docstrings on public classes and functions.
91
+
92
+ No external formatters are required, but the code should be consistent with what is already there.
fluxium-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2025 Flux Contributors
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,8 @@
1
+ include README.md
2
+ include LICENSE
3
+ include CONTRIBUTING.md
4
+ include CODE_OF_CONDUCT.md
5
+ include flux/py.typed
6
+ recursive-include flux *.py
7
+ recursive-include docs *.md
8
+ recursive-include examples *.py
fluxium-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,408 @@
1
+ Metadata-Version: 2.4
2
+ Name: fluxium
3
+ Version: 0.1.0
4
+ Summary: A zero-dependency async Python web framework
5
+ Project-URL: Homepage, https://github.com/sidx0/fluxium
6
+ Project-URL: Repository, https://github.com/sidx0/fluxium
7
+ Project-URL: Documentation, https://github.com/sidx0/fluxium/tree/main/docs
8
+ Project-URL: Bug Tracker, https://github.com/sidx0/fluxium/issues
9
+ Project-URL: Changelog, https://github.com/sidx0/fluxium/blob/main/CHANGELOG.md
10
+ Keywords: web,framework,asyncio,http,async,backend
11
+ Classifier: Development Status :: 3 - Alpha
12
+ Classifier: Intended Audience :: Developers
13
+ Classifier: License :: OSI Approved :: MIT License
14
+ Classifier: Programming Language :: Python :: 3
15
+ Classifier: Programming Language :: Python :: 3.10
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Framework :: AsyncIO
20
+ Classifier: Topic :: Internet :: WWW/HTTP :: HTTP Servers
21
+ Classifier: Topic :: Software Development :: Libraries :: Application Frameworks
22
+ Classifier: Operating System :: OS Independent
23
+ Requires-Python: >=3.10
24
+ Description-Content-Type: text/markdown
25
+ Provides-Extra: jwt
26
+ Requires-Dist: PyJWT>=2.8; extra == "jwt"
27
+ Provides-Extra: templates
28
+ Requires-Dist: Jinja2>=3.1; extra == "templates"
29
+ Provides-Extra: all
30
+ Requires-Dist: PyJWT>=2.8; extra == "all"
31
+ Requires-Dist: Jinja2>=3.1; extra == "all"
32
+ Provides-Extra: dev
33
+ Requires-Dist: pytest>=7.4; extra == "dev"
34
+ Requires-Dist: pytest-asyncio>=0.23; extra == "dev"
35
+ Requires-Dist: PyJWT>=2.8; extra == "dev"
36
+ Requires-Dist: Jinja2>=3.1; extra == "dev"
37
+
38
+ <p align="center">
39
+ <img src="logo.png" alt="Fluxium" width="220">
40
+ </p>
41
+
42
+ <h1 align="center">Fluxium</h1>
43
+
44
+ <p align="center">
45
+ An async Python web framework written from scratch.<br>
46
+ No Starlette. No Pydantic. No Uvicorn. Just Python.
47
+ </p>
48
+
49
+ <p align="center">
50
+ <a href="https://pypi.org/project/fluxium"><img src="https://img.shields.io/pypi/v/fluxium?color=1a1a1a&style=flat-square" alt="PyPI"></a>
51
+ <a href="https://github.com/sidx0/fluxium/actions"><img src="https://github.com/sidx0/fluxium/actions/workflows/tests.yml/badge.svg" alt="Tests"></a>
52
+ <img src="https://img.shields.io/badge/python-3.10+-1a1a1a?style=flat-square" alt="Python">
53
+ <img src="https://img.shields.io/badge/dependencies-zero-d4a017?style=flat-square" alt="Zero dependencies">
54
+ <img src="https://img.shields.io/badge/license-MIT-1a1a1a?style=flat-square" alt="MIT">
55
+ </p>
56
+
57
+ ---
58
+
59
+ Fluxium implements the entire HTTP stack in pure Python: the parser, header container, connection pool, router, middleware pipeline, dependency injection engine, ORM, authentication, WebSocket support, background task queue, and Prometheus metrics — all without a single mandatory third-party dependency.
60
+
61
+ It started as an experiment to understand what a web framework actually does underneath. The result is fast, readable at every layer, and ships more built-in functionality than most frameworks that rely on an ecosystem of external packages.
62
+
63
+ ```python
64
+ from flux import Flux
65
+
66
+ app = Flux()
67
+
68
+ @app.get("/")
69
+ async def index():
70
+ return {"message": "Hello from Fluxium"}
71
+
72
+ app.run(port=8000)
73
+ ```
74
+
75
+ ```bash
76
+ pip install fluxium
77
+ fluxium new myproject
78
+ cd myproject && python main.py
79
+ ```
80
+
81
+ ---
82
+
83
+ ## Design
84
+
85
+ Most Python frameworks are layers on top of other layers. FastAPI wraps Starlette. Starlette wraps anyio and h11. The code that actually moves bytes around lives several packages away from the thing you called `pip install` on.
86
+
87
+ Fluxium owns the whole stack. The HTTP parser uses `memoryview` slices to avoid copying bytes during header parsing. The router compiles route patterns into named-group regexes at registration time and caches matches in a dictionary. The middleware pipeline is built as a flat chain of closures rather than a recursive call stack. The in-process loopback client calls the app's dispatch function directly, skipping TCP and serialisation entirely.
88
+
89
+ Everything has a reason. Everything is readable.
90
+
91
+ ---
92
+
93
+ ## Performance
94
+
95
+ Benchmarks run in-process on a single core. No real TCP.
96
+
97
+ | Operation | Throughput | Mean latency |
98
+ |---|---|---|
99
+ | HTTP parse, GET | 140,026 / sec | 7.1 µs |
100
+ | HTTP parse, POST + JSON body | 124,527 / sec | 8.0 µs |
101
+ | Route match, warm cache | 986,564 / sec | 1.0 µs |
102
+ | JSONResponse build and encode | 222,480 / sec | 4.5 µs |
103
+ | Full in-process dispatch | 39,171 / sec | 25.5 µs |
104
+
105
+ Compared to Flask on the same in-process test harness:
106
+
107
+ | Metric | Flask | Fluxium |
108
+ |---|---|---|
109
+ | GET dispatch | 5,831 / sec | 70,142 / sec |
110
+ | URL routing | 206,654 / sec | 6,367,537 / sec |
111
+ | Memory per request | 12 KB | 4 KB |
112
+ | Import time | 255 ms | 16 ms |
113
+
114
+ The gap comes from abstraction count, not optimization tricks. Flask builds a full Werkzeug request context on every request. Fluxium wraps a parsed bytearray.
115
+
116
+ ```bash
117
+ python -m flux benchmark
118
+ ```
119
+
120
+ ---
121
+
122
+ ## Installation
123
+
124
+ ```bash
125
+ pip install fluxium
126
+ ```
127
+
128
+ Optional extras:
129
+
130
+ ```bash
131
+ pip install "fluxium[jwt]" # PyJWT for token signing
132
+ pip install "fluxium[templates]" # Jinja2 for template rendering
133
+ pip install "fluxium[all]" # both
134
+ ```
135
+
136
+ Neither extra is required. JWT falls back to stdlib HMAC-SHA256. Templates fall back to a built-in engine.
137
+
138
+ ---
139
+
140
+ ## Features
141
+
142
+ ### Core engine
143
+
144
+ - HTTP/1.1 parser with zero-copy header parsing via `memoryview`
145
+ - Compiled regex router with typed path parameters — `{id:int}`, `{slug:str}`, `{uid:uuid}`, `{file:path}`
146
+ - Route match cache — warm lookups at roughly one million per second
147
+ - Non-recursive async middleware pipeline, safe at any depth
148
+ - Type-hint driven dependency injection with per-request scope
149
+ - Schema auto-injection — body is parsed and validated before the handler runs
150
+ - Async connection pool with keep-alive and idle reaping
151
+ - In-process loopback client — same-process calls skip TCP entirely
152
+
153
+ ### Full-stack layers
154
+
155
+ Every layer runs on Python's standard library. Optional dependencies improve but never block.
156
+
157
+ | Layer | Description |
158
+ |---|---|
159
+ | `flux.orm` | Async SQLite ORM. Model, QuerySet, auto-migrations, thread-safe transactions. |
160
+ | `flux.auth` | JWT tokens, PBKDF2 password hashing, `@requires_auth`, `@requires_role`. |
161
+ | `flux.schema` | Validation with type coercion, constraints, mutable-default safety, 422 auto-response. |
162
+ | `flux.openapi` | Auto-generated OpenAPI 3.0 spec. Swagger UI at `/docs`, ReDoc at `/redoc`. |
163
+ | `flux.websocket` | RFC 6455 WebSocket with full fragmented-frame reassembly. |
164
+ | `flux.tasks` | Async priority task queue with configurable retry and exponential backoff. |
165
+ | `flux.observability` | Prometheus-compatible counters, histograms, structured JSON logging. |
166
+ | `flux.config` | `Settings` class that reads from environment variables and `.env` files with type coercion. |
167
+ | `flux.security` | Token-bucket rate limiter, CSRF protection, security headers, HTML sanitizer. |
168
+ | `flux.templates` | Jinja2 integration with a built-in fallback engine. |
169
+ | `flux.plugins` | Plugin lifecycle — `on_install`, `on_startup`, `on_shutdown`. |
170
+
171
+ ---
172
+
173
+ ## Usage
174
+
175
+ ### Path parameters
176
+
177
+ ```python
178
+ @app.get("/users/{id:int}")
179
+ async def get_user(id: int):
180
+ return {"id": id}
181
+
182
+ @app.get("/files/{path:path}")
183
+ async def get_file(path: str):
184
+ return {"path": path}
185
+ ```
186
+
187
+ Supported types: `int`, `float`, `str` (default), `path`, `uuid`. A non-matching value returns 404 — no manual validation needed.
188
+
189
+ ### Request body validation
190
+
191
+ ```python
192
+ from flux.schema import Schema, Field
193
+ from typing import Optional
194
+
195
+ class CreatePost(Schema):
196
+ title: str = Field(min_length=1, max_length=200)
197
+ body: str = Field(default="")
198
+ priority: int = Field(default=1, min_value=1, max_value=5)
199
+ tags: list = Field(default=[])
200
+
201
+ @app.post("/posts")
202
+ async def create_post(data: CreatePost):
203
+ return {"title": data.title, "priority": data.priority}
204
+ ```
205
+
206
+ If validation fails the handler is not called. The client receives a structured 422 response listing every field that failed and why.
207
+
208
+ ### Authentication
209
+
210
+ ```python
211
+ from flux.auth import AuthConfig, AuthUser, requires_auth, requires_role
212
+
213
+ app.auth = AuthConfig(secret="your-secret-key", token_ttl=86400)
214
+
215
+ @app.post("/login")
216
+ async def login(request):
217
+ data = request.json()
218
+ user = await User.filter(username=data["username"]).first()
219
+ if not user or not verify_password(data["password"], user.password_hash):
220
+ from flux.server.response import ErrorResponse
221
+ return ErrorResponse(401, "Invalid credentials")
222
+ token = app.auth.issue_token(user.id, roles=[user.role], username=user.username)
223
+ return {"token": token}
224
+
225
+ @app.get("/me")
226
+ @requires_auth
227
+ async def me(user: AuthUser):
228
+ return {"id": user.id, "username": user.username}
229
+
230
+ @app.delete("/admin/users/{id:int}")
231
+ @requires_role("admin")
232
+ async def delete_user(id: int, user: AuthUser):
233
+ await User.filter(id=id).delete()
234
+ return None
235
+ ```
236
+
237
+ ### Database
238
+
239
+ ```python
240
+ from flux.orm import Database, Model, Integer, String, Boolean, auto_migrate
241
+
242
+ db = Database("sqlite:///app.db")
243
+
244
+ class Post(Model):
245
+ id = Integer(primary_key=True)
246
+ title = String(nullable=False)
247
+ status = String(default="draft")
248
+ visible = Boolean(default=True)
249
+
250
+ Post.bind(db)
251
+
252
+ @app.on_startup
253
+ async def startup():
254
+ await auto_migrate(Post)
255
+ ```
256
+
257
+ ```python
258
+ post = await Post.create(title="First post")
259
+ posts = await Post.filter(status="draft").order_by("-id").limit(20).all()
260
+ count = await Post.all().count()
261
+
262
+ await Post.filter(id=post.id).update(status="published")
263
+ await post.delete()
264
+
265
+ async with db.transaction():
266
+ await Account.filter(id=from_id).update(balance=new_balance_from)
267
+ await Account.filter(id=to_id).update(balance=new_balance_to)
268
+ ```
269
+
270
+ ### Background tasks
271
+
272
+ ```python
273
+ from flux.tasks import TaskQueue
274
+
275
+ tq = TaskQueue(workers=4)
276
+ app.di.register(TaskQueue, lambda: tq)
277
+
278
+ @app.on_startup
279
+ async def startup():
280
+ await tq.start()
281
+
282
+ @app.on_shutdown
283
+ async def shutdown():
284
+ await tq.stop(wait=True)
285
+
286
+ @app.post("/register")
287
+ async def register(data: RegisterInput, tq: TaskQueue):
288
+ user = await User.create(...)
289
+ await tq.enqueue(send_welcome_email, user.email)
290
+ return JSONResponse(user.to_dict(), status_code=201)
291
+ ```
292
+
293
+ ### WebSocket
294
+
295
+ ```python
296
+ from flux.websocket import WebSocket, WebSocketDisconnect
297
+
298
+ @app.websocket("/ws")
299
+ async def handler(ws: WebSocket):
300
+ await ws.accept()
301
+ try:
302
+ while True:
303
+ message = await ws.receive_text()
304
+ await ws.send_json({"echo": message})
305
+ except WebSocketDisconnect:
306
+ pass
307
+ ```
308
+
309
+ ### Full application setup
310
+
311
+ ```python
312
+ from flux import Flux
313
+ from flux.auth import AuthConfig
314
+ from flux.plugins import CORSPlugin
315
+ from flux.observability import observability_middleware, mount_metrics
316
+ from flux.security import RateLimiter, security_headers_middleware
317
+
318
+ app = Flux(title="My API", version="1.0.0")
319
+ app.auth = AuthConfig(secret="change-in-production")
320
+
321
+ app.install(CORSPlugin(allow_origins="*"))
322
+ app.add_middleware(observability_middleware)
323
+ app.add_middleware(RateLimiter(requests_per_second=100))
324
+ app.add_middleware(security_headers_middleware)
325
+ mount_metrics(app)
326
+ app.mount_docs()
327
+
328
+ app.run(port=8000)
329
+ ```
330
+
331
+ ---
332
+
333
+ ## CLI
334
+
335
+ ```bash
336
+ fluxium new myapp # scaffold a complete project
337
+ fluxium run myapp:app # start the development server
338
+ fluxium run myapp:app --reload # with hot reload on file changes
339
+ fluxium routes myapp:app # print all registered routes
340
+ fluxium version
341
+ ```
342
+
343
+ `flux` works as an alias for all commands.
344
+
345
+ ---
346
+
347
+ ## Project layout
348
+
349
+ ```
350
+ fluxium/
351
+ flux/
352
+ core/ HTTP parser, headers, connection pool
353
+ server/ Router, middleware, DI, request, response
354
+ client/ Async HTTP client and loopback
355
+ orm/ SQLite ORM
356
+ auth/ JWT, password hashing, RBAC
357
+ schema/ Validation engine
358
+ openapi/ OpenAPI spec and UI
359
+ websocket/ RFC 6455 implementation
360
+ tasks/ Background task queue
361
+ observability/ Prometheus metrics and structured logging
362
+ config/ Environment-based configuration
363
+ security/ Rate limiting, CSRF, security headers
364
+ templates/ Template rendering
365
+ plugins/ Plugin lifecycle
366
+ examples/
367
+ example_app.py Minimal working example
368
+ fullstack_app.py All layers in one file
369
+ taskflow_demo.py Complete task manager with browser UI
370
+ tests/
371
+ docs/
372
+ architecture.md
373
+ getting_started.md
374
+ internals.md
375
+ ```
376
+
377
+ ---
378
+
379
+ ## Documentation
380
+
381
+ - [Getting Started](docs/getting_started.md)
382
+ - [Architecture](docs/architecture.md)
383
+ - [Internals](docs/internals.md)
384
+
385
+ ---
386
+
387
+ ## Requirements
388
+
389
+ - Python 3.10 or later
390
+ - No mandatory dependencies
391
+
392
+ ---
393
+
394
+ ## Contributing
395
+
396
+ See [CONTRIBUTING.md](CONTRIBUTING.md).
397
+
398
+ ---
399
+
400
+ ## License
401
+
402
+ MIT — see [LICENSE](LICENSE).
403
+
404
+ ---
405
+
406
+ <p align="center">
407
+ Built by <a href="https://github.com/sidx0">Siddhant B</a>
408
+ </p>