urisys 0.1.11__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.
- urisys-0.1.11/PKG-INFO +161 -0
- urisys-0.1.11/README.md +133 -0
- urisys-0.1.11/pyproject.toml +103 -0
- urisys-0.1.11/setup.cfg +4 -0
- urisys-0.1.11/src/urisys/__init__.py +3 -0
- urisys-0.1.11/src/urisys/cli.py +176 -0
- urisys-0.1.11/src/urisys/controllers/__init__.py +0 -0
- urisys-0.1.11/src/urisys/controllers/flow_controller.py +33 -0
- urisys-0.1.11/src/urisys/controllers/server_controller.py +18 -0
- urisys-0.1.11/src/urisys/controllers/uri_controller.py +33 -0
- urisys-0.1.11/src/urisys/defaults.py +18 -0
- urisys-0.1.11/src/urisys/flow.py +25 -0
- urisys-0.1.11/src/urisys/http_server.py +78 -0
- urisys-0.1.11/src/urisys/managers/__init__.py +0 -0
- urisys-0.1.11/src/urisys/managers/bridge_manager.py +14 -0
- urisys-0.1.11/src/urisys/managers/event_manager.py +13 -0
- urisys-0.1.11/src/urisys/managers/markpact_manager.py +579 -0
- urisys-0.1.11/src/urisys/managers/pack_manager.py +97 -0
- urisys-0.1.11/src/urisys/managers/policy_manager.py +18 -0
- urisys-0.1.11/src/urisys/managers/route_manager.py +23 -0
- urisys-0.1.11/src/urisys/managers/runtime_manager.py +30 -0
- urisys-0.1.11/src/urisys/managers/source_manager.py +224 -0
- urisys-0.1.11/src/urisys.egg-info/PKG-INFO +161 -0
- urisys-0.1.11/src/urisys.egg-info/SOURCES.txt +29 -0
- urisys-0.1.11/src/urisys.egg-info/dependency_links.txt +1 -0
- urisys-0.1.11/src/urisys.egg-info/entry_points.txt +2 -0
- urisys-0.1.11/src/urisys.egg-info/requires.txt +14 -0
- urisys-0.1.11/src/urisys.egg-info/top_level.txt +1 -0
- urisys-0.1.11/tests/test_markpact.py +80 -0
- urisys-0.1.11/tests/test_source_manager.py +35 -0
- urisys-0.1.11/tests/test_urisys.py +24 -0
urisys-0.1.11/PKG-INFO
ADDED
|
@@ -0,0 +1,161 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: urisys
|
|
3
|
+
Version: 0.1.11
|
|
4
|
+
Summary: URI control system managers/controllers over separate uri* capability packs.
|
|
5
|
+
Author: urisys contributors
|
|
6
|
+
Author-email: Tom Sapletta <tom@sapletta.com>
|
|
7
|
+
License-Expression: Apache-2.0
|
|
8
|
+
Keywords: uri,control-plane,controllers,managers,devices,services
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
14
|
+
Requires-Python: >=3.10
|
|
15
|
+
Description-Content-Type: text/markdown
|
|
16
|
+
Requires-Dist: uricore>=0.1.0
|
|
17
|
+
Requires-Dist: PyYAML>=6.0
|
|
18
|
+
Provides-Extra: dev
|
|
19
|
+
Requires-Dist: pytest>=8.0; extra == "dev"
|
|
20
|
+
Requires-Dist: uricore; extra == "dev"
|
|
21
|
+
Requires-Dist: uribrowser; extra == "dev"
|
|
22
|
+
Requires-Dist: uridocker; extra == "dev"
|
|
23
|
+
Requires-Dist: goal>=2.1.0; extra == "dev"
|
|
24
|
+
Requires-Dist: costs>=0.1.20; extra == "dev"
|
|
25
|
+
Requires-Dist: pfix>=0.1.60; extra == "dev"
|
|
26
|
+
Provides-Extra: lab
|
|
27
|
+
Requires-Dist: uri2flow>=0.1.2; extra == "lab"
|
|
28
|
+
|
|
29
|
+
# urisys
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
## AI Cost Tracking
|
|
33
|
+
|
|
34
|
+
   
|
|
35
|
+
  
