cf-web 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.
- cf_web-0.1.0/PKG-INFO +175 -0
- cf_web-0.1.0/README.md +154 -0
- cf_web-0.1.0/pyproject.toml +47 -0
- cf_web-0.1.0/setup.cfg +4 -0
- cf_web-0.1.0/src/cf_web/__init__.py +5 -0
- cf_web-0.1.0/src/cf_web/api/__init__.py +1 -0
- cf_web-0.1.0/src/cf_web/api/routers/__init__.py +3 -0
- cf_web-0.1.0/src/cf_web/api/routers/health.py +13 -0
- cf_web-0.1.0/src/cf_web/api/routers/ontology.py +90 -0
- cf_web-0.1.0/src/cf_web/api/routers/packages.py +53 -0
- cf_web-0.1.0/src/cf_web/api/routers/pipelines.py +75 -0
- cf_web-0.1.0/src/cf_web/api/routers/resource_manager.py +110 -0
- cf_web-0.1.0/src/cf_web/cli.py +157 -0
- cf_web-0.1.0/src/cf_web/config.py +37 -0
- cf_web-0.1.0/src/cf_web/main.py +82 -0
- cf_web-0.1.0/src/cf_web/services/__init__.py +13 -0
- cf_web-0.1.0/src/cf_web/services/manager_provider.py +32 -0
- cf_web-0.1.0/src/cf_web/services/ontology_explorer_service.py +1376 -0
- cf_web-0.1.0/src/cf_web/services/package_template_service.py +908 -0
- cf_web-0.1.0/src/cf_web/services/pipeline_creator_service.py +114 -0
- cf_web-0.1.0/src/cf_web/services/pipeline_service.py +98 -0
- cf_web-0.1.0/src/cf_web/services/resource_manager_service.py +583 -0
- cf_web-0.1.0/src/cf_web/static/assets/index-2NRYpRG3.css +1 -0
- cf_web-0.1.0/src/cf_web/static/assets/index-DZmFkFw8.js +72 -0
- cf_web-0.1.0/src/cf_web/static/favicon.ico +0 -0
- cf_web-0.1.0/src/cf_web/static/index.html +33 -0
- cf_web-0.1.0/src/cf_web.egg-info/PKG-INFO +175 -0
- cf_web-0.1.0/src/cf_web.egg-info/SOURCES.txt +31 -0
- cf_web-0.1.0/src/cf_web.egg-info/dependency_links.txt +1 -0
- cf_web-0.1.0/src/cf_web.egg-info/entry_points.txt +5 -0
- cf_web-0.1.0/src/cf_web.egg-info/requires.txt +17 -0
- cf_web-0.1.0/src/cf_web.egg-info/top_level.txt +1 -0
- cf_web-0.1.0/tests/test_install_surface.py +78 -0
cf_web-0.1.0/PKG-INFO
ADDED
|
@@ -0,0 +1,175 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: cf-web
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Web-based GUI for Cogniflow with FastAPI backend and React frontend
|
|
5
|
+
Requires-Python: >=3.10
|
|
6
|
+
Description-Content-Type: text/markdown
|
|
7
|
+
Requires-Dist: fastapi<1.0,>=0.100
|
|
8
|
+
Requires-Dist: uvicorn[standard]<1.0,>=0.24
|
|
9
|
+
Requires-Dist: pydantic<3.0,>=2.0
|
|
10
|
+
Requires-Dist: cf-ontology>=0.1
|
|
11
|
+
Provides-Extra: test
|
|
12
|
+
Requires-Dist: pytest<9.0,>=8.0; extra == "test"
|
|
13
|
+
Requires-Dist: pytest-asyncio<0.25,>=0.24; extra == "test"
|
|
14
|
+
Requires-Dist: httpx<1.0,>=0.25; extra == "test"
|
|
15
|
+
Provides-Extra: dev
|
|
16
|
+
Requires-Dist: pytest<9.0,>=8.0; extra == "dev"
|
|
17
|
+
Requires-Dist: pytest-asyncio<0.25,>=0.24; extra == "dev"
|
|
18
|
+
Requires-Dist: httpx<1.0,>=0.25; extra == "dev"
|
|
19
|
+
Provides-Extra: pipeline
|
|
20
|
+
Requires-Dist: cf-pipeline-engine>=0.1; extra == "pipeline"
|
|
21
|
+
|
|
22
|
+
# CogniFlow Web
|
|
23
|
+
|
|
24
|
+
`cf_web` is the web application package for CogniFlow. It provides:
|
|
25
|
+
|
|
26
|
+
- a FastAPI backend (`src/cf_web`) exposing ontology/pipeline APIs
|
|
27
|
+
- a React + TypeScript frontend (`frontend`) for ontology exploration and pipeline editing
|
|
28
|
+
- a CLI entrypoint (`cogniflow-web`) to launch the app
|
|
29
|
+
|
|
30
|
+
Published distribution name:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
pip install cf-web
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
Installed launcher surface:
|
|
37
|
+
|
|
38
|
+
```powershell
|
|
39
|
+
cogniflow-web
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The backend reads semantics through `cf_ontology` and its DuckDB quads stores.
|
|
43
|
+
|
|
44
|
+
## Architecture
|
|
45
|
+
|
|
46
|
+
- Backend framework: FastAPI + Uvicorn
|
|
47
|
+
- Frontend framework: React + Vite
|
|
48
|
+
- Semantics source: `cf_ontology.OntologyManager` (quads-backed)
|
|
49
|
+
- Service split:
|
|
50
|
+
- `ontology_explorer_service.py` for ontology explorer payloads
|
|
51
|
+
- `pipeline_creator_service.py` for step DTOs used by the editor
|
|
52
|
+
- `pipeline_service.py` for pipeline list/load/save/validate operations
|
|
53
|
+
|
|
54
|
+
## Install
|
|
55
|
+
|
|
56
|
+
From repository root (recommended in a virtual environment):
|
|
57
|
+
|
|
58
|
+
```powershell
|
|
59
|
+
python -m pip install -e "sandcastle/cf_web[test]"
|
|
60
|
+
```
|
|
61
|
+
|
|
62
|
+
Install with pipeline runtime support:
|
|
63
|
+
|
|
64
|
+
```powershell
|
|
65
|
+
python -m pip install -e "sandcastle/cf_web[test,pipeline]"
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
If you want frontend production assets served by FastAPI, build the frontend first:
|
|
69
|
+
|
|
70
|
+
```powershell
|
|
71
|
+
.\scripts\build_cf_web_frontend.ps1
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
## Run
|
|
75
|
+
|
|
76
|
+
### Option 1: direct app launcher
|
|
77
|
+
|
|
78
|
+
```powershell
|
|
79
|
+
cogniflow-web
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
Disable browser auto-open:
|
|
83
|
+
|
|
84
|
+
```powershell
|
|
85
|
+
cogniflow-web --no-browser
|
|
86
|
+
```
|
|
87
|
+
|
|
88
|
+
### Option 2: unified CLI
|
|
89
|
+
|
|
90
|
+
```powershell
|
|
91
|
+
cf web start
|
|
92
|
+
```
|
|
93
|
+
|
|
94
|
+
or
|
|
95
|
+
|
|
96
|
+
```powershell
|
|
97
|
+
cf web start --no-browser
|
|
98
|
+
```
|
|
99
|
+
|
|
100
|
+
## Backend API
|
|
101
|
+
|
|
102
|
+
Key routes:
|
|
103
|
+
|
|
104
|
+
- `GET /api/health`
|
|
105
|
+
- `GET /api/ontology/graph`
|
|
106
|
+
- `GET /api/ontology/dataset`
|
|
107
|
+
- `GET /api/ontology/dashboard`
|
|
108
|
+
- `GET /api/ontology/steps`
|
|
109
|
+
- `GET /api/ontology/steps/{step_id}`
|
|
110
|
+
- `GET /api/pipelines/`
|
|
111
|
+
- `GET /api/pipelines/{pipeline_id}?rev={n}`
|
|
112
|
+
- `POST /api/pipelines/save`
|
|
113
|
+
- `POST /api/pipelines/validate`
|
|
114
|
+
|
|
115
|
+
## Configuration
|
|
116
|
+
|
|
117
|
+
`cf_web` reads these environment variables:
|
|
118
|
+
|
|
119
|
+
- `CF_WEB_HOST` (default: `127.0.0.1`)
|
|
120
|
+
- `CF_WEB_PORT` (default: `8000`)
|
|
121
|
+
- `CF_WEB_RELOAD` (`1` enables reload, default: `0`)
|
|
122
|
+
- `CF_WEB_DEBUG` (`1` enables debug flag, default: `0`)
|
|
123
|
+
- `CF_WORKSPACE_DIR` (default: `~/.cogniflow/workspace`)
|
|
124
|
+
- `CF_SEMANTICS_DIR` (default: `<workspace>/semantics`)
|
|
125
|
+
|
|
126
|
+
By default the launcher sets:
|
|
127
|
+
|
|
128
|
+
- `CF_ENABLE_STEP_PACKAGES=1`
|
|
129
|
+
|
|
130
|
+
so installed step packages are ingested/discovered for UI usage.
|
|
131
|
+
|
|
132
|
+
## Development Notes
|
|
133
|
+
|
|
134
|
+
- Frontend source of truth is under `frontend/src`.
|
|
135
|
+
- Built frontend files are emitted to `src/cf_web/static` by Vite.
|
|
136
|
+
- The publish workflow packages the checked-in `src/cf_web/static` bundle and does not run a frontend build step.
|
|
137
|
+
- Backend services use a shared `OntologyManager` provider (`manager_provider.py`) to avoid repeated manager instantiation.
|
|
138
|
+
|
|
139
|
+
## Publishing
|
|
140
|
+
|
|
141
|
+
`cf_web` is published with the dedicated Windows workflow:
|
|
142
|
+
|
|
143
|
+
- Workflow: `.github/workflows/cf_web_windows_publish.yml`
|
|
144
|
+
- Package directory: `sandcastle/cf_web`
|
|
145
|
+
- Published distribution: `cf-web`
|
|
146
|
+
- PyPI tag: `cf-web-v<version>`
|
|
147
|
+
- TestPyPI tag: `cf-web-v<version>-test`
|
|
148
|
+
|
|
149
|
+
Local preflight:
|
|
150
|
+
|
|
151
|
+
```powershell
|
|
152
|
+
powershell -ExecutionPolicy Bypass -File scripts/mimic_windows_python_publish_workflow.ps1 `
|
|
153
|
+
-WorkflowFile .github/workflows/cf_web_windows_publish.yml `
|
|
154
|
+
-PackageDir sandcastle/cf_web `
|
|
155
|
+
-PythonExe py `
|
|
156
|
+
-PythonVersion 3.13
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
Queue a dry-run dispatch:
|
|
160
|
+
|
|
161
|
+
```powershell
|
|
162
|
+
powershell -ExecutionPolicy Bypass -File scripts/queue_windows_python_publish_workflow.ps1 `
|
|
163
|
+
-WorkflowFile .github/workflows/cf_web_windows_publish.yml `
|
|
164
|
+
-PackageDir sandcastle/cf_web `
|
|
165
|
+
-PublishTarget testpypi `
|
|
166
|
+
-Ref main `
|
|
167
|
+
-RequireLocalPass `
|
|
168
|
+
-DryRun
|
|
169
|
+
```
|
|
170
|
+
|
|
171
|
+
## Troubleshooting
|
|
172
|
+
|
|
173
|
+
- `GET /favicon.ico 404`: ensure favicon exists in `src/cf_web/static/favicon.ico` and frontend was rebuilt.
|
|
174
|
+
- App opens but says frontend build missing: run `.\scripts\build_cf_web_frontend.ps1`.
|
|
175
|
+
- No steps visible in UI: ensure step packages are installed and `CF_ENABLE_STEP_PACKAGES=1` (default via launcher).
|
cf_web-0.1.0/README.md
ADDED
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
# CogniFlow Web
|
|
2
|
+
|
|
3
|
+
`cf_web` is the web application package for CogniFlow. It provides:
|
|
4
|
+
|
|
5
|
+
- a FastAPI backend (`src/cf_web`) exposing ontology/pipeline APIs
|
|
6
|
+
- a React + TypeScript frontend (`frontend`) for ontology exploration and pipeline editing
|
|
7
|
+
- a CLI entrypoint (`cogniflow-web`) to launch the app
|
|
8
|
+
|
|
9
|
+
Published distribution name:
|
|
10
|
+
|
|
11
|
+
```bash
|
|
12
|
+
pip install cf-web
|
|
13
|
+
```
|
|
14
|
+
|
|
15
|
+
Installed launcher surface:
|
|
16
|
+
|
|
17
|
+
```powershell
|
|
18
|
+
cogniflow-web
|
|
19
|
+
```
|
|
20
|
+
|
|
21
|
+
The backend reads semantics through `cf_ontology` and its DuckDB quads stores.
|
|
22
|
+
|
|
23
|
+
## Architecture
|
|
24
|
+
|
|
25
|
+
- Backend framework: FastAPI + Uvicorn
|
|
26
|
+
- Frontend framework: React + Vite
|
|
27
|
+
- Semantics source: `cf_ontology.OntologyManager` (quads-backed)
|
|
28
|
+
- Service split:
|
|
29
|
+
- `ontology_explorer_service.py` for ontology explorer payloads
|
|
30
|
+
- `pipeline_creator_service.py` for step DTOs used by the editor
|
|
31
|
+
- `pipeline_service.py` for pipeline list/load/save/validate operations
|
|
32
|
+
|
|
33
|
+
## Install
|
|
34
|
+
|
|
35
|
+
From repository root (recommended in a virtual environment):
|
|
36
|
+
|
|
37
|
+
```powershell
|
|
38
|
+
python -m pip install -e "sandcastle/cf_web[test]"
|
|
39
|
+
```
|
|
40
|
+
|
|
41
|
+
Install with pipeline runtime support:
|
|
42
|
+
|
|
43
|
+
```powershell
|
|
44
|
+
python -m pip install -e "sandcastle/cf_web[test,pipeline]"
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
If you want frontend production assets served by FastAPI, build the frontend first:
|
|
48
|
+
|
|
49
|
+
```powershell
|
|
50
|
+
.\scripts\build_cf_web_frontend.ps1
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
## Run
|
|
54
|
+
|
|
55
|
+
### Option 1: direct app launcher
|
|
56
|
+
|
|
57
|
+
```powershell
|
|
58
|
+
cogniflow-web
|
|
59
|
+
```
|
|
60
|
+
|
|
61
|
+
Disable browser auto-open:
|
|
62
|
+
|
|
63
|
+
```powershell
|
|
64
|
+
cogniflow-web --no-browser
|
|
65
|
+
```
|
|
66
|
+
|
|
67
|
+
### Option 2: unified CLI
|
|
68
|
+
|
|
69
|
+
```powershell
|
|
70
|
+
cf web start
|
|
71
|
+
```
|
|
72
|
+
|
|
73
|
+
or
|
|
74
|
+
|
|
75
|
+
```powershell
|
|
76
|
+
cf web start --no-browser
|
|
77
|
+
```
|
|
78
|
+
|
|
79
|
+
## Backend API
|
|
80
|
+
|
|
81
|
+
Key routes:
|
|
82
|
+
|
|
83
|
+
- `GET /api/health`
|
|
84
|
+
- `GET /api/ontology/graph`
|
|
85
|
+
- `GET /api/ontology/dataset`
|
|
86
|
+
- `GET /api/ontology/dashboard`
|
|
87
|
+
- `GET /api/ontology/steps`
|
|
88
|
+
- `GET /api/ontology/steps/{step_id}`
|
|
89
|
+
- `GET /api/pipelines/`
|
|
90
|
+
- `GET /api/pipelines/{pipeline_id}?rev={n}`
|
|
91
|
+
- `POST /api/pipelines/save`
|
|
92
|
+
- `POST /api/pipelines/validate`
|
|
93
|
+
|
|
94
|
+
## Configuration
|
|
95
|
+
|
|
96
|
+
`cf_web` reads these environment variables:
|
|
97
|
+
|
|
98
|
+
- `CF_WEB_HOST` (default: `127.0.0.1`)
|
|
99
|
+
- `CF_WEB_PORT` (default: `8000`)
|
|
100
|
+
- `CF_WEB_RELOAD` (`1` enables reload, default: `0`)
|
|
101
|
+
- `CF_WEB_DEBUG` (`1` enables debug flag, default: `0`)
|
|
102
|
+
- `CF_WORKSPACE_DIR` (default: `~/.cogniflow/workspace`)
|
|
103
|
+
- `CF_SEMANTICS_DIR` (default: `<workspace>/semantics`)
|
|
104
|
+
|
|
105
|
+
By default the launcher sets:
|
|
106
|
+
|
|
107
|
+
- `CF_ENABLE_STEP_PACKAGES=1`
|
|
108
|
+
|
|
109
|
+
so installed step packages are ingested/discovered for UI usage.
|
|
110
|
+
|
|
111
|
+
## Development Notes
|
|
112
|
+
|
|
113
|
+
- Frontend source of truth is under `frontend/src`.
|
|
114
|
+
- Built frontend files are emitted to `src/cf_web/static` by Vite.
|
|
115
|
+
- The publish workflow packages the checked-in `src/cf_web/static` bundle and does not run a frontend build step.
|
|
116
|
+
- Backend services use a shared `OntologyManager` provider (`manager_provider.py`) to avoid repeated manager instantiation.
|
|
117
|
+
|
|
118
|
+
## Publishing
|
|
119
|
+
|
|
120
|
+
`cf_web` is published with the dedicated Windows workflow:
|
|
121
|
+
|
|
122
|
+
- Workflow: `.github/workflows/cf_web_windows_publish.yml`
|
|
123
|
+
- Package directory: `sandcastle/cf_web`
|
|
124
|
+
- Published distribution: `cf-web`
|
|
125
|
+
- PyPI tag: `cf-web-v<version>`
|
|
126
|
+
- TestPyPI tag: `cf-web-v<version>-test`
|
|
127
|
+
|
|
128
|
+
Local preflight:
|
|
129
|
+
|
|
130
|
+
```powershell
|
|
131
|
+
powershell -ExecutionPolicy Bypass -File scripts/mimic_windows_python_publish_workflow.ps1 `
|
|
132
|
+
-WorkflowFile .github/workflows/cf_web_windows_publish.yml `
|
|
133
|
+
-PackageDir sandcastle/cf_web `
|
|
134
|
+
-PythonExe py `
|
|
135
|
+
-PythonVersion 3.13
|
|
136
|
+
```
|
|
137
|
+
|
|
138
|
+
Queue a dry-run dispatch:
|
|
139
|
+
|
|
140
|
+
```powershell
|
|
141
|
+
powershell -ExecutionPolicy Bypass -File scripts/queue_windows_python_publish_workflow.ps1 `
|
|
142
|
+
-WorkflowFile .github/workflows/cf_web_windows_publish.yml `
|
|
143
|
+
-PackageDir sandcastle/cf_web `
|
|
144
|
+
-PublishTarget testpypi `
|
|
145
|
+
-Ref main `
|
|
146
|
+
-RequireLocalPass `
|
|
147
|
+
-DryRun
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## Troubleshooting
|
|
151
|
+
|
|
152
|
+
- `GET /favicon.ico 404`: ensure favicon exists in `src/cf_web/static/favicon.ico` and frontend was rebuilt.
|
|
153
|
+
- App opens but says frontend build missing: run `.\scripts\build_cf_web_frontend.ps1`.
|
|
154
|
+
- No steps visible in UI: ensure step packages are installed and `CF_ENABLE_STEP_PACKAGES=1` (default via launcher).
|
|
@@ -0,0 +1,47 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=70"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "cf-web"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Web-based GUI for Cogniflow with FastAPI backend and React frontend"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
dependencies = [
|
|
12
|
+
"fastapi>=0.100,<1.0",
|
|
13
|
+
"uvicorn[standard]>=0.24,<1.0",
|
|
14
|
+
"pydantic>=2.0,<3.0",
|
|
15
|
+
"cf-ontology>=0.1",
|
|
16
|
+
]
|
|
17
|
+
|
|
18
|
+
[project.optional-dependencies]
|
|
19
|
+
test = [
|
|
20
|
+
"pytest>=8.0,<9.0",
|
|
21
|
+
"pytest-asyncio>=0.24,<0.25",
|
|
22
|
+
"httpx>=0.25,<1.0",
|
|
23
|
+
]
|
|
24
|
+
dev = [
|
|
25
|
+
"pytest>=8.0,<9.0",
|
|
26
|
+
"pytest-asyncio>=0.24,<0.25",
|
|
27
|
+
"httpx>=0.25,<1.0",
|
|
28
|
+
]
|
|
29
|
+
pipeline = [
|
|
30
|
+
"cf-pipeline-engine>=0.1",
|
|
31
|
+
]
|
|
32
|
+
|
|
33
|
+
[project.scripts]
|
|
34
|
+
cogniflow-web = "cf_web.cli:main"
|
|
35
|
+
|
|
36
|
+
[project.entry-points."cogniflow.cli"]
|
|
37
|
+
web = "cf_web.cli:register_cli"
|
|
38
|
+
|
|
39
|
+
[tool.setuptools]
|
|
40
|
+
package-dir = {"" = "src"}
|
|
41
|
+
include-package-data = true
|
|
42
|
+
|
|
43
|
+
[tool.setuptools.packages.find]
|
|
44
|
+
where = ["src"]
|
|
45
|
+
|
|
46
|
+
[tool.setuptools.package-data]
|
|
47
|
+
cf_web = ["static/*", "static/**/*"]
|
cf_web-0.1.0/setup.cfg
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
"""API package."""
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
"""Health endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from fastapi import APIRouter
|
|
6
|
+
|
|
7
|
+
router = APIRouter()
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
@router.get("/health")
|
|
11
|
+
async def healthcheck() -> dict[str, str]:
|
|
12
|
+
"""Return liveness status for API health probing."""
|
|
13
|
+
return {"status": "ok"}
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
"""Ontology endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Optional
|
|
6
|
+
|
|
7
|
+
from fastapi import APIRouter, HTTPException
|
|
8
|
+
|
|
9
|
+
from cf_web.services.pipeline_creator_service import PipelineCreatorService
|
|
10
|
+
from cf_web.services.ontology_explorer_service import OntologyExplorerService
|
|
11
|
+
|
|
12
|
+
router = APIRouter()
|
|
13
|
+
pipeline_creator_service = PipelineCreatorService()
|
|
14
|
+
ontology_explorer_service = OntologyExplorerService()
|
|
15
|
+
|
|
16
|
+
|
|
17
|
+
@router.get("/graph")
|
|
18
|
+
async def get_graph() -> dict[str, object]:
|
|
19
|
+
"""Return ontology explorer graph payload."""
|
|
20
|
+
return {"jsonld": ontology_explorer_service.get_graph()}
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
@router.get("/dataset")
|
|
24
|
+
async def get_dataset() -> dict[str, object]:
|
|
25
|
+
"""Return ontology dataset payload."""
|
|
26
|
+
return {"jsonld": ontology_explorer_service.get_dataset()}
|
|
27
|
+
|
|
28
|
+
|
|
29
|
+
@router.get("/steps")
|
|
30
|
+
async def list_steps() -> dict[str, object]:
|
|
31
|
+
"""List processing-step DTOs for pipeline creation."""
|
|
32
|
+
return {"steps": pipeline_creator_service.get_steps()}
|
|
33
|
+
|
|
34
|
+
|
|
35
|
+
@router.get("/steps/{step_id}")
|
|
36
|
+
async def get_step(step_id: str) -> dict[str, object]:
|
|
37
|
+
"""Return one processing-step DTO by id or alias."""
|
|
38
|
+
step = pipeline_creator_service.get_step(step_id)
|
|
39
|
+
if not step:
|
|
40
|
+
raise HTTPException(status_code=404, detail="Step not found")
|
|
41
|
+
return {"step": step}
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
@router.get("/step-builder-options")
|
|
45
|
+
async def get_step_builder_options() -> dict[str, object]:
|
|
46
|
+
"""Return ontology-derived dropdown options for the package creator step builder."""
|
|
47
|
+
return pipeline_creator_service.get_step_builder_options()
|
|
48
|
+
|
|
49
|
+
|
|
50
|
+
@router.get("/dashboard")
|
|
51
|
+
async def get_dashboard() -> dict[str, object]:
|
|
52
|
+
"""Return ontology dashboard graph data."""
|
|
53
|
+
return {"graphs": ontology_explorer_service.get_dashboard_graphs()}
|
|
54
|
+
|
|
55
|
+
|
|
56
|
+
@router.get("/datatypes")
|
|
57
|
+
async def get_datatypes_graph() -> dict[str, object]:
|
|
58
|
+
"""Return the virtual datatypes graph payload."""
|
|
59
|
+
return {"graph": ontology_explorer_service.get_datatypes_graph()}
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
@router.get("/node-quads")
|
|
63
|
+
async def get_node_quads(
|
|
64
|
+
node_id: str,
|
|
65
|
+
graph_id: Optional[str] = None,
|
|
66
|
+
aliases: Optional[str] = None,
|
|
67
|
+
limit: int = 200,
|
|
68
|
+
) -> dict[str, object]:
|
|
69
|
+
"""Return raw quads for one selected node id/alias."""
|
|
70
|
+
alias_items = [item for item in (aliases or "").split(",") if item]
|
|
71
|
+
return {
|
|
72
|
+
"quads": ontology_explorer_service.get_node_quads(
|
|
73
|
+
node_id=node_id,
|
|
74
|
+
graph_id=graph_id,
|
|
75
|
+
aliases=alias_items,
|
|
76
|
+
limit=limit,
|
|
77
|
+
)
|
|
78
|
+
}
|
|
79
|
+
|
|
80
|
+
|
|
81
|
+
@router.get("/diagnostics")
|
|
82
|
+
async def get_diagnostics() -> dict[str, object]:
|
|
83
|
+
"""Return read-only diagnostics for ontology graph/quads quality checks."""
|
|
84
|
+
return ontology_explorer_service.get_diagnostics_report()
|
|
85
|
+
|
|
86
|
+
|
|
87
|
+
@router.post("/diagnostics/run")
|
|
88
|
+
async def run_diagnostics() -> dict[str, object]:
|
|
89
|
+
"""Run comprehensive diagnostics across semantics DuckDB quad stores."""
|
|
90
|
+
return ontology_explorer_service.run_comprehensive_diagnostics()
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
"""Package template endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
import base64
|
|
6
|
+
|
|
7
|
+
from fastapi import APIRouter, HTTPException
|
|
8
|
+
from fastapi.responses import StreamingResponse
|
|
9
|
+
|
|
10
|
+
from cf_web.services.package_template_service import (
|
|
11
|
+
PackageTemplateRequest,
|
|
12
|
+
PackageTemplateService,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
router = APIRouter()
|
|
16
|
+
service = PackageTemplateService()
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@router.post("/template")
|
|
20
|
+
async def create_package_template(payload: PackageTemplateRequest) -> StreamingResponse:
|
|
21
|
+
"""Generate a package template archive and return as a download."""
|
|
22
|
+
try:
|
|
23
|
+
result = service.create_template(payload)
|
|
24
|
+
except RuntimeError as exc:
|
|
25
|
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
26
|
+
except ValueError as exc:
|
|
27
|
+
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
|
28
|
+
|
|
29
|
+
headers = {"Content-Disposition": f'attachment; filename="{result.filename}"'}
|
|
30
|
+
return StreamingResponse(
|
|
31
|
+
iter([result.content]),
|
|
32
|
+
media_type="application/zip",
|
|
33
|
+
headers=headers,
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@router.post("/template/build")
|
|
38
|
+
async def build_package_template(payload: PackageTemplateRequest) -> dict[str, object]:
|
|
39
|
+
"""Generate a package template and return zip payload plus validation report."""
|
|
40
|
+
try:
|
|
41
|
+
result = service.create_template(payload)
|
|
42
|
+
except RuntimeError as exc:
|
|
43
|
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
44
|
+
except ValueError as exc:
|
|
45
|
+
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
|
46
|
+
|
|
47
|
+
return {
|
|
48
|
+
"filename": result.filename,
|
|
49
|
+
"zip_base64": base64.b64encode(result.content).decode("ascii"),
|
|
50
|
+
"validation_report": result.validation_report,
|
|
51
|
+
"generated_files": result.generated_files,
|
|
52
|
+
"generated_at_utc": result.generated_at_utc,
|
|
53
|
+
}
|
|
@@ -0,0 +1,75 @@
|
|
|
1
|
+
"""Pipeline endpoints."""
|
|
2
|
+
|
|
3
|
+
from __future__ import annotations
|
|
4
|
+
|
|
5
|
+
from typing import Any, Optional
|
|
6
|
+
|
|
7
|
+
from fastapi import APIRouter, HTTPException
|
|
8
|
+
from pydantic import BaseModel, Field
|
|
9
|
+
|
|
10
|
+
from cf_web.services.pipeline_service import PipelineService
|
|
11
|
+
|
|
12
|
+
router = APIRouter()
|
|
13
|
+
service = PipelineService()
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
class SavePipelineRequest(BaseModel):
|
|
17
|
+
"""Payload for saving a pipeline revision."""
|
|
18
|
+
|
|
19
|
+
pipeline_id: str = Field(min_length=1)
|
|
20
|
+
jsonld: dict[str, Any]
|
|
21
|
+
user: Optional[str] = None
|
|
22
|
+
message: Optional[str] = None
|
|
23
|
+
|
|
24
|
+
|
|
25
|
+
class ValidatePipelineRequest(BaseModel):
|
|
26
|
+
"""Payload for validating pipeline JSON-LD."""
|
|
27
|
+
|
|
28
|
+
jsonld: dict[str, Any]
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
@router.get("/")
|
|
32
|
+
async def list_pipelines() -> dict[str, list[dict[str, Any]]]:
|
|
33
|
+
"""List stored pipelines with current revision metadata."""
|
|
34
|
+
return {"pipelines": service.list_pipelines()}
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
@router.get("/{pipeline_id}")
|
|
38
|
+
async def load_pipeline(pipeline_id: str, rev: Optional[int] = None) -> dict[str, object]:
|
|
39
|
+
"""Load a pipeline by id, optionally for a specific revision."""
|
|
40
|
+
try:
|
|
41
|
+
jsonld = service.get_pipeline(pipeline_id, rev=rev)
|
|
42
|
+
except KeyError as exc:
|
|
43
|
+
raise HTTPException(status_code=404, detail=str(exc)) from exc
|
|
44
|
+
except RuntimeError as exc:
|
|
45
|
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
46
|
+
return {"pipeline_id": pipeline_id, "rev": rev, "jsonld": jsonld}
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
@router.post("/save")
|
|
50
|
+
async def save_pipeline(payload: SavePipelineRequest) -> dict[str, object]:
|
|
51
|
+
"""Commit a pipeline revision to the pipeline store."""
|
|
52
|
+
try:
|
|
53
|
+
result = service.save_pipeline(
|
|
54
|
+
pipeline_id=payload.pipeline_id,
|
|
55
|
+
jsonld=payload.jsonld,
|
|
56
|
+
user=payload.user,
|
|
57
|
+
message=payload.message,
|
|
58
|
+
)
|
|
59
|
+
except RuntimeError as exc:
|
|
60
|
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
61
|
+
except ValueError as exc:
|
|
62
|
+
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
|
63
|
+
return result
|
|
64
|
+
|
|
65
|
+
|
|
66
|
+
@router.post("/validate")
|
|
67
|
+
async def validate_pipeline(payload: ValidatePipelineRequest) -> dict[str, object]:
|
|
68
|
+
"""Validate pipeline JSON-LD and return validation diagnostics."""
|
|
69
|
+
try:
|
|
70
|
+
result = service.validate_pipeline(payload.jsonld)
|
|
71
|
+
except RuntimeError as exc:
|
|
72
|
+
raise HTTPException(status_code=503, detail=str(exc)) from exc
|
|
73
|
+
except ValueError as exc:
|
|
74
|
+
raise HTTPException(status_code=422, detail=str(exc)) from exc
|
|
75
|
+
return result
|