dryv-author 0.0.1__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.
- dryv_author-0.0.1/.gitignore +28 -0
- dryv_author-0.0.1/PKG-INFO +66 -0
- dryv_author-0.0.1/README.md +58 -0
- dryv_author-0.0.1/pyproject.toml +49 -0
- dryv_author-0.0.1/src/dryv_author/__init__.py +184 -0
- dryv_author-0.0.1/src/dryv_author/_version.py +6 -0
- dryv_author-0.0.1/src/dryv_author/behavior.py +613 -0
- dryv_author-0.0.1/src/dryv_author/composition.py +504 -0
- dryv_author-0.0.1/src/dryv_author/core.py +270 -0
- dryv_author-0.0.1/src/dryv_author/expressions.py +198 -0
- dryv_author-0.0.1/src/dryv_author/interaction.py +313 -0
- dryv_author-0.0.1/src/dryv_author/orchestration.py +216 -0
- dryv_author-0.0.1/src/dryv_author/properties.py +951 -0
- dryv_author-0.0.1/src/dryv_author/schemas.py +631 -0
- dryv_author-0.0.1/src/dryv_author/state.py +1253 -0
- dryv_author-0.0.1/tests/test_author.py +112 -0
- dryv_author-0.0.1/uv.lock +381 -0
|
@@ -0,0 +1,28 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
.pytest_cache/
|
|
6
|
+
.mypy_cache/
|
|
7
|
+
.ruff_cache/
|
|
8
|
+
.venv/
|
|
9
|
+
venv/
|
|
10
|
+
build/
|
|
11
|
+
dist/
|
|
12
|
+
generated/
|
|
13
|
+
# Node / editors
|
|
14
|
+
node_modules/
|
|
15
|
+
.vscode-test/
|
|
16
|
+
.idea
|
|
17
|
+
|
|
18
|
+
# Environment
|
|
19
|
+
.env
|
|
20
|
+
.env.*
|
|
21
|
+
!.env.example
|
|
22
|
+
|
|
23
|
+
# OS
|
|
24
|
+
.DS_Store
|
|
25
|
+
Thumbs.db
|
|
26
|
+
|
|
27
|
+
# Dryv local cache and materialized resources
|
|
28
|
+
.dryv/
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
Metadata-Version: 2.5
|
|
2
|
+
Name: dryv-author
|
|
3
|
+
Version: 0.0.1
|
|
4
|
+
Summary: Lightweight typed Python authoring SDK for Dryv
|
|
5
|
+
License: Apache-2.0
|
|
6
|
+
Requires-Python: >=3.11
|
|
7
|
+
Description-Content-Type: text/markdown
|
|
8
|
+
|
|
9
|
+
# dryv-author
|
|
10
|
+
|
|
11
|
+
`dryv-author` is the Python Authoring SDK installed in an authored project. It mirrors the TypeScript author with Pythonic names, and produces a typed `AuthorState` that `dryv-compiler` lowers to canonical `dryv.ir/v1alpha1`.
|
|
12
|
+
|
|
13
|
+
The package does not depend on the Dryv Engine and never serializes Runtime IR, selects packs, renders templates, chooses output paths, or writes files.
|
|
14
|
+
|
|
15
|
+
## Example
|
|
16
|
+
|
|
17
|
+
```python
|
|
18
|
+
from dryv_author import body, dryv, field, http, operation, path, prop, respond, schema, storage
|
|
19
|
+
|
|
20
|
+
users = dryv.group("users")
|
|
21
|
+
accounts = users.feature("Accounts") # features are registration scopes
|
|
22
|
+
|
|
23
|
+
ids = accounts.properties({"Id": prop.string.uuid(), "Name": prop.string()})
|
|
24
|
+
models = accounts.schemas({
|
|
25
|
+
"User": schema({
|
|
26
|
+
"id": field(ids.Id).system(),
|
|
27
|
+
"name": field(ids.Name).query(filter="*", sort=True),
|
|
28
|
+
}).facets(storage=storage("users").primary_key("id")),
|
|
29
|
+
})
|
|
30
|
+
|
|
31
|
+
create = operation().role("create").inputs(models.User).outputs(models.User)
|
|
32
|
+
create.facets(
|
|
33
|
+
http=http("POST", "/users").input(create.input(0), body()).output(create.output(0), respond(201)),
|
|
34
|
+
)
|
|
35
|
+
accounts.operations({"CreateUser": create})
|
|
36
|
+
|
|
37
|
+
users.schemas({"AuditEntry": schema({"id": field(ids.Id)})}) # group-owned: no feature
|
|
38
|
+
|
|
39
|
+
app = dryv.app("accounts").groups(users)
|
|
40
|
+
```
|
|
41
|
+
|
|
42
|
+
The entrypoint configured in `dryv.yaml` must expose exactly one module-level `dryv.app(...)`. It may import ordinary modules; every registration records the caller's file and line.
|
|
43
|
+
|
|
44
|
+
## Ownership
|
|
45
|
+
|
|
46
|
+
Registering through `group.feature("Name")` makes the group the declaration's `group` and the feature its `feature`. Registering directly on the group leaves it group-owned. A declaration can belong to one group and at most one feature ([decision 0011](../../../../.docs/reference/decisions/0011-declaration-owned-feature-membership.md)).
|
|
47
|
+
|
|
48
|
+
## API map (TypeScript → Python)
|
|
49
|
+
|
|
50
|
+
| TypeScript | Python |
|
|
51
|
+
| --- | --- |
|
|
52
|
+
| `property.string.uuid()` | `prop.string.uuid()` |
|
|
53
|
+
| `property.number.integer({ range: { min: 0 } })` | `prop.number.integer(range={"min": 0})` |
|
|
54
|
+
| `field(x).createOnly()` | `field(x).create_only()` |
|
|
55
|
+
| `.query({ filter: ["notEqual"] })` | `.query(filter=["not-equal"])` (`not_equal` also accepted) |
|
|
56
|
+
| `expression.and(...)`, `.or(...)`, `.not(...)` | `expression.all_of(...)`, `.any_of(...)`, `.not_(...)` |
|
|
57
|
+
| `operation().async()` | `operation().async_()` |
|
|
58
|
+
| `operationStep`, `waitFor`, `outputFrom`, `inputFrom` | `operation_step`, `wait_for`, `output_from`, `input_from` |
|
|
59
|
+
| `group.policies(ref1, ref2)` | same: a mapping registers, refs set scope policies |
|
|
60
|
+
|
|
61
|
+
## Development
|
|
62
|
+
|
|
63
|
+
```bash
|
|
64
|
+
uv sync
|
|
65
|
+
uv run ruff format . && uv run ruff check --fix . && uv run mypy && uv run pytest
|
|
66
|
+
```
|
|
@@ -0,0 +1,58 @@
|
|
|
1
|
+
# dryv-author
|
|
2
|
+
|
|
3
|
+
`dryv-author` is the Python Authoring SDK installed in an authored project. It mirrors the TypeScript author with Pythonic names, and produces a typed `AuthorState` that `dryv-compiler` lowers to canonical `dryv.ir/v1alpha1`.
|
|
4
|
+
|
|
5
|
+
The package does not depend on the Dryv Engine and never serializes Runtime IR, selects packs, renders templates, chooses output paths, or writes files.
|
|
6
|
+
|
|
7
|
+
## Example
|
|
8
|
+
|
|
9
|
+
```python
|
|
10
|
+
from dryv_author import body, dryv, field, http, operation, path, prop, respond, schema, storage
|
|
11
|
+
|
|
12
|
+
users = dryv.group("users")
|
|
13
|
+
accounts = users.feature("Accounts") # features are registration scopes
|
|
14
|
+
|
|
15
|
+
ids = accounts.properties({"Id": prop.string.uuid(), "Name": prop.string()})
|
|
16
|
+
models = accounts.schemas({
|
|
17
|
+
"User": schema({
|
|
18
|
+
"id": field(ids.Id).system(),
|
|
19
|
+
"name": field(ids.Name).query(filter="*", sort=True),
|
|
20
|
+
}).facets(storage=storage("users").primary_key("id")),
|
|
21
|
+
})
|
|
22
|
+
|
|
23
|
+
create = operation().role("create").inputs(models.User).outputs(models.User)
|
|
24
|
+
create.facets(
|
|
25
|
+
http=http("POST", "/users").input(create.input(0), body()).output(create.output(0), respond(201)),
|
|
26
|
+
)
|
|
27
|
+
accounts.operations({"CreateUser": create})
|
|
28
|
+
|
|
29
|
+
users.schemas({"AuditEntry": schema({"id": field(ids.Id)})}) # group-owned: no feature
|
|
30
|
+
|
|
31
|
+
app = dryv.app("accounts").groups(users)
|
|
32
|
+
```
|
|
33
|
+
|
|
34
|
+
The entrypoint configured in `dryv.yaml` must expose exactly one module-level `dryv.app(...)`. It may import ordinary modules; every registration records the caller's file and line.
|
|
35
|
+
|
|
36
|
+
## Ownership
|
|
37
|
+
|
|
38
|
+
Registering through `group.feature("Name")` makes the group the declaration's `group` and the feature its `feature`. Registering directly on the group leaves it group-owned. A declaration can belong to one group and at most one feature ([decision 0011](../../../../.docs/reference/decisions/0011-declaration-owned-feature-membership.md)).
|
|
39
|
+
|
|
40
|
+
## API map (TypeScript → Python)
|
|
41
|
+
|
|
42
|
+
| TypeScript | Python |
|
|
43
|
+
| --- | --- |
|
|
44
|
+
| `property.string.uuid()` | `prop.string.uuid()` |
|
|
45
|
+
| `property.number.integer({ range: { min: 0 } })` | `prop.number.integer(range={"min": 0})` |
|
|
46
|
+
| `field(x).createOnly()` | `field(x).create_only()` |
|
|
47
|
+
| `.query({ filter: ["notEqual"] })` | `.query(filter=["not-equal"])` (`not_equal` also accepted) |
|
|
48
|
+
| `expression.and(...)`, `.or(...)`, `.not(...)` | `expression.all_of(...)`, `.any_of(...)`, `.not_(...)` |
|
|
49
|
+
| `operation().async()` | `operation().async_()` |
|
|
50
|
+
| `operationStep`, `waitFor`, `outputFrom`, `inputFrom` | `operation_step`, `wait_for`, `output_from`, `input_from` |
|
|
51
|
+
| `group.policies(ref1, ref2)` | same: a mapping registers, refs set scope policies |
|
|
52
|
+
|
|
53
|
+
## Development
|
|
54
|
+
|
|
55
|
+
```bash
|
|
56
|
+
uv sync
|
|
57
|
+
uv run ruff format . && uv run ruff check --fix . && uv run mypy && uv run pytest
|
|
58
|
+
```
|
|
@@ -0,0 +1,49 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling>=1.27"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dryv-author"
|
|
7
|
+
version = "0.0.1"
|
|
8
|
+
description = "Lightweight typed Python authoring SDK for Dryv"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.11"
|
|
11
|
+
license = { text = "Apache-2.0" }
|
|
12
|
+
dependencies = []
|
|
13
|
+
|
|
14
|
+
[dependency-groups]
|
|
15
|
+
dev = [
|
|
16
|
+
"mypy>=1.17",
|
|
17
|
+
"pytest>=8.4",
|
|
18
|
+
"ruff>=0.12",
|
|
19
|
+
]
|
|
20
|
+
|
|
21
|
+
[tool.hatch.build.targets.wheel]
|
|
22
|
+
packages = ["src/dryv_author"]
|
|
23
|
+
|
|
24
|
+
[tool.ruff]
|
|
25
|
+
target-version = "py311"
|
|
26
|
+
line-length = 100
|
|
27
|
+
src = ["src", "tests"]
|
|
28
|
+
|
|
29
|
+
[tool.ruff.lint]
|
|
30
|
+
select = ["E4", "E7", "E9", "F", "I", "UP", "B", "SIM", "RUF"]
|
|
31
|
+
|
|
32
|
+
[tool.ruff.format]
|
|
33
|
+
quote-style = "double"
|
|
34
|
+
indent-style = "space"
|
|
35
|
+
line-ending = "lf"
|
|
36
|
+
docstring-code-format = true
|
|
37
|
+
|
|
38
|
+
[tool.mypy]
|
|
39
|
+
python_version = "3.11"
|
|
40
|
+
strict = true
|
|
41
|
+
files = ["src", "tests"]
|
|
42
|
+
pretty = true
|
|
43
|
+
show_error_codes = true
|
|
44
|
+
warn_unreachable = true
|
|
45
|
+
|
|
46
|
+
[tool.pytest.ini_options]
|
|
47
|
+
pythonpath = ["src"]
|
|
48
|
+
testpaths = ["tests"]
|
|
49
|
+
addopts = ["--strict-config", "--strict-markers", "-ra"]
|
|
@@ -0,0 +1,184 @@
|
|
|
1
|
+
"""Dryv Python Author SDK.
|
|
2
|
+
|
|
3
|
+
Declare software meaning in Python; the matching ``dryv-compiler`` lowers it to canonical
|
|
4
|
+
Runtime IR. The API mirrors the TypeScript author with Pythonic names::
|
|
5
|
+
|
|
6
|
+
from dryv_author import dryv, field, operation, prop, schema
|
|
7
|
+
|
|
8
|
+
users = dryv.group("users")
|
|
9
|
+
accounts = users.feature("Accounts")
|
|
10
|
+
ids = accounts.properties({"Id": prop.string.uuid()})
|
|
11
|
+
models = accounts.schemas({"User": schema({"id": field(ids.Id).system()})})
|
|
12
|
+
app = dryv.app("example").groups(users)
|
|
13
|
+
"""
|
|
14
|
+
|
|
15
|
+
from ._version import AUTHOR_REPRESENTATION_VERSION, AUTHOR_VERSION, __version__
|
|
16
|
+
from .behavior import (
|
|
17
|
+
EventDeclaration,
|
|
18
|
+
FailureDeclaration,
|
|
19
|
+
HttpFacet,
|
|
20
|
+
OperationDeclaration,
|
|
21
|
+
PolicyDeclaration,
|
|
22
|
+
ScheduleFacet,
|
|
23
|
+
WebSocketFacet,
|
|
24
|
+
body,
|
|
25
|
+
bytes_,
|
|
26
|
+
cookie,
|
|
27
|
+
csv,
|
|
28
|
+
daily,
|
|
29
|
+
event,
|
|
30
|
+
event_stream,
|
|
31
|
+
failure,
|
|
32
|
+
form,
|
|
33
|
+
header,
|
|
34
|
+
hours,
|
|
35
|
+
http,
|
|
36
|
+
interval,
|
|
37
|
+
json,
|
|
38
|
+
minutes,
|
|
39
|
+
multipart,
|
|
40
|
+
operation,
|
|
41
|
+
path,
|
|
42
|
+
policy,
|
|
43
|
+
port,
|
|
44
|
+
query,
|
|
45
|
+
query_object,
|
|
46
|
+
representation,
|
|
47
|
+
respond,
|
|
48
|
+
schedule,
|
|
49
|
+
seconds,
|
|
50
|
+
text,
|
|
51
|
+
websocket,
|
|
52
|
+
xml,
|
|
53
|
+
)
|
|
54
|
+
from .composition import (
|
|
55
|
+
AppDeclaration,
|
|
56
|
+
ApplicationDeclaration,
|
|
57
|
+
FeatureDeclaration,
|
|
58
|
+
GroupDeclaration,
|
|
59
|
+
application,
|
|
60
|
+
dryv,
|
|
61
|
+
feature,
|
|
62
|
+
is_dryv_app,
|
|
63
|
+
)
|
|
64
|
+
from .core import AuthoringError, OperationRef, Ref, Refs, SchemaRef, ViewRef, WorkflowRef
|
|
65
|
+
from .expressions import ExpressionDeclaration, context, duration, expression, value
|
|
66
|
+
from .interaction import (
|
|
67
|
+
SurfaceDeclaration,
|
|
68
|
+
ViewDeclaration,
|
|
69
|
+
input_from,
|
|
70
|
+
output_from,
|
|
71
|
+
part,
|
|
72
|
+
surface,
|
|
73
|
+
view,
|
|
74
|
+
)
|
|
75
|
+
from .orchestration import (
|
|
76
|
+
WorkflowDeclaration,
|
|
77
|
+
operation_step,
|
|
78
|
+
wait_for,
|
|
79
|
+
workflow,
|
|
80
|
+
workflow_step,
|
|
81
|
+
)
|
|
82
|
+
from .properties import TypeParameter, enum_member, prop
|
|
83
|
+
from .schemas import (
|
|
84
|
+
FieldSpec,
|
|
85
|
+
SchemaDeclaration,
|
|
86
|
+
dynamic,
|
|
87
|
+
field,
|
|
88
|
+
projection,
|
|
89
|
+
relation,
|
|
90
|
+
schema,
|
|
91
|
+
source,
|
|
92
|
+
storage,
|
|
93
|
+
unknown,
|
|
94
|
+
)
|
|
95
|
+
from .state import AuthorState, StringFormat
|
|
96
|
+
|
|
97
|
+
__all__ = [
|
|
98
|
+
"AUTHOR_REPRESENTATION_VERSION",
|
|
99
|
+
"AUTHOR_VERSION",
|
|
100
|
+
"AppDeclaration",
|
|
101
|
+
"ApplicationDeclaration",
|
|
102
|
+
"AuthorState",
|
|
103
|
+
"AuthoringError",
|
|
104
|
+
"EventDeclaration",
|
|
105
|
+
"ExpressionDeclaration",
|
|
106
|
+
"FailureDeclaration",
|
|
107
|
+
"FeatureDeclaration",
|
|
108
|
+
"FieldSpec",
|
|
109
|
+
"GroupDeclaration",
|
|
110
|
+
"HttpFacet",
|
|
111
|
+
"OperationDeclaration",
|
|
112
|
+
"OperationRef",
|
|
113
|
+
"PolicyDeclaration",
|
|
114
|
+
"Ref",
|
|
115
|
+
"Refs",
|
|
116
|
+
"ScheduleFacet",
|
|
117
|
+
"SchemaDeclaration",
|
|
118
|
+
"SchemaRef",
|
|
119
|
+
"StringFormat",
|
|
120
|
+
"SurfaceDeclaration",
|
|
121
|
+
"TypeParameter",
|
|
122
|
+
"ViewDeclaration",
|
|
123
|
+
"ViewRef",
|
|
124
|
+
"WebSocketFacet",
|
|
125
|
+
"WorkflowDeclaration",
|
|
126
|
+
"WorkflowRef",
|
|
127
|
+
"__version__",
|
|
128
|
+
"application",
|
|
129
|
+
"body",
|
|
130
|
+
"bytes_",
|
|
131
|
+
"context",
|
|
132
|
+
"cookie",
|
|
133
|
+
"csv",
|
|
134
|
+
"daily",
|
|
135
|
+
"dryv",
|
|
136
|
+
"duration",
|
|
137
|
+
"dynamic",
|
|
138
|
+
"enum_member",
|
|
139
|
+
"event",
|
|
140
|
+
"event_stream",
|
|
141
|
+
"expression",
|
|
142
|
+
"failure",
|
|
143
|
+
"feature",
|
|
144
|
+
"field",
|
|
145
|
+
"form",
|
|
146
|
+
"header",
|
|
147
|
+
"hours",
|
|
148
|
+
"http",
|
|
149
|
+
"input_from",
|
|
150
|
+
"interval",
|
|
151
|
+
"is_dryv_app",
|
|
152
|
+
"json",
|
|
153
|
+
"minutes",
|
|
154
|
+
"multipart",
|
|
155
|
+
"operation",
|
|
156
|
+
"operation_step",
|
|
157
|
+
"output_from",
|
|
158
|
+
"part",
|
|
159
|
+
"path",
|
|
160
|
+
"policy",
|
|
161
|
+
"port",
|
|
162
|
+
"projection",
|
|
163
|
+
"prop",
|
|
164
|
+
"query",
|
|
165
|
+
"query_object",
|
|
166
|
+
"relation",
|
|
167
|
+
"representation",
|
|
168
|
+
"respond",
|
|
169
|
+
"schedule",
|
|
170
|
+
"schema",
|
|
171
|
+
"seconds",
|
|
172
|
+
"source",
|
|
173
|
+
"storage",
|
|
174
|
+
"surface",
|
|
175
|
+
"text",
|
|
176
|
+
"unknown",
|
|
177
|
+
"value",
|
|
178
|
+
"view",
|
|
179
|
+
"wait_for",
|
|
180
|
+
"websocket",
|
|
181
|
+
"workflow",
|
|
182
|
+
"workflow_step",
|
|
183
|
+
"xml",
|
|
184
|
+
]
|