neutron-framework 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 (102) hide show
  1. neutron_framework-0.1.0/.gitignore +240 -0
  2. neutron_framework-0.1.0/LICENSE +21 -0
  3. neutron_framework-0.1.0/PKG-INFO +144 -0
  4. neutron_framework-0.1.0/README.md +101 -0
  5. neutron_framework-0.1.0/benchmarks/.gitignore +8 -0
  6. neutron_framework-0.1.0/benchmarks/README.md +134 -0
  7. neutron_framework-0.1.0/benchmarks/bench_apps/__init__.py +0 -0
  8. neutron_framework-0.1.0/benchmarks/bench_apps/common.py +104 -0
  9. neutron_framework-0.1.0/benchmarks/bench_apps/fastapi_app.py +74 -0
  10. neutron_framework-0.1.0/benchmarks/bench_apps/litestar_app.py +106 -0
  11. neutron_framework-0.1.0/benchmarks/bench_apps/neutron_app.py +99 -0
  12. neutron_framework-0.1.0/benchmarks/bench_apps/starlette_app.py +79 -0
  13. neutron_framework-0.1.0/benchmarks/client.mjs +53 -0
  14. neutron_framework-0.1.0/benchmarks/measure_noise.py +172 -0
  15. neutron_framework-0.1.0/benchmarks/requirements-bench.txt +59 -0
  16. neutron_framework-0.1.0/benchmarks/run_bench.py +563 -0
  17. neutron_framework-0.1.0/neutron/__init__.py +72 -0
  18. neutron_framework-0.1.0/neutron/__main__.py +5 -0
  19. neutron_framework-0.1.0/neutron/ai/__init__.py +39 -0
  20. neutron_framework-0.1.0/neutron/ai/agent.py +205 -0
  21. neutron_framework-0.1.0/neutron/ai/mcp.py +299 -0
  22. neutron_framework-0.1.0/neutron/ai/memory.py +202 -0
  23. neutron_framework-0.1.0/neutron/ai/providers.py +443 -0
  24. neutron_framework-0.1.0/neutron/ai/rag.py +212 -0
  25. neutron_framework-0.1.0/neutron/ai/structured.py +75 -0
  26. neutron_framework-0.1.0/neutron/ai/tools.py +146 -0
  27. neutron_framework-0.1.0/neutron/ai/workflow.py +187 -0
  28. neutron_framework-0.1.0/neutron/app.py +574 -0
  29. neutron_framework-0.1.0/neutron/auth/__init__.py +37 -0
  30. neutron_framework-0.1.0/neutron/auth/apikey.py +116 -0
  31. neutron_framework-0.1.0/neutron/auth/csrf.py +243 -0
  32. neutron_framework-0.1.0/neutron/auth/jwt.py +268 -0
  33. neutron_framework-0.1.0/neutron/auth/oauth.py +568 -0
  34. neutron_framework-0.1.0/neutron/auth/password.py +106 -0
  35. neutron_framework-0.1.0/neutron/auth/rbac.py +128 -0
  36. neutron_framework-0.1.0/neutron/auth/session.py +192 -0
  37. neutron_framework-0.1.0/neutron/cache/__init__.py +9 -0
  38. neutron_framework-0.1.0/neutron/cache/http.py +221 -0
  39. neutron_framework-0.1.0/neutron/cache/tiered.py +139 -0
  40. neutron_framework-0.1.0/neutron/cli.py +384 -0
  41. neutron_framework-0.1.0/neutron/config.py +88 -0
  42. neutron_framework-0.1.0/neutron/depends.py +30 -0
  43. neutron_framework-0.1.0/neutron/error.py +137 -0
  44. neutron_framework-0.1.0/neutron/handler.py +426 -0
  45. neutron_framework-0.1.0/neutron/jobs/__init__.py +9 -0
  46. neutron_framework-0.1.0/neutron/jobs/queue.py +626 -0
  47. neutron_framework-0.1.0/neutron/middleware.py +548 -0
  48. neutron_framework-0.1.0/neutron/nucleus/__init__.py +46 -0
  49. neutron_framework-0.1.0/neutron/nucleus/_exec.py +58 -0
  50. neutron_framework-0.1.0/neutron/nucleus/blob.py +165 -0
  51. neutron_framework-0.1.0/neutron/nucleus/cdc.py +81 -0
  52. neutron_framework-0.1.0/neutron/nucleus/client.py +229 -0
  53. neutron_framework-0.1.0/neutron/nucleus/columnar.py +82 -0
  54. neutron_framework-0.1.0/neutron/nucleus/datalog.py +73 -0
  55. neutron_framework-0.1.0/neutron/nucleus/document.py +307 -0
  56. neutron_framework-0.1.0/neutron/nucleus/fts.py +111 -0
  57. neutron_framework-0.1.0/neutron/nucleus/geo.py +220 -0
  58. neutron_framework-0.1.0/neutron/nucleus/graph.py +184 -0
  59. neutron_framework-0.1.0/neutron/nucleus/kv.py +304 -0
  60. neutron_framework-0.1.0/neutron/nucleus/migrate.py +172 -0
  61. neutron_framework-0.1.0/neutron/nucleus/pubsub.py +115 -0
  62. neutron_framework-0.1.0/neutron/nucleus/retry.py +137 -0
  63. neutron_framework-0.1.0/neutron/nucleus/sql.py +71 -0
  64. neutron_framework-0.1.0/neutron/nucleus/streams.py +171 -0
  65. neutron_framework-0.1.0/neutron/nucleus/timeseries.py +179 -0
  66. neutron_framework-0.1.0/neutron/nucleus/tx.py +105 -0
  67. neutron_framework-0.1.0/neutron/nucleus/vector.py +179 -0
  68. neutron_framework-0.1.0/neutron/openapi.py +371 -0
  69. neutron_framework-0.1.0/neutron/realtime/__init__.py +10 -0
  70. neutron_framework-0.1.0/neutron/realtime/sse.py +125 -0
  71. neutron_framework-0.1.0/neutron/realtime/websocket.py +136 -0
  72. neutron_framework-0.1.0/neutron/response.py +81 -0
  73. neutron_framework-0.1.0/neutron/router.py +237 -0
  74. neutron_framework-0.1.0/neutron/test/__init__.py +128 -0
  75. neutron_framework-0.1.0/pyproject.toml +93 -0
  76. neutron_framework-0.1.0/tests/__init__.py +0 -0
  77. neutron_framework-0.1.0/tests/conftest.py +46 -0
  78. neutron_framework-0.1.0/tests/test_ai.py +1173 -0
  79. neutron_framework-0.1.0/tests/test_app.py +308 -0
  80. neutron_framework-0.1.0/tests/test_auth.py +534 -0
  81. neutron_framework-0.1.0/tests/test_cache.py +364 -0
  82. neutron_framework-0.1.0/tests/test_cli.py +197 -0
  83. neutron_framework-0.1.0/tests/test_config.py +119 -0
  84. neutron_framework-0.1.0/tests/test_depends.py +98 -0
  85. neutron_framework-0.1.0/tests/test_error.py +78 -0
  86. neutron_framework-0.1.0/tests/test_handler.py +134 -0
  87. neutron_framework-0.1.0/tests/test_health_contract.py +40 -0
  88. neutron_framework-0.1.0/tests/test_jobs.py +188 -0
  89. neutron_framework-0.1.0/tests/test_jobs_durable.py +283 -0
  90. neutron_framework-0.1.0/tests/test_middleware.py +614 -0
  91. neutron_framework-0.1.0/tests/test_migrate.py +117 -0
  92. neutron_framework-0.1.0/tests/test_migrate_live.py +70 -0
  93. neutron_framework-0.1.0/tests/test_nucleus_live.py +82 -0
  94. neutron_framework-0.1.0/tests/test_nucleus_models.py +1414 -0
  95. neutron_framework-0.1.0/tests/test_nucleus_retry.py +133 -0
  96. neutron_framework-0.1.0/tests/test_oauth.py +593 -0
  97. neutron_framework-0.1.0/tests/test_openapi.py +352 -0
  98. neutron_framework-0.1.0/tests/test_realtime.py +137 -0
  99. neutron_framework-0.1.0/tests/test_response.py +171 -0
  100. neutron_framework-0.1.0/tests/test_router.py +130 -0
  101. neutron_framework-0.1.0/tests/test_shutdown.py +265 -0
  102. neutron_framework-0.1.0/tests/test_sync_test_client.py +91 -0
