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.
@@ -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
+ ]
@@ -0,0 +1,6 @@
1
+ AUTHOR_VERSION = "0.0.1"
2
+ AUTHOR_REPRESENTATION_VERSION = "dryv.author.python/v1alpha5"
3
+
4
+ __version__ = AUTHOR_VERSION
5
+
6
+ __all__ = ["AUTHOR_REPRESENTATION_VERSION", "AUTHOR_VERSION", "__version__"]