frontedge 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 (50) hide show
  1. frontedge-0.1.0/.gitignore +13 -0
  2. frontedge-0.1.0/LICENSE +21 -0
  3. frontedge-0.1.0/PKG-INFO +111 -0
  4. frontedge-0.1.0/README.md +84 -0
  5. frontedge-0.1.0/pyproject.toml +65 -0
  6. frontedge-0.1.0/src/frontedge/__init__.py +75 -0
  7. frontedge-0.1.0/src/frontedge/cli.py +750 -0
  8. frontedge-0.1.0/src/frontedge/config.py +138 -0
  9. frontedge-0.1.0/src/frontedge/gen/__init__.py +5 -0
  10. frontedge-0.1.0/src/frontedge/gen/typescript.py +384 -0
  11. frontedge-0.1.0/src/frontedge/meta.py +89 -0
  12. frontedge-0.1.0/src/frontedge/models.py +288 -0
  13. frontedge-0.1.0/src/frontedge/providers.py +311 -0
  14. frontedge-0.1.0/src/frontedge/py.typed +0 -0
  15. frontedge-0.1.0/src/frontedge/runtime/__init__.py +1 -0
  16. frontedge-0.1.0/src/frontedge/runtime/sse.py +75 -0
  17. frontedge-0.1.0/src/frontedge/runtime/static.py +72 -0
  18. frontedge-0.1.0/src/frontedge/screens/__init__.py +5 -0
  19. frontedge-0.1.0/src/frontedge/screens/runs.py +649 -0
  20. frontedge-0.1.0/src/frontedge/static/README.md +5 -0
  21. frontedge-0.1.0/src/frontedge/static/assets/index-CAazRc5A.css +1 -0
  22. frontedge-0.1.0/src/frontedge/static/assets/index-Cqi_KhCa.js +268 -0
  23. frontedge-0.1.0/src/frontedge/static/assets/inter-cyrillic-ext-wght-normal-BOeWTOD4.woff2 +0 -0
  24. frontedge-0.1.0/src/frontedge/static/assets/inter-cyrillic-wght-normal-DqGufNeO.woff2 +0 -0
  25. frontedge-0.1.0/src/frontedge/static/assets/inter-greek-ext-wght-normal-DlzME5K_.woff2 +0 -0
  26. frontedge-0.1.0/src/frontedge/static/assets/inter-greek-wght-normal-CkhJZR-_.woff2 +0 -0
  27. frontedge-0.1.0/src/frontedge/static/assets/inter-latin-ext-wght-normal-DO1Apj_S.woff2 +0 -0
  28. frontedge-0.1.0/src/frontedge/static/assets/inter-latin-wght-normal-Dx4kXJAl.woff2 +0 -0
  29. frontedge-0.1.0/src/frontedge/static/assets/inter-vietnamese-wght-normal-CBcvBZtf.woff2 +0 -0
  30. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-cyrillic-400-normal-BEIGL1Tu.woff2 +0 -0
  31. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-cyrillic-400-normal-ugxPyKxw.woff +0 -0
  32. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-cyrillic-500-normal-DJqRU3vO.woff +0 -0
  33. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-cyrillic-500-normal-DmUKJPL_.woff2 +0 -0
  34. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-greek-400-normal-B9oWc5Lo.woff +0 -0
  35. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-greek-400-normal-C190GLew.woff2 +0 -0
  36. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-greek-500-normal-D7SFKleX.woff +0 -0
  37. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-greek-500-normal-JpySY46c.woff2 +0 -0
  38. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-400-normal-6-qcROiO.woff +0 -0
  39. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-400-normal-V6pRDFza.woff2 +0 -0
  40. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-500-normal-BWZEU5yA.woff2 +0 -0
  41. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-500-normal-CJOVTJB7.woff +0 -0
  42. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-ext-400-normal-Bc8Ftmh3.woff2 +0 -0
  43. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-ext-400-normal-fXTG6kC5.woff +0 -0
  44. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-ext-500-normal-Cut-4mMH.woff2 +0 -0
  45. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-latin-ext-500-normal-ckzbgY84.woff +0 -0
  46. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-vietnamese-400-normal-CqNFfHCs.woff +0 -0
  47. frontedge-0.1.0/src/frontedge/static/assets/jetbrains-mono-vietnamese-500-normal-DNRqzVM1.woff +0 -0
  48. frontedge-0.1.0/src/frontedge/static/index.html +21 -0
  49. frontedge-0.1.0/tests/test_contract.py +1212 -0
  50. frontedge-0.1.0/tests/test_docs.py +129 -0
