edron 0.8.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.
- edron-0.8.0/.gitignore +36 -0
- edron-0.8.0/CHANGELOG.md +99 -0
- edron-0.8.0/LICENSE +21 -0
- edron-0.8.0/PKG-INFO +215 -0
- edron-0.8.0/README.md +164 -0
- edron-0.8.0/pyproject.toml +60 -0
- edron-0.8.0/src/edron/__init__.py +158 -0
- edron-0.8.0/src/edron/_internal.py +68 -0
- edron-0.8.0/src/edron/app.py +1384 -0
- edron-0.8.0/src/edron/cache.py +154 -0
- edron-0.8.0/src/edron/capabilities.py +52 -0
- edron-0.8.0/src/edron/cli/__init__.py +3 -0
- edron-0.8.0/src/edron/cli/main.py +218 -0
- edron-0.8.0/src/edron/composition.py +120 -0
- edron-0.8.0/src/edron/confirm.py +10 -0
- edron-0.8.0/src/edron/data.py +728 -0
- edron-0.8.0/src/edron/dependencies.py +112 -0
- edron-0.8.0/src/edron/deployment.py +776 -0
- edron-0.8.0/src/edron/descriptors.py +259 -0
- edron-0.8.0/src/edron/diagnostics.py +253 -0
- edron-0.8.0/src/edron/downloads.py +14 -0
- edron-0.8.0/src/edron/errors.py +79 -0
- edron-0.8.0/src/edron/jobs.py +90 -0
- edron-0.8.0/src/edron/migrate/__init__.py +21 -0
- edron-0.8.0/src/edron/migrate/analyze.py +62 -0
- edron-0.8.0/src/edron/migrate/cli.py +128 -0
- edron-0.8.0/src/edron/migrate/codemod.py +76 -0
- edron-0.8.0/src/edron/migrate/generate.py +209 -0
- edron-0.8.0/src/edron/migrate/report.py +122 -0
- edron-0.8.0/src/edron/navigation.py +122 -0
- edron-0.8.0/src/edron/outcomes.py +35 -0
- edron-0.8.0/src/edron/page.py +887 -0
- edron-0.8.0/src/edron/promotion.py +139 -0
- edron-0.8.0/src/edron/py.typed +0 -0
- edron-0.8.0/src/edron/scaffolds.py +92 -0
- edron-0.8.0/src/edron/styling.py +35 -0
- edron-0.8.0/src/edron/tooling.py +313 -0
edron-0.8.0/.gitignore
ADDED
|
@@ -0,0 +1,36 @@
|
|
|
1
|
+
.DS_Store
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*$py.class
|
|
5
|
+
*.egg-info/
|
|
6
|
+
.eggs/
|
|
7
|
+
dist/
|
|
8
|
+
/build/
|
|
9
|
+
# Artifact/output build trees only — never ignore package source such as
|
|
10
|
+
# packages/hedron/src/hedron/build (Hatchling respects gitignore and would
|
|
11
|
+
# omit it from sdists/wheels; see #32).
|
|
12
|
+
**/.hedron/build/
|
|
13
|
+
packages/hedron-runtime-java/build/
|
|
14
|
+
target/
|
|
15
|
+
.venv*/
|
|
16
|
+
.bounds-venv*
|
|
17
|
+
venv*/
|
|
18
|
+
.env
|
|
19
|
+
.coverage
|
|
20
|
+
htmlcov/
|
|
21
|
+
.pytest_cache/
|
|
22
|
+
.mypy_cache/
|
|
23
|
+
.ruff_cache/
|
|
24
|
+
.hypothesis/
|
|
25
|
+
.tox/
|
|
26
|
+
.nox/
|
|
27
|
+
.audit-build-proj/
|
|
28
|
+
examples/reference-app/.hedron/
|
|
29
|
+
*.html.gz
|
|
30
|
+
/site/
|
|
31
|
+
*.so
|
|
32
|
+
*.dylib
|
|
33
|
+
*.pyd
|
|
34
|
+
.devcontainer/
|
|
35
|
+
# Local SQLite demos (e.g. examples/notes-sqlalchemy)
|
|
36
|
+
*.db
|
edron-0.8.0/CHANGELOG.md
ADDED
|
@@ -0,0 +1,99 @@
|
|
|
1
|
+
# Changelog
|
|
2
|
+
|
|
3
|
+
## [0.8.0] — 2026-08-27
|
|
4
|
+
|
|
5
|
+
### Added
|
|
6
|
+
|
|
7
|
+
- Explicit local, single-process, reverse-proxy, container, orchestrated, Workbench, and Posit
|
|
8
|
+
Connect deployment profiles with deterministic precedence and bounded diagnostics.
|
|
9
|
+
- `edron deploy-check` plus profile-aware `doctor` reports for production manifests, secrets,
|
|
10
|
+
proxy trust, root paths, multi-worker state/job claims, and host handoffs.
|
|
11
|
+
- Deterministic Edron artifact manifests with bounded SHA-256 records for offline promotion and
|
|
12
|
+
release verification.
|
|
13
|
+
- Phase 0.8 acceptance packet, profile/proxy/host/recovery fixtures, and deployment guide.
|
|
14
|
+
|
|
15
|
+
### Changed
|
|
16
|
+
|
|
17
|
+
- Scaffolds and generated migration projects pin the current `edron>=0.8,<0.9` package train.
|
|
18
|
+
|
|
19
|
+
## [0.7.0] — 2026-08-27
|
|
20
|
+
|
|
21
|
+
### Added
|
|
22
|
+
|
|
23
|
+
- Bounded, no-execution `edron migrate streamlit` analysis and Edron-native project generation.
|
|
24
|
+
- Deterministic JSON, text, and SARIF migration reports with source maps and a review checklist.
|
|
25
|
+
- Opt-in syntax-only codemods for safe Edron API spelling migrations.
|
|
26
|
+
|
|
27
|
+
## [0.6.0] — 2026-08-26
|
|
28
|
+
|
|
29
|
+
### Added
|
|
30
|
+
|
|
31
|
+
- Declarative `FeaturePackage` composition with native FeatureBundle inclusion, asset
|
|
32
|
+
collision/deduplication, provenance, and rollback.
|
|
33
|
+
- Typed app-owned navigation targets and shared bounded layout recipes over native Hedron nodes.
|
|
34
|
+
- Reviewed lazy promotion metadata for the mature `hedron-data`, `hedron-charts`, and
|
|
35
|
+
`hedron-maps` capabilities, with explicit native ejection guidance.
|
|
36
|
+
- Bounded deterministic application manifests and callback-free conformance reports.
|
|
37
|
+
|
|
38
|
+
## [0.5.0] — 2026-08-26
|
|
39
|
+
|
|
40
|
+
### Added
|
|
41
|
+
|
|
42
|
+
- App-owned native resource registration with lazy resolution, lifespan cleanup, health metadata,
|
|
43
|
+
and explicit dependency descriptors.
|
|
44
|
+
- Native-backed Edron caching with TTL, scope/vary policy, tags, mutable-value isolation, and
|
|
45
|
+
bounded per-function eviction.
|
|
46
|
+
- JobFlow backend selection, native poll policy wiring, bounded retry/result policy metadata, and
|
|
47
|
+
safe native job-status SSE event formatting.
|
|
48
|
+
- Bounded deployment diagnostics and resource metadata through `App.operations()` and `doctor`.
|
|
49
|
+
|
|
50
|
+
### Fixed
|
|
51
|
+
|
|
52
|
+
- Edron JobFlow now honors its explicit backend and polling interval instead of silently using the
|
|
53
|
+
process-global job backend/default poll policy.
|
|
54
|
+
|
|
55
|
+
## [0.4.0] — 2026-08-26
|
|
56
|
+
|
|
57
|
+
### Added
|
|
58
|
+
|
|
59
|
+
- Advanced native chart specifications with explicit accessible alternatives.
|
|
60
|
+
- Typed chart and map interaction registration that resolves Edron actions to native handles.
|
|
61
|
+
- Native image, audio, and video page helpers with safe URLs and validated media tracks.
|
|
62
|
+
- Bounded visualization interaction metadata in `App.explain()`.
|
|
63
|
+
|
|
64
|
+
### Fixed
|
|
65
|
+
|
|
66
|
+
- Edron action handlers now receive fresh request-local controller instances without permitting
|
|
67
|
+
output emission during action execution.
|
|
68
|
+
- Chart and map interaction dispatch supports both native handlers and Edron action endpoints.
|
|
69
|
+
|
|
70
|
+
## [0.3.0] — 2026-08-26
|
|
71
|
+
|
|
72
|
+
### Added
|
|
73
|
+
|
|
74
|
+
- Explicit native, in-memory/dataframe, and SQLAlchemy data-source facades.
|
|
75
|
+
- Bounded data workspaces with allowlisted paging, filters, sorting, search, selection, and CSV
|
|
76
|
+
export.
|
|
77
|
+
- Typed edit intents with deny-by-default authorization, validation, writable-field, concurrency,
|
|
78
|
+
and value-free audit contracts.
|
|
79
|
+
- Native DataTable/DataEditor page composition and ordinary-form DataWorkspace escape hatch.
|
|
80
|
+
|
|
81
|
+
## [0.2.0] — 2026-08-26
|
|
82
|
+
|
|
83
|
+
### Added
|
|
84
|
+
|
|
85
|
+
- Source-aware structured diagnostics and AST-only `check` tooling.
|
|
86
|
+
- Bounded application explanations, source maps, capability doctor, and SARIF reports.
|
|
87
|
+
- `edron new` minimal, dashboard, and form teaching scaffolds.
|
|
88
|
+
- Explicit `function_page`/`page_function` and `inherit`/`expose` authoring conveniences.
|
|
89
|
+
|
|
90
|
+
## [0.1.0] — 2026-08-26
|
|
91
|
+
|
|
92
|
+
### Added
|
|
93
|
+
|
|
94
|
+
- Initial Edron class-oriented authoring facade over Hedron.
|
|
95
|
+
|
|
96
|
+
### Fixed
|
|
97
|
+
|
|
98
|
+
- Lowered fragment/action dependencies into their native route registrations.
|
|
99
|
+
- Preserved explicitly bound action arguments in generated controls and forms.
|
edron-0.8.0/LICENSE
ADDED
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Odos Matthews
|
|
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.
|
edron-0.8.0/PKG-INFO
ADDED
|
@@ -0,0 +1,215 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: edron
|
|
3
|
+
Version: 0.8.0
|
|
4
|
+
Summary: Pythonic class-oriented authoring facade for Hedron
|
|
5
|
+
Project-URL: Homepage, https://github.com/eddiethedean/hedron
|
|
6
|
+
Project-URL: Repository, https://github.com/eddiethedean/hedron
|
|
7
|
+
Project-URL: Issues, https://github.com/eddiethedean/hedron/issues
|
|
8
|
+
Author-email: Odos Matthews <odosmatthews@gmail.com>
|
|
9
|
+
Maintainer-email: Odos Matthews <odosmatthews@gmail.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: dashboard,fastapi,htmx,python,server-rendered
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Framework :: FastAPI
|
|
15
|
+
Classifier: Intended Audience :: Developers
|
|
16
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
17
|
+
Classifier: Programming Language :: Python
|
|
18
|
+
Classifier: Programming Language :: Python :: 3
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
20
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
21
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
22
|
+
Classifier: Programming Language :: Python :: 3.14
|
|
23
|
+
Classifier: Typing :: Typed
|
|
24
|
+
Requires-Python: <3.15,>=3.11
|
|
25
|
+
Requires-Dist: hedron-charts<0.3,>=0.2.2
|
|
26
|
+
Requires-Dist: hedron-data<0.67,>=0.66.2
|
|
27
|
+
Requires-Dist: hedron-maps<0.2,>=0.1.2
|
|
28
|
+
Requires-Dist: hedron<0.67,>=0.66.2
|
|
29
|
+
Requires-Dist: markdown>=3.5
|
|
30
|
+
Requires-Dist: nh3>=0.2
|
|
31
|
+
Requires-Dist: uvicorn>=0.52.1
|
|
32
|
+
Provides-Extra: altair
|
|
33
|
+
Requires-Dist: altair<7,>=6; extra == 'altair'
|
|
34
|
+
Requires-Dist: vl-convert-python>=1.0; extra == 'altair'
|
|
35
|
+
Provides-Extra: matplotlib
|
|
36
|
+
Requires-Dist: matplotlib<4,>=3.8; extra == 'matplotlib'
|
|
37
|
+
Provides-Extra: pandas
|
|
38
|
+
Requires-Dist: narwhals>=1.0; extra == 'pandas'
|
|
39
|
+
Requires-Dist: pandas>=2.0; extra == 'pandas'
|
|
40
|
+
Provides-Extra: plotly
|
|
41
|
+
Requires-Dist: plotly<7,>=5.18; extra == 'plotly'
|
|
42
|
+
Provides-Extra: polars
|
|
43
|
+
Requires-Dist: narwhals>=1.0; extra == 'polars'
|
|
44
|
+
Requires-Dist: polars>=1.0; extra == 'polars'
|
|
45
|
+
Provides-Extra: pyarrow
|
|
46
|
+
Requires-Dist: narwhals>=1.0; extra == 'pyarrow'
|
|
47
|
+
Requires-Dist: pyarrow>=15.0; extra == 'pyarrow'
|
|
48
|
+
Provides-Extra: sqlalchemy
|
|
49
|
+
Requires-Dist: sqlalchemy<3,>=2; extra == 'sqlalchemy'
|
|
50
|
+
Description-Content-Type: text/markdown
|
|
51
|
+
|
|
52
|
+
# Edron
|
|
53
|
+
|
|
54
|
+
[](https://github.com/eddiethedean/hedron/actions/workflows/ci.yml)
|
|
55
|
+
[](https://pypi.org/project/edron/)
|
|
56
|
+
[](https://pypi.org/project/edron/)
|
|
57
|
+
[](https://github.com/eddiethedean/hedron/blob/main/packages/edron/LICENSE)
|
|
58
|
+
[](https://github.com/eddiethedean/hedron)
|
|
59
|
+
|
|
60
|
+
Build polished, server-rendered Python apps with a small, explicit API.
|
|
61
|
+
|
|
62
|
+
Edron keeps the first page simple and gives the same codebase room to grow into dashboards,
|
|
63
|
+
internal tools, data workspaces, long-running jobs, and reusable feature packages. You write
|
|
64
|
+
ordinary Python, run one command, and get accessible HTML with progressive enhancement—without
|
|
65
|
+
maintaining a separate frontend application or learning a callback-heavy UI model.
|
|
66
|
+
|
|
67
|
+
For existing Streamlit projects, `edron migrate streamlit app.py --out migrated-app` produces a
|
|
68
|
+
fresh Edron project, deterministic review report, and source map. The migration is static and
|
|
69
|
+
review-first: source files are never executed or overwritten, and uncertain behavior is called out
|
|
70
|
+
as a finding or TODO.
|
|
71
|
+
|
|
72
|
+
## A first page in minutes
|
|
73
|
+
|
|
74
|
+
Install Edron, create `app.py`, and start the development server:
|
|
75
|
+
|
|
76
|
+
```console
|
|
77
|
+
python -m pip install edron
|
|
78
|
+
edron run app:app --reload
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
```python
|
|
82
|
+
import edron as ed
|
|
83
|
+
|
|
84
|
+
app = ed.App(title="Hello Edron")
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@app.page("/", title="Hello")
|
|
88
|
+
class Home(ed.Page):
|
|
89
|
+
def render(self) -> None:
|
|
90
|
+
self.heading("Hello, Edron")
|
|
91
|
+
self.text("A small Python API for useful web applications.")
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
That is the whole application. Add a route, compose a layout, or wire an action when you need
|
|
95
|
+
it—there is no generated frontend project to keep in sync.
|
|
96
|
+
|
|
97
|
+
For a guided starting point, use a teaching scaffold:
|
|
98
|
+
|
|
99
|
+
```console
|
|
100
|
+
edron new my-app --template minimal
|
|
101
|
+
cd my-app
|
|
102
|
+
edron run app:app --reload
|
|
103
|
+
```
|
|
104
|
+
|
|
105
|
+
## Why developers reach for Edron
|
|
106
|
+
|
|
107
|
+
- **Python all the way down.** Pages, components, actions, forms, data, and jobs use familiar
|
|
108
|
+
functions, classes, and type hints.
|
|
109
|
+
- **A fast path and an escape hatch.** Start with a handful of readable Edron primitives. Keep
|
|
110
|
+
full control of the underlying application when an advanced integration needs it.
|
|
111
|
+
- **Server-first by default.** HTML is useful on its own; HTMX-style enhancement adds smooth
|
|
112
|
+
interactions without making JavaScript a requirement.
|
|
113
|
+
- **Batteries included for real work.** Compose navigation and layouts, render charts and media,
|
|
114
|
+
build bounded data tables and editors, manage resources and caching, and expose durable jobs.
|
|
115
|
+
- **Inspectable instead of magical.** `edron check`, `edron explain`, and `edron doctor` make
|
|
116
|
+
registration, dependencies, capabilities, and deployment facts visible before production.
|
|
117
|
+
- **Easy to test and review.** Explicit routes, typed inputs, bounded payloads, and deterministic
|
|
118
|
+
manifests keep behavior straightforward to assert in unit tests and code review.
|
|
119
|
+
|
|
120
|
+
## A small API that scales
|
|
121
|
+
|
|
122
|
+
The same page vocabulary works for a simple screen or a complete workflow:
|
|
123
|
+
|
|
124
|
+
```python
|
|
125
|
+
import edron as ed
|
|
126
|
+
|
|
127
|
+
app = ed.App(title="Sales")
|
|
128
|
+
|
|
129
|
+
|
|
130
|
+
@app.page("/sales", title="Sales")
|
|
131
|
+
class Sales(ed.Page):
|
|
132
|
+
def render(self) -> None:
|
|
133
|
+
self.heading("Sales overview")
|
|
134
|
+
with self.layout(ed.layout("grid", columns=2)) as body:
|
|
135
|
+
body.text("A layout is just Python composition.")
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Common building blocks include:
|
|
139
|
+
|
|
140
|
+
| Need | Edron API |
|
|
141
|
+
| --- | --- |
|
|
142
|
+
| Pages and reusable UI | `Page`, `@app.page`, `fragment`, `inherit`, `expose` |
|
|
143
|
+
| Navigation and layout | `navigation_target`, `layout`, `NavLink`-compatible targets |
|
|
144
|
+
| Forms and interactions | typed `action`, `fragment`, `Outcome`, `refresh`, `success` |
|
|
145
|
+
| Tables and editing | `DataSource`, `DataWorkspace`, `Column`, `EditPolicy` |
|
|
146
|
+
| Charts and media | `chart`, `map`, `image`, `audio`, `video` |
|
|
147
|
+
| Resources and performance | `resource`, `dependency`, `cache_data` |
|
|
148
|
+
| Long-running work | `JobFlow`, `JobBackend`, status polling/events |
|
|
149
|
+
| Reusable app features | `feature_package`, `include_package`, capability promotion |
|
|
150
|
+
|
|
151
|
+
## Data, resources, and jobs stay explicit
|
|
152
|
+
|
|
153
|
+
Edron makes application boundaries visible instead of hiding them in global state. For example,
|
|
154
|
+
resources are lazy and app-owned, cache policy is declared beside the function it protects, and
|
|
155
|
+
data editing is deny-by-default:
|
|
156
|
+
|
|
157
|
+
```python
|
|
158
|
+
db = app.resource("database", create_database, secret_refs={"dsn": "DATABASE_URL"})
|
|
159
|
+
|
|
160
|
+
|
|
161
|
+
@ed.cache_data(ttl=60, scope="tenant", vary_on=("tenant_id",))
|
|
162
|
+
def load_summary(tenant_id: str) -> dict[str, int]:
|
|
163
|
+
return query_summary(db, tenant_id)
|
|
164
|
+
```
|
|
165
|
+
|
|
166
|
+
Use `DataWorkspace` for bounded paging, filtering, sorting, selection, CSV export, and typed edit
|
|
167
|
+
intents. Use `JobFlow` when work must outlive a request. Your application still owns the database
|
|
168
|
+
session, transaction, authorization, persistence, and audit decisions.
|
|
169
|
+
|
|
170
|
+
## Tooling that helps before deployment
|
|
171
|
+
|
|
172
|
+
```console
|
|
173
|
+
# Check source without importing application code
|
|
174
|
+
edron check app.py
|
|
175
|
+
|
|
176
|
+
# Inspect registered pages and surfaces
|
|
177
|
+
edron explain app:app
|
|
178
|
+
|
|
179
|
+
# Check installed required and optional capabilities
|
|
180
|
+
edron doctor
|
|
181
|
+
|
|
182
|
+
# Validate a deployment profile without importing application code
|
|
183
|
+
edron deploy-check --profile reverse-proxy --format json
|
|
184
|
+
```
|
|
185
|
+
|
|
186
|
+
For CI, `edron check --format sarif` produces review-friendly diagnostics. Applications can also
|
|
187
|
+
expose deterministic `app.manifest()` and `app.conformance()` reports for release checks.
|
|
188
|
+
|
|
189
|
+
## Installation and optional integrations
|
|
190
|
+
|
|
191
|
+
Edron supports Python 3.11–3.14. Install only what your application needs:
|
|
192
|
+
|
|
193
|
+
```console
|
|
194
|
+
python -m pip install edron
|
|
195
|
+
```
|
|
196
|
+
|
|
197
|
+
Optional extras are available for pandas, Polars, PyArrow, Plotly, Altair, Matplotlib, and
|
|
198
|
+
SQLAlchemy (for example, `pip install "edron[polars,sqlalchemy]"`).
|
|
199
|
+
|
|
200
|
+
Read the [getting started guide](https://hedron.readthedocs.io/en/latest/getting-started/), browse
|
|
201
|
+
the [API guides](https://hedron.readthedocs.io/en/latest/api/), or see the
|
|
202
|
+
[Edron user guide](https://hedron.readthedocs.io/en/latest/guides/edron-user-guide/), the
|
|
203
|
+
[Edron roadmap](https://github.com/eddiethedean/hedron/blob/main/docs/EDRON_ROADMAP.md) and
|
|
204
|
+
[deployment guide](https://github.com/eddiethedean/hedron/blob/main/docs/guides/edron-deployment.md).
|
|
205
|
+
|
|
206
|
+
## How Edron fits in
|
|
207
|
+
|
|
208
|
+
Edron is the authoring layer: it gives application developers a friendly, typed vocabulary and
|
|
209
|
+
keeps the important boundaries explicit. A mature native web engine handles the lower-level
|
|
210
|
+
rendering, routing, interaction, styling, and security work underneath. Most applications never
|
|
211
|
+
need to think about that implementation detail; when they do, the exact native application remains
|
|
212
|
+
available through `app.native` / `app.hedron` and `Page.include()`.
|
|
213
|
+
|
|
214
|
+
Edron is currently a **Beta** API line. Feedback, issues, and contributions are welcome in the
|
|
215
|
+
[Hedron repository](https://github.com/eddiethedean/hedron).
|
edron-0.8.0/README.md
ADDED
|
@@ -0,0 +1,164 @@
|
|
|
1
|
+
# Edron
|
|
2
|
+
|
|
3
|
+
[](https://github.com/eddiethedean/hedron/actions/workflows/ci.yml)
|
|
4
|
+
[](https://pypi.org/project/edron/)
|
|
5
|
+
[](https://pypi.org/project/edron/)
|
|
6
|
+
[](https://github.com/eddiethedean/hedron/blob/main/packages/edron/LICENSE)
|
|
7
|
+
[](https://github.com/eddiethedean/hedron)
|
|
8
|
+
|
|
9
|
+
Build polished, server-rendered Python apps with a small, explicit API.
|
|
10
|
+
|
|
11
|
+
Edron keeps the first page simple and gives the same codebase room to grow into dashboards,
|
|
12
|
+
internal tools, data workspaces, long-running jobs, and reusable feature packages. You write
|
|
13
|
+
ordinary Python, run one command, and get accessible HTML with progressive enhancement—without
|
|
14
|
+
maintaining a separate frontend application or learning a callback-heavy UI model.
|
|
15
|
+
|
|
16
|
+
For existing Streamlit projects, `edron migrate streamlit app.py --out migrated-app` produces a
|
|
17
|
+
fresh Edron project, deterministic review report, and source map. The migration is static and
|
|
18
|
+
review-first: source files are never executed or overwritten, and uncertain behavior is called out
|
|
19
|
+
as a finding or TODO.
|
|
20
|
+
|
|
21
|
+
## A first page in minutes
|
|
22
|
+
|
|
23
|
+
Install Edron, create `app.py`, and start the development server:
|
|
24
|
+
|
|
25
|
+
```console
|
|
26
|
+
python -m pip install edron
|
|
27
|
+
edron run app:app --reload
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
```python
|
|
31
|
+
import edron as ed
|
|
32
|
+
|
|
33
|
+
app = ed.App(title="Hello Edron")
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
@app.page("/", title="Hello")
|
|
37
|
+
class Home(ed.Page):
|
|
38
|
+
def render(self) -> None:
|
|
39
|
+
self.heading("Hello, Edron")
|
|
40
|
+
self.text("A small Python API for useful web applications.")
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
That is the whole application. Add a route, compose a layout, or wire an action when you need
|
|
44
|
+
it—there is no generated frontend project to keep in sync.
|
|
45
|
+
|
|
46
|
+
For a guided starting point, use a teaching scaffold:
|
|
47
|
+
|
|
48
|
+
```console
|
|
49
|
+
edron new my-app --template minimal
|
|
50
|
+
cd my-app
|
|
51
|
+
edron run app:app --reload
|
|
52
|
+
```
|
|
53
|
+
|
|
54
|
+
## Why developers reach for Edron
|
|
55
|
+
|
|
56
|
+
- **Python all the way down.** Pages, components, actions, forms, data, and jobs use familiar
|
|
57
|
+
functions, classes, and type hints.
|
|
58
|
+
- **A fast path and an escape hatch.** Start with a handful of readable Edron primitives. Keep
|
|
59
|
+
full control of the underlying application when an advanced integration needs it.
|
|
60
|
+
- **Server-first by default.** HTML is useful on its own; HTMX-style enhancement adds smooth
|
|
61
|
+
interactions without making JavaScript a requirement.
|
|
62
|
+
- **Batteries included for real work.** Compose navigation and layouts, render charts and media,
|
|
63
|
+
build bounded data tables and editors, manage resources and caching, and expose durable jobs.
|
|
64
|
+
- **Inspectable instead of magical.** `edron check`, `edron explain`, and `edron doctor` make
|
|
65
|
+
registration, dependencies, capabilities, and deployment facts visible before production.
|
|
66
|
+
- **Easy to test and review.** Explicit routes, typed inputs, bounded payloads, and deterministic
|
|
67
|
+
manifests keep behavior straightforward to assert in unit tests and code review.
|
|
68
|
+
|
|
69
|
+
## A small API that scales
|
|
70
|
+
|
|
71
|
+
The same page vocabulary works for a simple screen or a complete workflow:
|
|
72
|
+
|
|
73
|
+
```python
|
|
74
|
+
import edron as ed
|
|
75
|
+
|
|
76
|
+
app = ed.App(title="Sales")
|
|
77
|
+
|
|
78
|
+
|
|
79
|
+
@app.page("/sales", title="Sales")
|
|
80
|
+
class Sales(ed.Page):
|
|
81
|
+
def render(self) -> None:
|
|
82
|
+
self.heading("Sales overview")
|
|
83
|
+
with self.layout(ed.layout("grid", columns=2)) as body:
|
|
84
|
+
body.text("A layout is just Python composition.")
|
|
85
|
+
```
|
|
86
|
+
|
|
87
|
+
Common building blocks include:
|
|
88
|
+
|
|
89
|
+
| Need | Edron API |
|
|
90
|
+
| --- | --- |
|
|
91
|
+
| Pages and reusable UI | `Page`, `@app.page`, `fragment`, `inherit`, `expose` |
|
|
92
|
+
| Navigation and layout | `navigation_target`, `layout`, `NavLink`-compatible targets |
|
|
93
|
+
| Forms and interactions | typed `action`, `fragment`, `Outcome`, `refresh`, `success` |
|
|
94
|
+
| Tables and editing | `DataSource`, `DataWorkspace`, `Column`, `EditPolicy` |
|
|
95
|
+
| Charts and media | `chart`, `map`, `image`, `audio`, `video` |
|
|
96
|
+
| Resources and performance | `resource`, `dependency`, `cache_data` |
|
|
97
|
+
| Long-running work | `JobFlow`, `JobBackend`, status polling/events |
|
|
98
|
+
| Reusable app features | `feature_package`, `include_package`, capability promotion |
|
|
99
|
+
|
|
100
|
+
## Data, resources, and jobs stay explicit
|
|
101
|
+
|
|
102
|
+
Edron makes application boundaries visible instead of hiding them in global state. For example,
|
|
103
|
+
resources are lazy and app-owned, cache policy is declared beside the function it protects, and
|
|
104
|
+
data editing is deny-by-default:
|
|
105
|
+
|
|
106
|
+
```python
|
|
107
|
+
db = app.resource("database", create_database, secret_refs={"dsn": "DATABASE_URL"})
|
|
108
|
+
|
|
109
|
+
|
|
110
|
+
@ed.cache_data(ttl=60, scope="tenant", vary_on=("tenant_id",))
|
|
111
|
+
def load_summary(tenant_id: str) -> dict[str, int]:
|
|
112
|
+
return query_summary(db, tenant_id)
|
|
113
|
+
```
|
|
114
|
+
|
|
115
|
+
Use `DataWorkspace` for bounded paging, filtering, sorting, selection, CSV export, and typed edit
|
|
116
|
+
intents. Use `JobFlow` when work must outlive a request. Your application still owns the database
|
|
117
|
+
session, transaction, authorization, persistence, and audit decisions.
|
|
118
|
+
|
|
119
|
+
## Tooling that helps before deployment
|
|
120
|
+
|
|
121
|
+
```console
|
|
122
|
+
# Check source without importing application code
|
|
123
|
+
edron check app.py
|
|
124
|
+
|
|
125
|
+
# Inspect registered pages and surfaces
|
|
126
|
+
edron explain app:app
|
|
127
|
+
|
|
128
|
+
# Check installed required and optional capabilities
|
|
129
|
+
edron doctor
|
|
130
|
+
|
|
131
|
+
# Validate a deployment profile without importing application code
|
|
132
|
+
edron deploy-check --profile reverse-proxy --format json
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
For CI, `edron check --format sarif` produces review-friendly diagnostics. Applications can also
|
|
136
|
+
expose deterministic `app.manifest()` and `app.conformance()` reports for release checks.
|
|
137
|
+
|
|
138
|
+
## Installation and optional integrations
|
|
139
|
+
|
|
140
|
+
Edron supports Python 3.11–3.14. Install only what your application needs:
|
|
141
|
+
|
|
142
|
+
```console
|
|
143
|
+
python -m pip install edron
|
|
144
|
+
```
|
|
145
|
+
|
|
146
|
+
Optional extras are available for pandas, Polars, PyArrow, Plotly, Altair, Matplotlib, and
|
|
147
|
+
SQLAlchemy (for example, `pip install "edron[polars,sqlalchemy]"`).
|
|
148
|
+
|
|
149
|
+
Read the [getting started guide](https://hedron.readthedocs.io/en/latest/getting-started/), browse
|
|
150
|
+
the [API guides](https://hedron.readthedocs.io/en/latest/api/), or see the
|
|
151
|
+
[Edron user guide](https://hedron.readthedocs.io/en/latest/guides/edron-user-guide/), the
|
|
152
|
+
[Edron roadmap](https://github.com/eddiethedean/hedron/blob/main/docs/EDRON_ROADMAP.md) and
|
|
153
|
+
[deployment guide](https://github.com/eddiethedean/hedron/blob/main/docs/guides/edron-deployment.md).
|
|
154
|
+
|
|
155
|
+
## How Edron fits in
|
|
156
|
+
|
|
157
|
+
Edron is the authoring layer: it gives application developers a friendly, typed vocabulary and
|
|
158
|
+
keeps the important boundaries explicit. A mature native web engine handles the lower-level
|
|
159
|
+
rendering, routing, interaction, styling, and security work underneath. Most applications never
|
|
160
|
+
need to think about that implementation detail; when they do, the exact native application remains
|
|
161
|
+
available through `app.native` / `app.hedron` and `Page.include()`.
|
|
162
|
+
|
|
163
|
+
Edron is currently a **Beta** API line. Feedback, issues, and contributions are welcome in the
|
|
164
|
+
[Hedron repository](https://github.com/eddiethedean/hedron).
|
|
@@ -0,0 +1,60 @@
|
|
|
1
|
+
[project]
|
|
2
|
+
name = "edron"
|
|
3
|
+
version = "0.8.0"
|
|
4
|
+
description = "Pythonic class-oriented authoring facade for Hedron"
|
|
5
|
+
readme = "README.md"
|
|
6
|
+
requires-python = ">=3.11,<3.15"
|
|
7
|
+
license = "MIT"
|
|
8
|
+
license-files = ["LICENSE"]
|
|
9
|
+
authors = [{ name = "Odos Matthews", email = "odosmatthews@gmail.com" }]
|
|
10
|
+
maintainers = [{ name = "Odos Matthews", email = "odosmatthews@gmail.com" }]
|
|
11
|
+
keywords = ["fastapi", "htmx", "python", "server-rendered", "dashboard"]
|
|
12
|
+
classifiers = [
|
|
13
|
+
"Development Status :: 4 - Beta",
|
|
14
|
+
"Framework :: FastAPI",
|
|
15
|
+
"Intended Audience :: Developers",
|
|
16
|
+
"License :: OSI Approved :: MIT License",
|
|
17
|
+
"Programming Language :: Python",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.11",
|
|
20
|
+
"Programming Language :: Python :: 3.12",
|
|
21
|
+
"Programming Language :: Python :: 3.13",
|
|
22
|
+
"Programming Language :: Python :: 3.14",
|
|
23
|
+
"Typing :: Typed",
|
|
24
|
+
]
|
|
25
|
+
dependencies = [
|
|
26
|
+
"hedron>=0.66.2,<0.67",
|
|
27
|
+
"hedron-data>=0.66.2,<0.67",
|
|
28
|
+
"hedron-charts>=0.2.2,<0.3",
|
|
29
|
+
"hedron-maps>=0.1.2,<0.2",
|
|
30
|
+
"markdown>=3.5",
|
|
31
|
+
"nh3>=0.2",
|
|
32
|
+
"uvicorn>=0.52.1",
|
|
33
|
+
]
|
|
34
|
+
|
|
35
|
+
[project.optional-dependencies]
|
|
36
|
+
pandas = ["pandas>=2.0", "narwhals>=1.0"]
|
|
37
|
+
polars = ["polars>=1.0", "narwhals>=1.0"]
|
|
38
|
+
pyarrow = ["pyarrow>=15.0", "narwhals>=1.0"]
|
|
39
|
+
plotly = ["plotly>=5.18,<7"]
|
|
40
|
+
altair = ["altair>=6,<7", "vl-convert-python>=1.0"]
|
|
41
|
+
matplotlib = ["matplotlib>=3.8,<4"]
|
|
42
|
+
sqlalchemy = ["sqlalchemy>=2,<3"]
|
|
43
|
+
|
|
44
|
+
[project.scripts]
|
|
45
|
+
edron = "edron.cli:main"
|
|
46
|
+
|
|
47
|
+
[project.urls]
|
|
48
|
+
Homepage = "https://github.com/eddiethedean/hedron"
|
|
49
|
+
Repository = "https://github.com/eddiethedean/hedron"
|
|
50
|
+
Issues = "https://github.com/eddiethedean/hedron/issues"
|
|
51
|
+
|
|
52
|
+
[build-system]
|
|
53
|
+
requires = ["hatchling"]
|
|
54
|
+
build-backend = "hatchling.build"
|
|
55
|
+
|
|
56
|
+
[tool.hatch.build.targets.wheel]
|
|
57
|
+
packages = ["src/edron"]
|
|
58
|
+
|
|
59
|
+
[tool.hatch.build.targets.sdist]
|
|
60
|
+
only-include = ["src/edron", "README.md", "CHANGELOG.md", "LICENSE", "pyproject.toml"]
|