|
|
36
|
+
|
|
37
|
+
- 🤖 **LLM usage:** $3.9320 (19 commits)
|
|
38
|
+
- 👤 **Human dev:** ~$891 (8.9h @ $100/h, 30min dedup)
|
|
39
|
+
|
|
40
|
+
Generated on 2026-06-16 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
41
|
+
|
|
42
|
+
---
|
|
43
|
+
|
|
44
|
+
Centralny **URI control plane** dla TellMesh: CLI (`urisys`), managers, Markpact oraz monorepo obrazów Docker z edge runtime.
|
|
45
|
+
|
|
46
|
+
## Instalacja
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install urisys
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
### Dev (checkout tellmesh)
|
|
53
|
+
|
|
54
|
+
Wymaga checkout **tellmesh** (urisys obok `uricore/`, `uri-packs/`, opcjonalnie `nl2uri/`, `uri2flow/`).
|
|
55
|
+
|
|
56
|
+
```bash
|
|
57
|
+
cd tellmesh/urisys
|
|
58
|
+
|
|
59
|
+
# wirtualne środowisko (poprawna składnia — NIE komenda `venv`)
|
|
60
|
+
python3 -m venv .venv
|
|
61
|
+
source .venv/bin/activate
|
|
62
|
+
|
|
63
|
+
# zalecane: uv (lockfile)
|
|
64
|
+
uv sync
|
|
65
|
+
|
|
66
|
+
# alternatywa bez uv:
|
|
67
|
+
pip install -e ".[dev]"
|
|
68
|
+
pip install -e ../uricore # sibling w tellmesh workspace
|
|
69
|
+
```
|
|
70
|
+
|
|
71
|
+
Po instalacji CLI:
|
|
72
|
+
|
|
73
|
+
```bash
|
|
74
|
+
urisys --help
|
|
75
|
+
which urisys # → .venv/bin/urisys
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Zależności runtime: **`uricore`** (PyPI `uricore>=0.1.2` lub editable `../uricore`), paczki URI z **`uri-packs`** (dev group w `pyproject.toml`).
|
|
79
|
+
|
|
80
|
+
## Szybki start
|
|
81
|
+
|
|
82
|
+
```bash
|
|
83
|
+
cd urisys && uv sync
|
|
84
|
+
|
|
85
|
+
# Pojedyncze URI (paczki z uri-packs)
|
|
86
|
+
urisys --packs browser call browser://default/page/open \
|
|
87
|
+
--payload '{"url":"https://example.com"}' --approve
|
|
88
|
+
|
|
89
|
+
# Flow mock
|
|
90
|
+
urisys --packs all flow flows/device-maintenance.uri.flow.yaml --approve --dry-run
|
|
91
|
+
|
|
92
|
+
# HTTP server
|
|
93
|
+
urisys --packs all serve --port 8789
|
|
94
|
+
```
|
|
95
|
+
|
|
96
|
+
## Docker lab (10 automatyzacji + RDP)
|
|
97
|
+
|
|
98
|
+
```bash
|
|
99
|
+
cd urisys-automation-lab
|
|
100
|
+
bash scripts/docker-up.sh
|
|
101
|
+
bash scripts/docker-smoke.sh
|
|
102
|
+
|
|
103
|
+
# Pełny test E2E
|
|
104
|
+
python3 scripts/run_test_sessions.py --sessions lab-10-flows
|
|
105
|
+
# lub: bash scripts/run-lab-e2e.sh
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Dokumentacja
|
|
109
|
+
|
|
110
|
+
| Dokument | Temat |
|
|
111
|
+
|----------|--------|
|
|
112
|
+
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Jak działa urisys — warstwy, runtime, testy |
|
|
113
|
+
| [`docs/PACKAGES.md`](docs/PACKAGES.md) | Layout monorepo, duplikaty, plan konsolidacji |
|
|
114
|
+
| [`docs/FLOWS.md`](docs/FLOWS.md) | URI flows, zależności, walidacja |
|
|
115
|
+
| [`docs/EXAMPLES.md`](docs/EXAMPLES.md) | Przykłady shell/frontend/Docker |
|
|
116
|
+
| [`docs/CLI.md`](docs/CLI.md) | Komendy CLI |
|
|
117
|
+
| [`docs/MARKPACT.md`](docs/MARKPACT.md) | Markpact validate/compile/test |
|
|
118
|
+
| [`project/MAP.md`](project/MAP.md) | Przewodnik po `map.toon.yaml` (code2llm) |
|
|
119
|
+
| [`project/PACKAGES.md`](project/PACKAGES.md) | Indeks paczek sync z mapÄ… |
|
|
120
|
+
|
|
121
|
+
## Struktura monorepo
|
|
122
|
+
|
|
123
|
+
```text
|
|
124
|
+
src/urisys/ pip package — CLI + managers
|
|
125
|
+
packages/python/urisysedge/ wspólny edge runtime (canonical)
|
|
126
|
+
urirdp-docker/ RDP + KVM/HIM/OCR/LLM/shell/browser
|
|
127
|
+
urisys-automation-lab/ 10 flows, lab UI :8099
|
|
128
|
+
urisys-node/ slave node + ArtifactResolver
|
|
129
|
+
local-lab/ markpact.com release chain
|
|
130
|
+
flows/ przykład flow dla CLI
|
|
131
|
+
examples/ shell + frontend
|
|
132
|
+
markpacts/packs/ Markpact do walidacji
|
|
133
|
+
scripts/ test sessions, validate-all-markpacts
|
|
134
|
+
```
|
|
135
|
+
|
|
136
|
+
## Managers
|
|
137
|
+
|
|
138
|
+
- `PackManager` — paczki `uri*`, manifest.yaml, Markpact
|
|
139
|
+
- `MarkpactManager` — validate / compile / test `*.markpact.md`
|
|
140
|
+
- `RuntimeManager` — `uri_control.UriControlRuntime`
|
|
141
|
+
- `UriController` — call, explain, routes
|
|
142
|
+
- `FlowController` — sekwencyjne `*.uri.flow.yaml`
|
|
143
|
+
- `BridgeManager` — forward do zdalnego `/uri/call`
|
|
144
|
+
|
|
145
|
+
## Markpact
|
|
146
|
+
|
|
147
|
+
```bash
|
|
148
|
+
urisys markpact validate markpacts/packs/uribrowser.markpact.md
|
|
149
|
+
bash scripts/validate-all-markpacts.sh
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## Analiza projektu (code2llm)
|
|
153
|
+
|
|
154
|
+
```bash
|
|
155
|
+
code2llm ./ -f all -o ./project
|
|
156
|
+
# → project/map.toon.yaml, calls.mmd, context.md
|
|
157
|
+
```
|
|
158
|
+
|
|
159
|
+
## License
|
|
160
|
+
|
|
161
|
+
Licensed under Apache-2.0.
|
urisys-0.1.11/README.md
ADDED
|
@@ -0,0 +1,133 @@
|
|
|
1
|
+
# urisys
|
|
2
|
+
|
|
3
|
+
|
|
4
|
+
## AI Cost Tracking
|
|
5
|
+
|
|
6
|
+
   
|
|
7
|
+
  
|
|
8
|
+
|
|
9
|
+
- 🤖 **LLM usage:** $3.9320 (19 commits)
|
|
10
|
+
- 👤 **Human dev:** ~$891 (8.9h @ $100/h, 30min dedup)
|
|
11
|
+
|
|
12
|
+
Generated on 2026-06-16 using [openrouter/qwen/qwen3-coder-next](https://openrouter.ai/qwen/qwen3-coder-next)
|
|
13
|
+
|
|
14
|
+
---
|
|
15
|
+
|
|
16
|
+
Centralny **URI control plane** dla TellMesh: CLI (`urisys`), managers, Markpact oraz monorepo obrazów Docker z edge runtime.
|
|
17
|
+
|
|
18
|
+
## Instalacja
|
|
19
|
+
|
|
20
|
+
```bash
|
|
21
|
+
pip install urisys
|
|
22
|
+
```
|
|
23
|
+
|
|
24
|
+
### Dev (checkout tellmesh)
|
|
25
|
+
|
|
26
|
+
Wymaga checkout **tellmesh** (urisys obok `uricore/`, `uri-packs/`, opcjonalnie `nl2uri/`, `uri2flow/`).
|
|
27
|
+
|
|
28
|
+
```bash
|
|
29
|
+
cd tellmesh/urisys
|
|
30
|
+
|
|
31
|
+
# wirtualne środowisko (poprawna składnia — NIE komenda `venv`)
|
|
32
|
+
python3 -m venv .venv
|
|
33
|
+
source .venv/bin/activate
|
|
34
|
+
|
|
35
|
+
# zalecane: uv (lockfile)
|
|
36
|
+
uv sync
|
|
37
|
+
|
|
38
|
+
# alternatywa bez uv:
|
|
39
|
+
pip install -e ".[dev]"
|
|
40
|
+
pip install -e ../uricore # sibling w tellmesh workspace
|
|
41
|
+
```
|
|
42
|
+
|
|
43
|
+
Po instalacji CLI:
|
|
44
|
+
|
|
45
|
+
```bash
|
|
46
|
+
urisys --help
|
|
47
|
+
which urisys # → .venv/bin/urisys
|
|
48
|
+
```
|
|
49
|
+
|
|
50
|
+
Zależności runtime: **`uricore`** (PyPI `uricore>=0.1.2` lub editable `../uricore`), paczki URI z **`uri-packs`** (dev group w `pyproject.toml`).
|
|
51
|
+
|
|
52
|
+
## Szybki start
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
cd urisys && uv sync
|
|
56
|
+
|
|
57
|
+
# Pojedyncze URI (paczki z uri-packs)
|
|
58
|
+
urisys --packs browser call browser://default/page/open \
|
|
59
|
+
--payload '{"url":"https://example.com"}' --approve
|
|
60
|
+
|
|
61
|
+
# Flow mock
|
|
62
|
+
urisys --packs all flow flows/device-maintenance.uri.flow.yaml --approve --dry-run
|
|
63
|
+
|
|
64
|
+
# HTTP server
|
|
65
|
+
urisys --packs all serve --port 8789
|
|
66
|
+
```
|
|
67
|
+
|
|
68
|
+
## Docker lab (10 automatyzacji + RDP)
|
|
69
|
+
|
|
70
|
+
```bash
|
|
71
|
+
cd urisys-automation-lab
|
|
72
|
+
bash scripts/docker-up.sh
|
|
73
|
+
bash scripts/docker-smoke.sh
|
|
74
|
+
|
|
75
|
+
# Pełny test E2E
|
|
76
|
+
python3 scripts/run_test_sessions.py --sessions lab-10-flows
|
|
77
|
+
# lub: bash scripts/run-lab-e2e.sh
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## Dokumentacja
|
|
81
|
+
|
|
82
|
+
| Dokument | Temat |
|
|
83
|
+
|----------|--------|
|
|
84
|
+
| [`docs/ARCHITECTURE.md`](docs/ARCHITECTURE.md) | Jak działa urisys — warstwy, runtime, testy |
|
|
85
|
+
| [`docs/PACKAGES.md`](docs/PACKAGES.md) | Layout monorepo, duplikaty, plan konsolidacji |
|
|
86
|
+
| [`docs/FLOWS.md`](docs/FLOWS.md) | URI flows, zależności, walidacja |
|
|
87
|
+
| [`docs/EXAMPLES.md`](docs/EXAMPLES.md) | Przykłady shell/frontend/Docker |
|
|
88
|
+
| [`docs/CLI.md`](docs/CLI.md) | Komendy CLI |
|
|
89
|
+
| [`docs/MARKPACT.md`](docs/MARKPACT.md) | Markpact validate/compile/test |
|
|
90
|
+
| [`project/MAP.md`](project/MAP.md) | Przewodnik po `map.toon.yaml` (code2llm) |
|
|
91
|
+
| [`project/PACKAGES.md`](project/PACKAGES.md) | Indeks paczek sync z mapÄ… |
|
|
92
|
+
|
|
93
|
+
## Struktura monorepo
|
|
94
|
+
|
|
95
|
+
```text
|
|
96
|
+
src/urisys/ pip package — CLI + managers
|
|
97
|
+
packages/python/urisysedge/ wspólny edge runtime (canonical)
|
|
98
|
+
urirdp-docker/ RDP + KVM/HIM/OCR/LLM/shell/browser
|
|
99
|
+
urisys-automation-lab/ 10 flows, lab UI :8099
|
|
100
|
+
urisys-node/ slave node + ArtifactResolver
|
|
101
|
+
local-lab/ markpact.com release chain
|
|
102
|
+
flows/ przykład flow dla CLI
|
|
103
|
+
examples/ shell + frontend
|
|
104
|
+
markpacts/packs/ Markpact do walidacji
|
|
105
|
+
scripts/ test sessions, validate-all-markpacts
|
|
106
|
+
```
|
|
107
|
+
|
|
108
|
+
## Managers
|
|
109
|
+
|
|
110
|
+
- `PackManager` — paczki `uri*`, manifest.yaml, Markpact
|
|
111
|
+
- `MarkpactManager` — validate / compile / test `*.markpact.md`
|
|
112
|
+
- `RuntimeManager` — `uri_control.UriControlRuntime`
|
|
113
|
+
- `UriController` — call, explain, routes
|
|
114
|
+
- `FlowController` — sekwencyjne `*.uri.flow.yaml`
|
|
115
|
+
- `BridgeManager` — forward do zdalnego `/uri/call`
|
|
116
|
+
|
|
117
|
+
## Markpact
|
|
118
|
+
|
|
119
|
+
```bash
|
|
120
|
+
urisys markpact validate markpacts/packs/uribrowser.markpact.md
|
|
121
|
+
bash scripts/validate-all-markpacts.sh
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
## Analiza projektu (code2llm)
|
|
125
|
+
|
|
126
|
+
```bash
|
|
127
|
+
code2llm ./ -f all -o ./project
|
|
128
|
+
# → project/map.toon.yaml, calls.mmd, context.md
|
|
129
|
+
```
|
|
130
|
+
|
|
131
|
+
## License
|
|
132
|
+
|
|
133
|
+
Licensed under Apache-2.0.
|
|
@@ -0,0 +1,103 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=68", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "urisys"
|
|
7
|
+
version = "0.1.11"
|
|
8
|
+
description = "URI control system managers/controllers over separate uri* capability packs."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.10"
|
|
11
|
+
license = "Apache-2.0"
|
|
12
|
+
authors = [
|
|
13
|
+
{ name = "urisys contributors" },
|
|
14
|
+
{ name = "Tom Sapletta", email = "tom@sapletta.com" },
|
|
15
|
+
]
|
|
16
|
+
dependencies = ["uricore>=0.1.0", "PyYAML>=6.0"]
|
|
17
|
+
keywords = ["uri", "control-plane", "controllers", "managers", "devices", "services"]
|
|
18
|
+
classifiers = [
|
|
19
|
+
"Development Status :: 3 - Alpha",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.10",
|
|
22
|
+
"Programming Language :: Python :: 3.11",
|
|
23
|
+
"Programming Language :: Python :: 3.12",
|
|
24
|
+
]
|
|
25
|
+
|
|
26
|
+
[project.optional-dependencies]
|
|
27
|
+
dev = [
|
|
28
|
+
"pytest>=8.0",
|
|
29
|
+
"uricore",
|
|
30
|
+
"uribrowser",
|
|
31
|
+
"uridocker",
|
|
32
|
+
"goal>=2.1.0",
|
|
33
|
+
"costs>=0.1.20",
|
|
34
|
+
"pfix>=0.1.60",
|
|
35
|
+
]
|
|
36
|
+
lab = [
|
|
37
|
+
"uri2flow>=0.1.2",
|
|
38
|
+
]
|
|
39
|
+
|
|
40
|
+
[dependency-groups]
|
|
41
|
+
dev = [
|
|
42
|
+
"pytest>=8.0",
|
|
43
|
+
"uricore",
|
|
44
|
+
"uribrowser",
|
|
45
|
+
"uridocker",
|
|
46
|
+
]
|
|
47
|
+
lab = [
|
|
48
|
+
"uri2flow>=0.1.2",
|
|
49
|
+
]
|
|
50
|
+
|
|
51
|
+
[tool.uv.sources]
|
|
52
|
+
uricore = { path = "../uricore", editable = true }
|
|
53
|
+
uribrowser = { path = "../uri-packs/packages/python/uribrowser", editable = true }
|
|
54
|
+
uridocker = { path = "../uri-packs/packages/python/uridocker", editable = true }
|
|
55
|
+
uri2flow = { path = "../uri2flow", editable = true }
|
|
56
|
+
uri2ops = { path = "../uri2ops", editable = true }
|
|
57
|
+
uri3 = { path = "../uri3", editable = true }
|
|
58
|
+
|
|
59
|
+
[tool.uv]
|
|
60
|
+
default-groups = ["dev"]
|
|
61
|
+
|
|
62
|
+
[project.scripts]
|
|
63
|
+
urisys = "urisys.cli:main"
|
|
64
|
+
|
|
65
|
+
[tool.setuptools]
|
|
66
|
+
package-dir = {"" = "src"}
|
|
67
|
+
|
|
68
|
+
[tool.setuptools.packages.find]
|
|
69
|
+
where = ["src"]
|
|
70
|
+
include = ["urisys*"]
|
|
71
|
+
|
|
72
|
+
[tool.pytest.ini_options]
|
|
73
|
+
pythonpath = ["src"]
|
|
74
|
+
testpaths = ["tests"]
|
|
75
|
+
|
|
76
|
+
[tool.pfix]
|
|
77
|
+
# Self-healing Python configuration
|
|
78
|
+
model = "openrouter/qwen/qwen3-coder-next"
|
|
79
|
+
auto_apply = true
|
|
80
|
+
auto_install_deps = true
|
|
81
|
+
auto_restart = false
|
|
82
|
+
max_retries = 3
|
|
83
|
+
create_backups = false
|
|
84
|
+
git_auto_commit = false
|
|
85
|
+
|
|
86
|
+
[tool.pfix.runtime_todo]
|
|
87
|
+
enabled = true
|
|
88
|
+
todo_file = "TODO.md"
|
|
89
|
+
min_severity = "low"
|
|
90
|
+
deduplicate = true
|
|
91
|
+
|
|
92
|
+
[tool.costs]
|
|
93
|
+
# AI Cost tracking configuration
|
|
94
|
+
badge = true
|
|
95
|
+
update_readme = true
|
|
96
|
+
readme_path = "README.md"
|
|
97
|
+
default_model = "openrouter/qwen/qwen3-coder-next"
|
|
98
|
+
analysis_mode = "byok"
|
|
99
|
+
full_history = true
|
|
100
|
+
max_commits = 500
|
|
101
|
+
|
|
102
|
+
# Cost thresholds for badge colors (USD)
|
|
103
|
+
badge_color_thresholds = { low = 1.0, medium = 5.0, high = 10.0, critical = 50.0 }
|
urisys-0.1.11/setup.cfg
ADDED
|
@@ -0,0 +1,176 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
import argparse
|
|
4
|
+
import json
|
|
5
|
+
from pathlib import Path
|
|
6
|
+
|
|
7
|
+
from uri_control import CapabilityRegistry
|
|
8
|
+
|
|
9
|
+
from .defaults import DEFAULT_ENVIRONMENT
|
|
10
|
+
from .controllers.flow_controller import FlowController
|
|
11
|
+
from .controllers.server_controller import ServerController
|
|
12
|
+
from .controllers.uri_controller import UriController
|
|
13
|
+
from .managers.event_manager import EventManager
|
|
14
|
+
from .managers.markpact_manager import MarkpactManager, MarkpactError
|
|
15
|
+
from .managers.source_manager import SourceManager, SourceError
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
def _json_arg(value: str | None) -> dict:
|
|
19
|
+
if not value:
|
|
20
|
+
return {}
|
|
21
|
+
if value.startswith("@"):
|
|
22
|
+
return json.loads(Path(value[1:]).read_text(encoding="utf-8"))
|
|
23
|
+
return json.loads(value)
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
def print_json(data: dict) -> None:
|
|
27
|
+
print(json.dumps(data, ensure_ascii=False, indent=2, sort_keys=True))
|
|
28
|
+
|
|
29
|
+
|
|
30
|
+
def _add_runtime_flags(parser: argparse.ArgumentParser) -> None:
|
|
31
|
+
parser.add_argument("--approve", action="store_true")
|
|
32
|
+
parser.add_argument("--dry-run", action="store_true")
|
|
33
|
+
parser.add_argument("--allow-real", action="store_true")
|
|
34
|
+
parser.add_argument("--environment", default=DEFAULT_ENVIRONMENT)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
def resolve_markpact_source(source: str, *, source_manager: SourceManager | None = None) -> str:
|
|
38
|
+
manager = source_manager or SourceManager()
|
|
39
|
+
return str(manager.resolve(source))
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
def build_parser() -> argparse.ArgumentParser:
|
|
43
|
+
parser = argparse.ArgumentParser(prog="urisys", description="URI control system: managers/controllers over uri* packs and UriPack Markpacts.")
|
|
44
|
+
parser.add_argument("--packs", default="all", help="Comma-separated pack aliases/packages, plain manifest paths, Markpact paths or all/none.")
|
|
45
|
+
parser.add_argument("--markpact", action="append", default=[], help="Load one UriPack Markpact. Can be used multiple times.")
|
|
46
|
+
parser.add_argument("--events", default="output/urisys-events.jsonl")
|
|
47
|
+
sub = parser.add_subparsers(dest="command", required=True)
|
|
48
|
+
|
|
49
|
+
p = sub.add_parser("call", help="Execute a URI through urisys.")
|
|
50
|
+
p.add_argument("uri")
|
|
51
|
+
p.add_argument("--payload", default="{}", help="JSON payload or @file.json")
|
|
52
|
+
_add_runtime_flags(p)
|
|
53
|
+
|
|
54
|
+
p = sub.add_parser("explain", help="Explain how a URI routes.")
|
|
55
|
+
p.add_argument("uri")
|
|
56
|
+
|
|
57
|
+
sub.add_parser("routes", help="List loaded routes.")
|
|
58
|
+
sub.add_parser("events", help="List event log.")
|
|
59
|
+
|
|
60
|
+
p = sub.add_parser("flow", help="Run a compact URI flow YAML.")
|
|
61
|
+
p.add_argument("path")
|
|
62
|
+
_add_runtime_flags(p)
|
|
63
|
+
|
|
64
|
+
p = sub.add_parser("serve", help="Run HTTP URI server.")
|
|
65
|
+
p.add_argument("--host", default="127.0.0.1")
|
|
66
|
+
p.add_argument("--port", type=int, default=8789)
|
|
67
|
+
|
|
68
|
+
p = sub.add_parser("markpact", help="Validate, compile, fetch and test one-file UriPack Markpacts.")
|
|
69
|
+
msub = p.add_subparsers(dest="markpact_command", required=True)
|
|
70
|
+
|
|
71
|
+
p_fetch = msub.add_parser("fetch", help="Fetch a Markpact from file/HTTP/GitHub/git/ZIP and cache it locally.")
|
|
72
|
+
p_fetch.add_argument("source")
|
|
73
|
+
p_fetch.add_argument("--force", action="store_true")
|
|
74
|
+
|
|
75
|
+
p_validate = msub.add_parser("validate", help="Validate a Markpact file or remote source.")
|
|
76
|
+
p_validate.add_argument("path")
|
|
77
|
+
|
|
78
|
+
p_compile = msub.add_parser("compile", help="Compile Markpact to cached runtime manifest and handlers.")
|
|
79
|
+
p_compile.add_argument("path")
|
|
80
|
+
p_compile.add_argument("--out", default=None, help="Optional output/cache directory.")
|
|
81
|
+
p_compile.add_argument("--force", action="store_true")
|
|
82
|
+
|
|
83
|
+
p_routes = msub.add_parser("routes", help="Compile Markpact and list generated routes.")
|
|
84
|
+
p_routes.add_argument("path")
|
|
85
|
+
p_routes.add_argument("--out", default=None)
|
|
86
|
+
|
|
87
|
+
p_test = msub.add_parser("test", help="Run tests embedded in Markpact.")
|
|
88
|
+
p_test.add_argument("path")
|
|
89
|
+
p_test.add_argument("--out", default=None, help="Optional compile/cache directory.")
|
|
90
|
+
|
|
91
|
+
return parser
|
|
92
|
+
|
|
93
|
+
|
|
94
|
+
def main(argv: list[str] | None = None) -> int:
|
|
95
|
+
args = build_parser().parse_args(argv)
|
|
96
|
+
|
|
97
|
+
try:
|
|
98
|
+
if args.command == "markpact":
|
|
99
|
+
source_manager = SourceManager(cache_root=(Path(args.out) / "sources") if getattr(args, "out", None) else ".urisys/cache/sources")
|
|
100
|
+
manager = MarkpactManager(cache_root=args.out) if getattr(args, "out", None) else MarkpactManager()
|
|
101
|
+
if args.markpact_command == "fetch":
|
|
102
|
+
print_json(source_manager.fetch(args.source, force=args.force))
|
|
103
|
+
return 0
|
|
104
|
+
local_path = resolve_markpact_source(args.path, source_manager=source_manager)
|
|
105
|
+
if args.markpact_command == "validate":
|
|
106
|
+
print_json(manager.validate(local_path))
|
|
107
|
+
return 0
|
|
108
|
+
if args.markpact_command == "compile":
|
|
109
|
+
compiled = manager.compile(local_path, out_dir=args.out, force=args.force)
|
|
110
|
+
print_json({"ok": True, "compiled": compiled.to_dict()})
|
|
111
|
+
return 0
|
|
112
|
+
if args.markpact_command == "routes":
|
|
113
|
+
compiled = manager.compile(local_path, out_dir=args.out)
|
|
114
|
+
registry = CapabilityRegistry.from_manifest_files([compiled.manifest_path])
|
|
115
|
+
print_json({
|
|
116
|
+
"ok": True,
|
|
117
|
+
"compiled": compiled.to_dict(),
|
|
118
|
+
"routes": [
|
|
119
|
+
{
|
|
120
|
+
"manifest_id": r.manifest_id,
|
|
121
|
+
"scheme": r.scheme,
|
|
122
|
+
"pattern": r.pattern,
|
|
123
|
+
"kind": r.kind,
|
|
124
|
+
"operation": r.operation,
|
|
125
|
+
"approval": r.approval,
|
|
126
|
+
"side_effects": r.side_effects,
|
|
127
|
+
"handler_ref": r.handler_ref,
|
|
128
|
+
}
|
|
129
|
+
for r in registry.routes
|
|
130
|
+
],
|
|
131
|
+
})
|
|
132
|
+
return 0
|
|
133
|
+
if args.markpact_command == "test":
|
|
134
|
+
print_json(manager.run_tests(local_path, events_path=args.events))
|
|
135
|
+
return 0
|
|
136
|
+
|
|
137
|
+
if args.command == "serve":
|
|
138
|
+
ServerController(host=args.host, port=args.port, packs=args.packs, markpacts=args.markpact, events_path=args.events).serve_forever()
|
|
139
|
+
return 0
|
|
140
|
+
|
|
141
|
+
if args.command == "flow":
|
|
142
|
+
ctrl = FlowController(packs=args.packs, markpacts=args.markpact, events_path=args.events)
|
|
143
|
+
try:
|
|
144
|
+
print_json(ctrl.run(args.path, approved=args.approve, dry_run=args.dry_run, allow_real=args.allow_real, environment=args.environment))
|
|
145
|
+
finally:
|
|
146
|
+
ctrl.close()
|
|
147
|
+
return 0
|
|
148
|
+
|
|
149
|
+
if args.command == "events":
|
|
150
|
+
print_json({"ok": True, "events": EventManager(args.events).list_events()})
|
|
151
|
+
return 0
|
|
152
|
+
|
|
153
|
+
ctrl = UriController(packs=args.packs, markpacts=args.markpact, events_path=args.events)
|
|
154
|
+
try:
|
|
155
|
+
if args.command == "call":
|
|
156
|
+
print_json(ctrl.call(args.uri, _json_arg(args.payload), approved=args.approve, dry_run=args.dry_run, allow_real=args.allow_real, environment=args.environment))
|
|
157
|
+
return 0
|
|
158
|
+
if args.command == "explain":
|
|
159
|
+
print_json({"ok": True, "explain": ctrl.explain(args.uri)})
|
|
160
|
+
return 0
|
|
161
|
+
if args.command == "routes":
|
|
162
|
+
print_json({"ok": True, "routes": ctrl.routes()})
|
|
163
|
+
return 0
|
|
164
|
+
finally:
|
|
165
|
+
ctrl.close()
|
|
166
|
+
return 1
|
|
167
|
+
except MarkpactError as exc:
|
|
168
|
+
print_json({"ok": False, "error": str(exc), "type": "markpact_error"})
|
|
169
|
+
return 2
|
|
170
|
+
except SourceError as exc:
|
|
171
|
+
print_json({"ok": False, "error": str(exc), "type": "source_error"})
|
|
172
|
+
return 2
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
if __name__ == "__main__":
|
|
176
|
+
raise SystemExit(main())
|
|
File without changes
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from pathlib import Path
|
|
4
|
+
|
|
5
|
+
from ..defaults import DEFAULT_ENVIRONMENT
|
|
6
|
+
from ..flow import iter_steps, load_flow
|
|
7
|
+
from .uri_controller import UriController
|
|
8
|
+
|
|
9
|
+
|
|
10
|
+
class FlowController:
|
|
11
|
+
def __init__(self, packs="all", *, markpacts=None, events_path: str | None = None) -> None:
|
|
12
|
+
self.uri_controller = UriController(packs=packs, markpacts=markpacts, events_path=events_path)
|
|
13
|
+
|
|
14
|
+
def run(self, path: str | Path, *, approved=False, dry_run=False, allow_real=False, environment=DEFAULT_ENVIRONMENT) -> dict:
|
|
15
|
+
flow = load_flow(path)
|
|
16
|
+
defaults = flow.get("defaults") or {}
|
|
17
|
+
results = []
|
|
18
|
+
for uri, payload in iter_steps(flow):
|
|
19
|
+
result = self.uri_controller.call(
|
|
20
|
+
uri,
|
|
21
|
+
payload,
|
|
22
|
+
approved=bool(defaults.get("approved", approved)),
|
|
23
|
+
dry_run=bool(defaults.get("dry_run", dry_run)),
|
|
24
|
+
allow_real=bool(defaults.get("allow_real", allow_real)),
|
|
25
|
+
environment=str(defaults.get("environment", environment)),
|
|
26
|
+
)
|
|
27
|
+
results.append(result)
|
|
28
|
+
if not result.get("ok") and not bool(defaults.get("continue_on_error")):
|
|
29
|
+
break
|
|
30
|
+
return {"ok": all(r.get("ok") for r in results), "flow": flow.get("flow", {}), "results": results}
|
|
31
|
+
|
|
32
|
+
def close(self) -> None:
|
|
33
|
+
self.uri_controller.close()
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ..http_server import create_server
|
|
4
|
+
|
|
5
|
+
|
|
6
|
+
class ServerController:
|
|
7
|
+
def __init__(self, *, host="127.0.0.1", port=8789, packs="all", markpacts=None, events_path="output/urisys-events.jsonl") -> None:
|
|
8
|
+
self.host = host
|
|
9
|
+
self.port = port
|
|
10
|
+
self.packs = packs
|
|
11
|
+
self.markpacts = markpacts
|
|
12
|
+
self.events_path = events_path
|
|
13
|
+
self.server = create_server(host, port, packs=packs, markpacts=markpacts, events_path=events_path)
|
|
14
|
+
|
|
15
|
+
def serve_forever(self) -> None:
|
|
16
|
+
print(f"urisys server listening on http://{self.host}:{self.port}")
|
|
17
|
+
print("endpoints: GET /health, GET /uri/routes, GET /uri/events, POST /uri/call, POST /uri/explain")
|
|
18
|
+
self.server.serve_forever()
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
3
|
+
from ..defaults import DEFAULT_ENVIRONMENT
|
|
4
|
+
from ..managers.policy_manager import PolicyManager
|
|
5
|
+
from ..managers.route_manager import RouteManager
|
|
6
|
+
from ..managers.runtime_manager import RuntimeManager
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
class UriController:
|
|
10
|
+
def __init__(self, packs="all", *, markpacts=None, events_path: str | None = None) -> None:
|
|
11
|
+
self.runtime_manager = RuntimeManager(packs, markpacts=markpacts, events_path=events_path)
|
|
12
|
+
self.runtime = self.runtime_manager.create_runtime()
|
|
13
|
+
self.policy_manager = PolicyManager()
|
|
14
|
+
self.route_manager = RouteManager(self.runtime)
|
|
15
|
+
|
|
16
|
+
def call(self, uri: str, payload=None, *, approved=False, dry_run=False, allow_real=False, environment=DEFAULT_ENVIRONMENT, context=None) -> dict:
|
|
17
|
+
ctx = self.policy_manager.build_context(
|
|
18
|
+
approved=approved,
|
|
19
|
+
dry_run=dry_run,
|
|
20
|
+
allow_real=allow_real,
|
|
21
|
+
environment=environment,
|
|
22
|
+
extra=context or {},
|
|
23
|
+
)
|
|
24
|
+
return self.runtime.call(uri, payload or {}, ctx).to_dict()
|
|
25
|
+
|
|
26
|
+
def explain(self, uri: str) -> dict:
|
|
27
|
+
return self.route_manager.explain(uri)
|
|
28
|
+
|
|
29
|
+
def routes(self) -> list[dict]:
|
|
30
|
+
return self.route_manager.list_routes()
|
|
31
|
+
|
|
32
|
+
def close(self) -> None:
|
|
33
|
+
self.runtime_manager.close()
|