@@ -0,0 +1,240 @@
1
+ # Build artifacts
2
+ target/
3
+ dist/
4
+ build/
5
+ .next/
6
+ .svelte-kit/
7
+ .solid/
8
+ out/
9
+
10
+ # Dependencies
11
+ node_modules/
12
+ .pnpm-store/
13
+
14
+ # Environment & secrets
15
+ .env
16
+ .env.*
17
+ !.env.example
18
+
19
+ # IDE / OS
20
+ .DS_Store
21
+ Thumbs.db
22
+ *.swp
23
+ *.swo
24
+ .vscode/settings.json
25
+ .idea/
26
+
27
+ # Logs
28
+ *.log
29
+ server_err.log
30
+
31
+ # Temporary files
32
+ *.tmp
33
+ *.bak
34
+
35
+ # Compiled Mojo outputs
36
+ /tmp/test_*
37
+
38
+ # Archive — planning docs & research
39
+ archive/
40
+ **/ARCHITECTURE.md
41
+ **/PLAN.md
42
+ **/STATUS.md
43
+ **/TODO-NEXT.md
44
+ # Exception: the framework-excellence program's master plan is a tracked deliverable.
45
+ !docs/framework-excellence/PLAN.md
46
+ **/EXECUTION.md
47
+ **/CHECKLIST.md
48
+ **/NEUTRON_FINISH_CHECKLIST.md
49
+ **/BENCHMARK_UPDATE.md
50
+ **/competitive-analysis*.md
51
+ **/PARITY-COMPARISON.md
52
+ **/COMPETITOR-GAPS.md
53
+ **/AUDIT-REPORT.md
54
+ **/ai-ml-database-research.md
55
+ **/SPRINT-*.md
56
+ **/SPRINTS-*.md
57
+ **/IMPLEMENTATION-COMPLETE.md
58
+ **/IMPLEMENTATION_PLAN.md
59
+ **/COMPLETION_REPORT.md
60
+ **/ENGINEERING_EFFORT_ANALYSIS.md
61
+ **/PROJECT_STATUS_*.md
62
+ **/ONE_WEEK_RELEASE_PLAN.md
63
+ **/TECHNICAL_DEEP_DIVE.md
64
+ **/FULL_STACK_ANALYSIS.md
65
+ **/MULTI_LANGUAGE_CLIENT_ANALYSIS.md
66
+ **/NUCLEUS_CLIENT_SPEC.md
67
+ **/ORM_CLIENT_STUDIO_DECISION.md
68
+ **/NEUTRON-VS-REMIX.md
69
+ **/NEUTRON-FEATURE-AUDIT.md
70
+ **/ECOSYSTEM_*.md
71
+ **/DOCS_API_ECOSYSTEM.md
72
+ **/rust-PLAN.md
73
+ **/DEFER-EXAMPLE.md
74
+ **/URGENT-NOTE.md
75
+ **/QUICK-REFERENCE.md
76
+ **/ASTRO6-NEXTJS16-FEATURES.md
77
+ **/SVELTEKIT-SOLIDJS-FEATURES.md
78
+ **/REMIX-FEATURES-TO-ADOPT.md
79
+
80
+ # Vercel parity / product strategy research (local only)
81
+ /docs/VERCEL_PARITY_BACKLOG.md
82
+ /docs/design/
83
+
84
+ # Planning & audit docs
85
+ **/NUCLEUS-AUDIT.md
86
+ **/NUCLEUS-ROADMAP.md
87
+ LAUNCH_PROMPTS.md
88
+
89
+ # Benchmark & debug artifacts
90
+ **/benchmark_results.json
91
+ **/compete_results.json
92
+ **/clippy_out.txt
93
+ **/clippy_remain.txt
94
+
95
+ # Deprecated
96
+ mobile-preview/
97
+
98
+ # Third-party benchmark apps are tracked like every other subject app — an
99
+ # ignored subject is a benchmark row nobody else can reproduce. Their own
100
+ # .gitignore files keep node_modules and build output out.
101
+
102
+ # Observe (separate project)
103
+ typescript/apps/observe/
104
+
105
+ # Zig build artifacts
106
+ zig/.zig-cache/
107
+ zig/zig-out/
108
+
109
+ # Mojo validation reports, research, and internal specs
110
+ mojo/reports/
111
+ mojo/study/
112
+ mojo/specs/
113
+
114
+ # NOT ignored: typescript/.turbo-ls-normalized.json. It looks like turbo cache
115
+ # and was filed here as "Turbo internal", but it is the authored BASELINE that
116
+ # `pnpm run ci:workspace` compares the workspace graph against. Ignoring it made
117
+ # the check fail on every CI run with "Missing snapshot file" — a gate that can
118
+ # only pass on the laptop that generated it is not a gate.
119
+
120
+ # Scratch / dev tooling files
121
+ **/do_edit.py
122
+ **/edit_distributed.py
123
+ **/coord_lines.py
124
+ **/coord_methods.rs
125
+
126
+ # Rust framework (rust/) — the SOURCE is tracked. Only the cargo build output is
127
+ # ignored. (Earlier this was `/rust/` under the mistaken belief the source lived
128
+ # in `rs/`; `rs/` was renamed to `rust/` in 6079213, so `/rust/` was silently
129
+ # excluding the entire framework from version control. Fixed to ignore only target/.)
130
+ /rust/target/
131
+
132
+ # Site build output (source is tracked, dist is not)
133
+ typescript/apps/site/dist/
134
+ typescript/apps/site/.neutron/
135
+ # Same for the playground: .neutron/runtime/entry.node.ts is emitted by
136
+ # `neutron-ts build`, so a tracked copy goes stale the moment the codegen
137
+ # changes and dirties the tree on every build.
138
+ typescript/apps/playground/.neutron/
139
+
140
+ # Claude internal
141
+ .claude/
142
+
143
+ # Python
144
+ __pycache__/
145
+ *.pyc
146
+ *.pyo
147
+ .venv/
148
+ venv/
149
+
150
+ # Rust — track the framework + engine lockfiles for reproducible builds.
151
+ # (The `!rs/Cargo.lock` exception was stale: `rs/` was renamed to `rust/` in
152
+ # 6079213, so the framework lockfile silently went untracked.)
153
+ Cargo.lock
154
+ !rust/Cargo.lock
155
+ !nucleus/Cargo.lock
156
+ # Database files
157
+ *.db
158
+
159
+ # Rust build artifacts (added after filter-repo cleanup of history)
160
+ **/target/
161
+ **/debug/
162
+ *.rlib
163
+ *.rmeta
164
+ *.rcgu.o
165
+
166
+ # ---------------------------------------------------------------------------
167
+ # Working docs, notes and context — local only, never committed
168
+ # ---------------------------------------------------------------------------
169
+ # Everything above this block is a DENYLIST OF EXACT FILENAMES, added reactively
170
+ # one name at a time. That shape cannot hold: a working note is tracked by
171
+ # default until somebody remembers to add its exact name here, and the rule only
172
+ # ever arrives after the file already exists. It also does nothing to a file that
173
+ # is already tracked -- `.gitignore` does not untrack -- which is how
174
+ # `nucleus/PARITY-COMPARISON.md` sat public on the GitHub mirror from 2026-07-20
175
+ # while both the ignore list and the document's own first line called it
176
+ # local-only.
177
+ #
178
+ # The patterns below are CONVENTIONS instead: name a note in any of these shapes
179
+ # and it is ignored the moment it is created, without an edit here. Prefer them
180
+ # for anything new.
181
+ #
182
+ # `.github/scripts/check_ignored_not_tracked.py` enforces the whole file: it
183
+ # fails if any tracked path matches an ignore rule, so intent and reality cannot
184
+ # drift apart again silently.
185
+
186
+ # Private planning trees. `_internal/` is its own private git repo (Forgejo
187
+ # `Tyler/neutron-internal`) — gitignored here so the public repo never sees it,
188
+ # versioned there so it is not single-copy on one laptop.
189
+ /_internal/
190
+ **/_internal/
191
+ **/_notes/
192
+ **/_scratch/
193
+ **/.notes/
194
+
195
+ # Note/context/session filename conventions
196
+ **/INTERNAL.md
197
+ **/NOTES.md
198
+ **/*_NOTES.md
199
+ **/*-NOTES.md
200
+ **/NOTES-*.md
201
+ **/SESSION_*.md
202
+ **/SESSION-*.md
203
+ **/HANDOFF*.md
204
+ **/*_HANDOFF.md
205
+ **/SCRATCH*.md
206
+ **/WIP*.md
207
+ **/DRAFT*.md
208
+ **/TODO.md
209
+ **/TODO-*.md
210
+ **/BRAINSTORM*.md
211
+ **/RESEARCH-*.md
212
+ **/*-RESEARCH.md
213
+ **/POSTMORTEM*.md
214
+ **/RETRO*.md
215
+ **/DECISIONS.md
216
+ **/OPEN_WORK.md
217
+ **/PROGRESS.md
218
+ **/ORCHESTRATION.md
219
+ **/GROUND_TRUTH.md
220
+
221
+ # The universal escape hatch: any file may be made local-only by adding `.local`
222
+ # before its extension. Use this instead of extending the denylist above.
223
+ **/*.local.md
224
+ **/*.local.txt
225
+ **/*.local.json
226
+ **/*.local.*
227
+
228
+ uv.lock
229
+
230
+ # Conformance executor build output. `go build ./...` in the executor directory
231
+ # drops a binary named after its module; it is a 10 MB artifact of running the
232
+ # suite, not part of it.
233
+ conformance/live/executors/go/neutron-live-conformance-go
234
+ conformance/live/executors/rust/target/
235
+
236
+ # Zig conformance executor build output.
237
+ conformance/live/executors/zig/.zig-cache/
238
+ conformance/live/executors/zig/zig-out/
239
+ uuid
240
+ status
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Neutron
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,144 @@
1
+ Metadata-Version: 2.5
2
+ Name: neutron-framework
3
+ Version: 0.1.0
4
+ Summary: The AI application development framework for Python
5
+ Project-URL: Homepage, https://neutron.build/
6
+ Project-URL: Documentation, https://neutron.build/docs/python/overview
7
+ Project-URL: Repository, https://github.com/neutron-build/neutron
8
+ Project-URL: Issues, https://github.com/neutron-build/neutron/issues
9
+ License-Expression: MIT
10
+ License-File: LICENSE
11
+ Requires-Python: >=3.11
12
+ Requires-Dist: asyncpg>=0.29.0
13
+ Requires-Dist: cyclopts>=3.0
14
+ Requires-Dist: httpx>=0.27.0
15
+ Requires-Dist: pydantic-settings>=2.0
16
+ Requires-Dist: pydantic>=2.0
17
+ Requires-Dist: starlette>=0.38.0
18
+ Requires-Dist: structlog>=24.0
19
+ Requires-Dist: uvicorn[standard]>=0.30.0
20
+ Provides-Extra: ai
21
+ Requires-Dist: httpx>=0.27.0; extra == 'ai'
22
+ Provides-Extra: all
23
+ Requires-Dist: argon2-cffi>=23.1.0; extra == 'all'
24
+ Requires-Dist: granian>=2.0.0; extra == 'all'
25
+ Requires-Dist: httpx>=0.27.0; extra == 'all'
26
+ Requires-Dist: pyjwt[crypto]>=2.8.0; extra == 'all'
27
+ Requires-Dist: rich>=13.0; extra == 'all'
28
+ Provides-Extra: crypto
29
+ Requires-Dist: argon2-cffi>=23.1.0; extra == 'crypto'
30
+ Requires-Dist: pyjwt[crypto]>=2.8.0; extra == 'crypto'
31
+ Provides-Extra: granian
32
+ Requires-Dist: granian>=2.0.0; extra == 'granian'
33
+ Provides-Extra: rich
34
+ Requires-Dist: rich>=13.0; extra == 'rich'
35
+ Provides-Extra: test
36
+ Requires-Dist: argon2-cffi>=23.1.0; extra == 'test'
37
+ Requires-Dist: editables>=0.5; extra == 'test'
38
+ Requires-Dist: httpx>=0.27.0; extra == 'test'
39
+ Requires-Dist: pyjwt[crypto]>=2.8.0; extra == 'test'
40
+ Requires-Dist: pytest-asyncio>=0.24; extra == 'test'
41
+ Requires-Dist: pytest>=8.0; extra == 'test'
42
+ Description-Content-Type: text/markdown
43
+
44
+ # neutron-framework
45
+
46
+ The AI application development framework for Python — Starlette underneath,
47
+ Pydantic throughout, with a first-class client for [Nucleus](https://github.com/neutron-build/neutron/tree/main/nucleus), the
48
+ multi-model database the rest of Neutron is built on.
49
+
50
+ ```bash
51
+ pip install neutron-framework
52
+ ```
53
+
54
+ > The distribution is **`neutron-framework`**, not `neutron` — that name on PyPI
55
+ > belongs to OpenStack's networking service.
56
+
57
+ ## A first app
58
+
59
+ ```python
60
+ from pydantic import BaseModel
61
+ from neutron import App, Router
62
+
63
+ app = App(title="My API", version="1.0.0")
64
+ router = Router()
65
+
66
+ class User(BaseModel):
67
+ id: int
68
+ name: str
69
+ email: str
70
+
71
+ @router.get("/users/{user_id}")
72
+ async def get_user(user_id: int) -> User:
73
+ return await app.db.sql.query_one(
74
+ User, "SELECT * FROM users WHERE id = $1", user_id
75
+ )
76
+
77
+ app.include_router(router)
78
+ ```
79
+
80
+ Return a Pydantic model and you get validation, serialisation and an OpenAPI
81
+ 3.1 schema from the same declaration. `GET /health`, `GET /openapi.json` and
82
+ `GET /docs` are mounted for you.
83
+
84
+ ## What ships
85
+
86
+ | Area | Module |
87
+ |---|---|
88
+ | Routing, handlers, dependency injection | `neutron/router.py`, `handler.py`, `depends.py` |
89
+ | Middleware (the contract's 10-layer order) | `neutron/middleware.py`, `default_stack()` |
90
+ | Errors as RFC 7807 problem+json | `neutron/error.py` |
91
+ | OpenAPI 3.1 generation | `neutron/openapi.py` |
92
+ | Nucleus client — all 14 data models | `neutron/nucleus/` |
93
+ | AI: providers, agents, RAG, MCP | `neutron/ai/` |
94
+ | Auth, cache, jobs, realtime | `neutron/auth/`, `cache/`, `jobs/`, `realtime/` |
95
+ | CLI (`python -m neutron`) | `neutron/cli.py` |
96
+ | Test helpers | `neutron/test/` |
97
+
98
+ ## Extras
99
+
100
+ ```bash
101
+ pip install "neutron-framework[ai]" # AI providers, agents, RAG
102
+ pip install "neutron-framework[crypto]" # password hashing
103
+ pip install "neutron-framework[granian]" # the Granian server
104
+ pip install "neutron-framework[rich]" # richer CLI output
105
+ pip install "neutron-framework[all]" # everything above
106
+ ```
107
+
108
+ `[test]` is the development extra and is what CI installs.
109
+
110
+ ## Nucleus
111
+
112
+ One pgwire connection reaches every data model; the non-relational models are
113
+ SQL functions rather than separate services or ports.
114
+
115
+ ```python
116
+ from neutron.nucleus import NucleusClient
117
+
118
+ db = await NucleusClient.connect("postgresql://localhost:5432/mydb")
119
+
120
+ await db.kv.set("session:abc", "user-1", ttl=3600)
121
+ await db.vector.search("docs", embedding, k=5)
122
+ await db.document.insert("events", {"kind": "signup"})
123
+ ```
124
+
125
+ Any PostgreSQL client works against Nucleus, so `asyncpg` and `psycopg` remain
126
+ available if you would rather not use this client at all.
127
+
128
+ ## Documentation
129
+
130
+ Published docs — overview, quickstart, routing, middleware, database, realtime,
131
+ deployment — start at **https://neutron.build/docs/python/overview**. The wire-level
132
+ contract every Neutron SDK implements is
133
+ [`FRAMEWORK_CONTRACT.md`](https://github.com/neutron-build/neutron/blob/main/FRAMEWORK_CONTRACT.md); this SDK scores 12/12 on
134
+ its conformance matrix.
135
+
136
+ ## Development
137
+
138
+ ```bash
139
+ pip install -e ".[test]"
140
+ pytest
141
+ ```
142
+
143
+ Live-database tests skip unless `NEUTRON_TEST_DATABASE_URL` points at a running
144
+ Nucleus instance.
@@ -0,0 +1,101 @@
1
+ # neutron-framework
2
+
3
+ The AI application development framework for Python — Starlette underneath,
4
+ Pydantic throughout, with a first-class client for [Nucleus](https://github.com/neutron-build/neutron/tree/main/nucleus), the
5
+ multi-model database the rest of Neutron is built on.
6
+
7
+ ```bash
8
+ pip install neutron-framework
9
+ ```
10
+
11
+ > The distribution is **`neutron-framework`**, not `neutron` — that name on PyPI
12
+ > belongs to OpenStack's networking service.
13
+
14
+ ## A first app
15
+
16
+ ```python
17
+ from pydantic import BaseModel
18
+ from neutron import App, Router
19
+
20
+ app = App(title="My API", version="1.0.0")
21
+ router = Router()
22
+
23
+ class User(BaseModel):
24
+ id: int
25
+ name: str
26
+ email: str
27
+
28
+ @router.get("/users/{user_id}")
29
+ async def get_user(user_id: int) -> User:
30
+ return await app.db.sql.query_one(
31
+ User, "SELECT * FROM users WHERE id = $1", user_id
32
+ )
33
+
34
+ app.include_router(router)
35
+ ```
36
+
37
+ Return a Pydantic model and you get validation, serialisation and an OpenAPI
38
+ 3.1 schema from the same declaration. `GET /health`, `GET /openapi.json` and
39
+ `GET /docs` are mounted for you.
40
+
41
+ ## What ships
42
+
43
+ | Area | Module |
44
+ |---|---|
45
+ | Routing, handlers, dependency injection | `neutron/router.py`, `handler.py`, `depends.py` |
46
+ | Middleware (the contract's 10-layer order) | `neutron/middleware.py`, `default_stack()` |
47
+ | Errors as RFC 7807 problem+json | `neutron/error.py` |
48
+ | OpenAPI 3.1 generation | `neutron/openapi.py` |
49
+ | Nucleus client — all 14 data models | `neutron/nucleus/` |
50
+ | AI: providers, agents, RAG, MCP | `neutron/ai/` |
51
+ | Auth, cache, jobs, realtime | `neutron/auth/`, `cache/`, `jobs/`, `realtime/` |
52
+ | CLI (`python -m neutron`) | `neutron/cli.py` |
53
+ | Test helpers | `neutron/test/` |
54
+
55
+ ## Extras
56
+
57
+ ```bash
58
+ pip install "neutron-framework[ai]" # AI providers, agents, RAG
59
+ pip install "neutron-framework[crypto]" # password hashing
60
+ pip install "neutron-framework[granian]" # the Granian server
61
+ pip install "neutron-framework[rich]" # richer CLI output
62
+ pip install "neutron-framework[all]" # everything above
63
+ ```
64
+
65
+ `[test]` is the development extra and is what CI installs.
66
+
67
+ ## Nucleus
68
+
69
+ One pgwire connection reaches every data model; the non-relational models are
70
+ SQL functions rather than separate services or ports.
71
+
72
+ ```python
73
+ from neutron.nucleus import NucleusClient
74
+
75
+ db = await NucleusClient.connect("postgresql://localhost:5432/mydb")
76
+
77
+ await db.kv.set("session:abc", "user-1", ttl=3600)
78
+ await db.vector.search("docs", embedding, k=5)
79
+ await db.document.insert("events", {"kind": "signup"})
80
+ ```
81
+
82
+ Any PostgreSQL client works against Nucleus, so `asyncpg` and `psycopg` remain
83
+ available if you would rather not use this client at all.
84
+
85
+ ## Documentation
86
+
87
+ Published docs — overview, quickstart, routing, middleware, database, realtime,
88
+ deployment — start at **https://neutron.build/docs/python/overview**. The wire-level
89
+ contract every Neutron SDK implements is
90
+ [`FRAMEWORK_CONTRACT.md`](https://github.com/neutron-build/neutron/blob/main/FRAMEWORK_CONTRACT.md); this SDK scores 12/12 on
91
+ its conformance matrix.
92
+
93
+ ## Development
94
+
95
+ ```bash
96
+ pip install -e ".[test]"
97
+ pytest
98
+ ```
99
+
100
+ Live-database tests skip unless `NEUTRON_TEST_DATABASE_URL` points at a running
101
+ Nucleus instance.
@@ -0,0 +1,8 @@
1
+ # Generated by run_bench.py / measure_noise.py. Machine-specific throughput
2
+ # numbers do not belong in the repository: the reproducible artifact is the
3
+ # harness plus the pinned environment in requirements-bench.txt, not any
4
+ # individual figure measured on one laptop. Committing them is how a number
5
+ # nobody can reproduce ends up quoted.
6
+ results/
7
+ .venv-bench/
8
+ __pycache__/
@@ -0,0 +1,134 @@
1
+ # Python ASGI Benchmark Protocol
2
+
3
+ Measures `neutron-py` against its real peer set — **FastAPI, Starlette,
4
+ Litestar** — on the same eight scenarios the TypeScript harness uses
5
+ (`typescript/benchmarks/run-comparison.mjs`), with the same client
6
+ (autocannon), so the two suites share vocabulary and scenario shapes.
7
+
8
+ ## What it tests
9
+
10
+ - Frameworks (5 rows):
11
+ - `neutron` — `App()` with no user middleware (routing/serialization
12
+ overhead on top of the Starlette it wraps)
13
+ - `neutron-default` — `App(middleware=default_stack())`, the documented
14
+ production posture: a uuid4 request-id plus a structlog event per request
15
+ - `starlette` — bare Starlette, the floor both neutron-py and FastAPI sit on
16
+ - `fastapi` — `FastAPI()` defaults, pydantic-validated body
17
+ - `litestar` — `Litestar()` defaults, pydantic body via DTO
18
+ - Scenarios (exact ports of the TS routes; see `bench_apps/common.py` for the
19
+ provenance of every constant):
20
+ - `static`: `GET /` (constant HTML)
21
+ - `dynamic`: `GET /users/1` (dict lookup + render)
22
+ - `compute`: `GET /compute` (140k-iteration arithmetic loop)
23
+ - `big`: `GET /big` (400 rows rendered per request, ~16 KB HTML)
24
+ - `mutate`: `POST /api/mutate` with `{"seed":13,"repeat":6000}`
25
+ - `login`: `GET /login` (constant HTML)
26
+ - `protected`: `GET /protected` with `Authorization: Bearer valid-token`
27
+ - `session-refresh`: `POST /api/session/refresh` (auth check, body `{}`)
28
+ - Parity probes run against every app before any measurement: status codes,
29
+ byte-identical bodies, content types, and the negative-auth 401 paths.
30
+ `compute` and `mutate` return values are asserted equal to the TypeScript
31
+ implementation's values (JS and Python verified to produce 719963 and
32
+ 258368509 respectively).
33
+
34
+ ## Fairness model
35
+
36
+ - Same server for everyone: one uvicorn worker, `--no-access-log`, default
37
+ uvloop + httptools, app stdout/stderr to DEVNULL.
38
+ - Same client for everyone: autocannon (borrowed read-only from
39
+ `typescript/benchmarks/node_modules`; override with `AUTOCANNON_MODULE`),
40
+ 100 connections, HTTP/1.1, pipelining 1.
41
+ - Frameworks run as shipped: FastAPI and Litestar keep their default
42
+ openapi/docs routes (not measured); `neutron-default`'s per-request logging
43
+ cost is measured and reported as its own row rather than hidden.
44
+ - The TS harness measures SSR frameworks rendering HTML; these are ASGI apps
45
+ doing the same per-route work. In-suite comparisons are apples-to-apples;
46
+ cross-suite (TS vs Python) numbers are directional only.
47
+
48
+ ## Error policy
49
+
50
+ Every run asserts zero socket errors, zero timeouts, and zero non-2xx
51
+ responses. Violations are recorded, excluded from medians, printed, and fail
52
+ the invocation (exit 1). A framework serving 500s fast cannot look like a
53
+ win — this is the exact defect that produced the bad Nucleus numbers.
54
+
55
+ ## Run it
56
+
57
+ ```bash
58
+ # one-time setup (venv lives inside python/benchmarks)
59
+ uv venv benchmarks/.venv-bench --python 3.12
60
+ uv pip install --python benchmarks/.venv-bench/bin/python \
61
+ -e ".[crypto]" fastapi "litestar[standard]" "uvicorn[standard]" httpx editables
62
+ # peer versions are frozen in benchmarks/requirements-bench.txt — a rerun
63
+ # should install from that file, not from latest
64
+
65
+ cd python/benchmarks
66
+ .venv-bench/bin/python run_bench.py # main matrix
67
+ .venv-bench/bin/python measure_noise.py --repeats 6 # noise floor + gate check
68
+ ```
69
+
70
+ If `typescript/benchmarks/node_modules` is absent (it is a borrowed install,
71
+ not a dependency of this suite), point `AUTOCANNON_MODULE` at any autocannon
72
+ 8.x — e.g. `npm install autocannon@8.0.0` in a scratch dir and export
73
+ `AUTOCANNON_MODULE=<dir>/node_modules/autocannon`. The recorded provenance
74
+ follows the override, so the artifact still names the client it used.
75
+
76
+ Tunables (local defaults, NOT the TS CI profile): `PYBENCH_CONNECTIONS`
77
+ (100), `PYBENCH_DURATION` (5), `PYBENCH_WARMUP` (2), `PYBENCH_RUNS` (3),
78
+ `PYBENCH_FRAMEWORKS`, `PYBENCH_SCENARIOS`, `PYBENCH_PORT`.
79
+
80
+ Outputs: `results/run-<ts>.json`, `results/latest.json`,
81
+ `results/noise-<ts>.json` — every file carries a provenance block (machine,
82
+ Python, package versions, client, profile, exclusions). Raw per-run rows are
83
+ kept, not just medians.
84
+
85
+ ## Noise, gates, and honest limits
86
+
87
+ `measure_noise.py` repeats the full matrix with rotated framework order
88
+ (this machine's throughput drifts with warm-up state, so fixed order would
89
+ confound framework with position), computes per-cell medians, and reports the
90
+ worst single-repeat deviation for the neutron rows. That deviation is the
91
+ noise floor. Do not wire a CI regression gate below it. The suggested
92
+ thresholds follow the same derivation as
93
+ `typescript/benchmarks/scripts/measure-gate-noise.mjs`; if the floor is too
94
+ wide for a gate at the current profile, that is the finding — say so, don't
95
+ tune the number.
96
+
97
+ **The floor was measured (2026-08-19, Apple M4 / 10 cores / macOS): no gate
98
+ is possible on this harness on this machine class, so none is wired.**
99
+ Three runs, all 6 repeats of the full matrix:
100
+
101
+ - Quietest attainable window (background load still swung the 1-min loadavg
102
+ from 7 to 35 during the run; a dev laptop is never idle while in use):
103
+ worst single-repeat rps drop on neutron rows **95.4%**, six cells above
104
+ 79%.
105
+ - Contaminated window (a concurrent 4-core `rustc` build; loadavg 8 → 98):
106
+ worst drop **100%** — one neutron/compute repeat measured 0 rps with zero
107
+ errors, a green run indistinguishable from a dead framework.
108
+ - The interrupted 2026-08-18 run (4 repeats, "idle-ish"): worst drop
109
+ **76.8%**.
110
+
111
+ A 10x regression is a 90% rps drop — at or below the green-run floor, so a
112
+ threshold high enough to never fire on a green run can never fire on a real
113
+ regression either. A paired within-repeat ratio (neutron/starlette, which
114
+ load bursts should cancel if anything could) deviates up to 257% from its
115
+ own median, so ratio gates are out too. The suggested-threshold column that
116
+ `measure_noise.py` prints is a derivation, not a recommendation: when it
117
+ says 135%, the answer is "no gate", not "gate at 135%".
118
+
119
+ No competitive figures are publishable from this machine either: framework
120
+ medians differ by less than ~26% on every scenario while single cells swing
121
+ 1.6x–36x across green repeats of the same framework. Revisit only on a
122
+ machine whose background load is controlled (dedicated runner; the noise
123
+ artifacts now record the per-repeat loadavg precisely so contamination is
124
+ visible in the artifact, not inferred afterwards).
125
+
126
+ ## Known caveats
127
+
128
+ - `compute`/`mutate` are GIL-bound pure-Python arithmetic. CPython executes
129
+ these loops ~10x slower than V8 executes the identical TS loops, so those
130
+ two scenarios measure the language runtime, not the framework; the
131
+ framework signal there is small relative to the interpreter cost.
132
+ - Single machine, single worker, loopback. Numbers are not comparable to
133
+ other machines; the reproducible artifact is the harness plus the pinned
134
+ environment, not any individual figure.