@@ -0,0 +1,13 @@
1
+ node_modules/
2
+ dist/
3
+ .venv/
4
+ __pycache__/
5
+ *.log
6
+
7
+ # The built interface is copied into the Python package at build time
8
+ python/frontedge/src/frontedge/static/index.html
9
+ python/frontedge/src/frontedge/static/assets/
10
+
11
+ # Local reference material stays out of the repository
12
+ design-prompts-local/
13
+ mockups-local/
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 socrabs151
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,111 @@
1
+ Metadata-Version: 2.5
2
+ Name: frontedge
3
+ Version: 0.1.0
4
+ Summary: Frontend layer for ML engineering: mount ready-made screens into any FastAPI app
5
+ Project-URL: Homepage, https://github.com/socrabs151/frontedge-ml
6
+ Project-URL: Repository, https://github.com/socrabs151/frontedge-ml
7
+ Project-URL: Issues, https://github.com/socrabs151/frontedge-ml/issues
8
+ Project-URL: Changelog, https://github.com/socrabs151/frontedge-ml/blob/main/CHANGELOG.md
9
+ Project-URL: Documentation, https://github.com/socrabs151/frontedge-ml/blob/main/docs/integration.md
10
+ Author: socrabs151
11
+ License: MIT
12
+ License-File: LICENSE
13
+ Keywords: dashboard,evaluation,experiments,fastapi,ml,mlops,runs
14
+ Classifier: Development Status :: 3 - Alpha
15
+ Classifier: Framework :: FastAPI
16
+ Classifier: Intended Audience :: Science/Research
17
+ Classifier: License :: OSI Approved :: MIT License
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: Typing :: Typed
23
+ Requires-Python: >=3.11
24
+ Requires-Dist: fastapi>=0.115
25
+ Requires-Dist: pydantic>=2.9
26
+ Description-Content-Type: text/markdown
27
+
28
+ # frontedge
29
+
30
+ The frontend layer for ML engineering: a ready-made design system and screens that mount into
31
+ any FastAPI application.
32
+
33
+ ```python
34
+ from fastapi import FastAPI
35
+ import frontedge
36
+
37
+ app = FastAPI()
38
+ app.include_router(frontedge.runs(runs_provider=my_provider))
39
+ ```
40
+
41
+ The provider returns `frontedge.Run` objects; the library knows nothing about authentication and
42
+ hands the `request` to the provider, so access control stays on the application side.
43
+
44
+ ## What's inside
45
+
46
+ - `frontedge.mount(runs_provider, evals=..., datasets=..., actions=..., config=..., path="/frontedge")`
47
+ — the router: the list of runs, the run details, the log stream (SSE), the metadata and the
48
+ built interface.
49
+ - `frontedge.runs(runs_provider, path="/frontedge")` — the same router without the eval and
50
+ dataset screens.
51
+ - `frontedge.models` — the domain model: `Run`, `Stage`, `MetricPoint`, `Artifact`, `Example`,
52
+ `LogLine`, `EvalSummary`, `EvalComparison`, `DatasetInfo`, `DatasetDetail`, the statuses and
53
+ the freshness.
54
+ - `frontedge gen --out src/generated` — the generator of TypeScript types and a typed client
55
+ from the pydantic models. Pure Python, no Node needed.
56
+
57
+ One process, one port: the interface and the API are served by the same app.
58
+
59
+ ## Configuration
60
+
61
+ The configuration is data, not code — a TOML or JSON file that the same interface can edit by
62
+ hand, from code and later with a visual editor:
63
+
64
+ ```toml
65
+ # frontedge.toml
66
+ density = "default" # compact | default | comfortable
67
+ theme = "light" # light | dark
68
+ run_columns = ["name", "status", "ribbon", "dataset", "startedAt", "durationMs", "accuracy", "loss"]
69
+ ```
70
+
71
+ ```python
72
+ app.include_router(frontedge.mount(my_runs_provider, config="frontedge.toml"))
73
+ ```
74
+
75
+ `UiConfig` also knows `eval_tabs`, `actions`, `live_refresh_seconds`, `baseline_run` and
76
+ `page_size`. The configuration is served to the browser as `GET /frontedge/api/config`.
77
+
78
+ ## Actions
79
+
80
+ The interface never invents what a button does: a project declares the actions it supports, and
81
+ the library calls them.
82
+
83
+ ```toml
84
+ [[actions]]
85
+ id = "stop"
86
+ label = "Stop"
87
+ placement = "run" # run | runs | evals | datasets
88
+ danger = true
89
+ ```
90
+
91
+ ```python
92
+ from frontedge import ActionResult
93
+
94
+ async def stop_run(request, payload) -> ActionResult:
95
+ run_id = payload["runId"]
96
+ await my_repository.stop(run_id)
97
+ return ActionResult(ok=True, message=f"Run {run_id} stopped")
98
+
99
+ app.include_router(
100
+ frontedge.mount(my_runs_provider, actions={"stop": stop_run}, config="frontedge.toml")
101
+ )
102
+ ```
103
+
104
+ The handler receives the `request` and the `payload` of the interface and returns an
105
+ `ActionResult`; its `message` is shown to the user.
106
+
107
+ The full description of the product and of the visual language:
108
+ [design document](https://github.com/socrabs151/frontedge-ml/blob/main/docs/specs/2026-10-20-frontedge-design.md).
109
+ The full contract: [docs/integration.md](https://github.com/socrabs151/frontedge-ml/blob/main/docs/integration.md).
110
+
111
+ MIT.
@@ -0,0 +1,84 @@
1
+ # frontedge
2
+
3
+ The frontend layer for ML engineering: a ready-made design system and screens that mount into
4
+ any FastAPI application.
5
+
6
+ ```python
7
+ from fastapi import FastAPI
8
+ import frontedge
9
+
10
+ app = FastAPI()
11
+ app.include_router(frontedge.runs(runs_provider=my_provider))
12
+ ```
13
+
14
+ The provider returns `frontedge.Run` objects; the library knows nothing about authentication and
15
+ hands the `request` to the provider, so access control stays on the application side.
16
+
17
+ ## What's inside
18
+
19
+ - `frontedge.mount(runs_provider, evals=..., datasets=..., actions=..., config=..., path="/frontedge")`
20
+ — the router: the list of runs, the run details, the log stream (SSE), the metadata and the
21
+ built interface.
22
+ - `frontedge.runs(runs_provider, path="/frontedge")` — the same router without the eval and
23
+ dataset screens.
24
+ - `frontedge.models` — the domain model: `Run`, `Stage`, `MetricPoint`, `Artifact`, `Example`,
25
+ `LogLine`, `EvalSummary`, `EvalComparison`, `DatasetInfo`, `DatasetDetail`, the statuses and
26
+ the freshness.
27
+ - `frontedge gen --out src/generated` — the generator of TypeScript types and a typed client
28
+ from the pydantic models. Pure Python, no Node needed.
29
+
30
+ One process, one port: the interface and the API are served by the same app.
31
+
32
+ ## Configuration
33
+
34
+ The configuration is data, not code — a TOML or JSON file that the same interface can edit by
35
+ hand, from code and later with a visual editor:
36
+
37
+ ```toml
38
+ # frontedge.toml
39
+ density = "default" # compact | default | comfortable
40
+ theme = "light" # light | dark
41
+ run_columns = ["name", "status", "ribbon", "dataset", "startedAt", "durationMs", "accuracy", "loss"]
42
+ ```
43
+
44
+ ```python
45
+ app.include_router(frontedge.mount(my_runs_provider, config="frontedge.toml"))
46
+ ```
47
+
48
+ `UiConfig` also knows `eval_tabs`, `actions`, `live_refresh_seconds`, `baseline_run` and
49
+ `page_size`. The configuration is served to the browser as `GET /frontedge/api/config`.
50
+
51
+ ## Actions
52
+
53
+ The interface never invents what a button does: a project declares the actions it supports, and
54
+ the library calls them.
55
+
56
+ ```toml
57
+ [[actions]]
58
+ id = "stop"
59
+ label = "Stop"
60
+ placement = "run" # run | runs | evals | datasets
61
+ danger = true
62
+ ```
63
+
64
+ ```python
65
+ from frontedge import ActionResult
66
+
67
+ async def stop_run(request, payload) -> ActionResult:
68
+ run_id = payload["runId"]
69
+ await my_repository.stop(run_id)
70
+ return ActionResult(ok=True, message=f"Run {run_id} stopped")
71
+
72
+ app.include_router(
73
+ frontedge.mount(my_runs_provider, actions={"stop": stop_run}, config="frontedge.toml")
74
+ )
75
+ ```
76
+
77
+ The handler receives the `request` and the `payload` of the interface and returns an
78
+ `ActionResult`; its `message` is shown to the user.
79
+
80
+ The full description of the product and of the visual language:
81
+ [design document](https://github.com/socrabs151/frontedge-ml/blob/main/docs/specs/2026-10-20-frontedge-design.md).
82
+ The full contract: [docs/integration.md](https://github.com/socrabs151/frontedge-ml/blob/main/docs/integration.md).
83
+
84
+ MIT.
@@ -0,0 +1,65 @@
1
+ [project]
2
+ name = "frontedge"
3
+ version = "0.1.0"
4
+ description = "Frontend layer for ML engineering: mount ready-made screens into any FastAPI app"
5
+ readme = "README.md"
6
+ requires-python = ">=3.11"
7
+ authors = [{ name = "socrabs151" }]
8
+ keywords = ["ml", "mlops", "fastapi", "experiments", "dashboard", "runs", "evaluation"]
9
+ license = { text = "MIT" }
10
+ license-files = ["LICENSE"]
11
+ classifiers = [
12
+ "Development Status :: 3 - Alpha",
13
+ "Framework :: FastAPI",
14
+ "Intended Audience :: Science/Research",
15
+ "License :: OSI Approved :: MIT License",
16
+ "Programming Language :: Python :: 3",
17
+ "Programming Language :: Python :: 3.11",
18
+ "Programming Language :: Python :: 3.12",
19
+ "Programming Language :: Python :: 3.13",
20
+ "Typing :: Typed",
21
+ ]
22
+ dependencies = [
23
+ "fastapi>=0.115",
24
+ "pydantic>=2.9",
25
+ ]
26
+
27
+ [project.urls]
28
+ Homepage = "https://github.com/socrabs151/frontedge-ml"
29
+ Repository = "https://github.com/socrabs151/frontedge-ml"
30
+ Issues = "https://github.com/socrabs151/frontedge-ml/issues"
31
+ Changelog = "https://github.com/socrabs151/frontedge-ml/blob/main/CHANGELOG.md"
32
+ Documentation = "https://github.com/socrabs151/frontedge-ml/blob/main/docs/integration.md"
33
+
34
+ [project.scripts]
35
+ frontedge = "frontedge.cli:main"
36
+
37
+ [build-system]
38
+ requires = ["hatchling"]
39
+ build-backend = "hatchling.build"
40
+
41
+ [tool.hatch.build.targets.wheel]
42
+ packages = ["src/frontedge"]
43
+ # The built interface is copied into src/frontedge/static (build: pnpm build && pnpm build:ui)
44
+ artifacts = ["src/frontedge/static/**"]
45
+
46
+ [tool.ruff]
47
+ line-length = 100
48
+ target-version = "py311"
49
+
50
+ [tool.ruff.lint]
51
+ select = ["E", "F", "I", "UP", "B"]
52
+
53
+ [tool.mypy]
54
+ python_version = "3.11"
55
+ mypy_path = "src"
56
+ plugins = ["pydantic.mypy"]
57
+ ignore_missing_imports = true
58
+
59
+ [dependency-groups]
60
+ dev = [
61
+ "httpx>=0.27",
62
+ "mypy>=1.11",
63
+ "pytest>=8.0",
64
+ "ruff>=0.6",
65
+ ]
@@ -0,0 +1,75 @@
1
+ """Frontedge — the frontend layer for ML engineering.
2
+
3
+ from fastapi import FastAPI
4
+ import frontedge
5
+
6
+ app = FastAPI()
7
+ app.include_router(frontedge.mount(my_runs_provider))
8
+ """
9
+
10
+ from .config import ActionResult, ActionSpec, ColumnSpec, MetricSpec, UiConfig, load_config
11
+ from .models import (
12
+ Artifact,
13
+ DatasetDetail,
14
+ DatasetInfo,
15
+ EvalComparison,
16
+ EvalSummary,
17
+ Example,
18
+ ExampleResult,
19
+ Freshness,
20
+ LogLine,
21
+ MetricDirection,
22
+ MetricEvent,
23
+ MetricPoint,
24
+ ProvenanceEntry,
25
+ Run,
26
+ RunStatus,
27
+ Stage,
28
+ StageName,
29
+ role,
30
+ )
31
+ from .providers import (
32
+ CallableProvider,
33
+ DatasetProvider,
34
+ EvalProvider,
35
+ FrontedgeProvider,
36
+ ProviderError,
37
+ )
38
+ from .screens import mount, runs
39
+
40
+ __version__ = "0.1.0"
41
+
42
+ __all__ = [
43
+ "ActionResult",
44
+ "ActionSpec",
45
+ "Artifact",
46
+ "CallableProvider",
47
+ "ColumnSpec",
48
+ "DatasetDetail",
49
+ "DatasetInfo",
50
+ "DatasetProvider",
51
+ "EvalComparison",
52
+ "EvalProvider",
53
+ "EvalSummary",
54
+ "Example",
55
+ "ExampleResult",
56
+ "Freshness",
57
+ "FrontedgeProvider",
58
+ "LogLine",
59
+ "MetricDirection",
60
+ "MetricEvent",
61
+ "MetricSpec",
62
+ "MetricPoint",
63
+ "ProviderError",
64
+ "ProvenanceEntry",
65
+ "Run",
66
+ "RunStatus",
67
+ "Stage",
68
+ "StageName",
69
+ "UiConfig",
70
+ "load_config",
71
+ "__version__",
72
+ "mount",
73
+ "role",
74
+ "runs",
75
+ ]