umf-codegen 0.10.8__py3-none-any.whl

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,198 @@
1
+ # SPDX-License-Identifier: MIT OR Apache-2.0
2
+ """Generate the same typed Python client as UMF's portable TypeScript API."""
3
+ from __future__ import annotations
4
+
5
+ from typing import Literal, TypedDict, cast
6
+
7
+ from ._native import GenerationError, execute
8
+
9
+ __version__ = "0.10.8"
10
+
11
+
12
+ class RecordSelection(TypedDict):
13
+ module: str
14
+ element: str
15
+
16
+
17
+ class ActionSelection(TypedDict):
18
+ module: str
19
+ action: str
20
+
21
+
22
+ class GeneratedFile(TypedDict):
23
+ path: str
24
+ text: str
25
+ sha256: str
26
+
27
+
28
+ class PythonClientResult(TypedDict):
29
+ sourceDigest: str
30
+ description: dict[str, object]
31
+ files: list[GeneratedFile]
32
+
33
+
34
+ class TableDeploymentConfiguration(TypedDict):
35
+ module: str
36
+ schema: str
37
+ ownerRole: str
38
+ personRole: str
39
+ batchRole: str
40
+ groupRoles: dict[str, str]
41
+
42
+
43
+ class TableDeploymentDiagnostic(TypedDict):
44
+ code: str
45
+ path: str
46
+ message: str
47
+ severity: str
48
+
49
+
50
+ class CompiledTableDeployment(TypedDict):
51
+ status: Literal["compiled"]
52
+ bundle: dict[str, object]
53
+ diagnostics: list[TableDeploymentDiagnostic]
54
+
55
+
56
+ class BlockedTableDeployment(TypedDict):
57
+ status: Literal["blocked"]
58
+ diagnostics: list[TableDeploymentDiagnostic]
59
+
60
+
61
+ class TableMigrationPredecessor(TypedDict):
62
+ id: str
63
+ digest: str
64
+
65
+
66
+ class CompiledTableMigration(TypedDict):
67
+ status: Literal["compiled"]
68
+ plan: dict[str, object]
69
+ diagnostics: list[TableDeploymentDiagnostic]
70
+
71
+
72
+ class BlockedTableMigration(TypedDict):
73
+ status: Literal["blocked"]
74
+ diagnostics: list[TableDeploymentDiagnostic]
75
+
76
+
77
+ class ReviewedChangeCandidate(TypedDict):
78
+ id: str
79
+ kind: str
80
+ path: str
81
+ oldDigest: str
82
+ newDigest: str
83
+ oldValue: object
84
+ newValue: object
85
+
86
+
87
+ class TableMigrationDiscoveryOptions(TypedDict):
88
+ version: Literal["umf.table-migration-discovery/0.2"]
89
+
90
+
91
+ def compile_table_migration(*, migration_id: str, predecessor: TableMigrationPredecessor | None,
92
+ previous_bundle: dict[str, object] | None, next_bundle: dict[str, object],
93
+ options: dict[str, object] | None = None,
94
+ timeout_seconds: float = 30) -> CompiledTableMigration | BlockedTableMigration:
95
+ """Compile an inert forward plan; native ledger and approval remain required."""
96
+ return cast(CompiledTableMigration | BlockedTableMigration,
97
+ execute({"id": migration_id, "predecessor": predecessor,
98
+ "previous": previous_bundle, "next": next_bundle,
99
+ **({"options": options} if options is not None else {})},
100
+ timeout_seconds, operation="migration"))
101
+
102
+
103
+ def verify_table_migration(plan: dict[str, object], *, timeout_seconds: float = 30) -> dict[str, object]:
104
+ """Recompile a complete plan; consistency cannot authenticate native history."""
105
+ return execute({"plan": plan}, timeout_seconds, operation="verify_migration")
106
+
107
+
108
+ def discover_table_migration_changes(previous_bundle: dict[str, object], next_bundle: dict[str, object],
109
+ *, options: TableMigrationDiscoveryOptions | None = None,
110
+ timeout_seconds: float = 30) -> list[ReviewedChangeCandidate]:
111
+ """Discover exact source-bound review candidates from two verified deployment bundles.
112
+
113
+ Returned values explain each delta. Copy only id, kind, path, oldDigest and
114
+ newDigest into `reviewedChanges`; a supported type conversion must also be
115
+ selected explicitly as `pg-cast-v1`.
116
+ Omitting `options`, or passing `None`, retains the historical discovery
117
+ profile. G03 candidates require the explicit discovery 0.2 selector.
118
+ """
119
+ request = {"previous": previous_bundle, "next": next_bundle}
120
+ if options is not None:
121
+ request["options"] = options
122
+ result = execute(request, timeout_seconds,
123
+ operation="discover_changes")
124
+ changes = result.get("changes")
125
+ if not isinstance(changes, list) or any(not isinstance(item, dict) for item in changes):
126
+ raise GenerationError("PAYLOAD_INVALID", "Embedded compiler returned invalid reviewed changes")
127
+ return cast(list[ReviewedChangeCandidate], changes)
128
+
129
+
130
+ def compile_table_deployment(text: str, *, configuration: TableDeploymentConfiguration,
131
+ format: Literal["json", "yaml"] = "json", timeout_seconds: float = 30
132
+ ) -> CompiledTableDeployment | BlockedTableDeployment:
133
+ """Compile inert initial DDL using UMF's original portable implementation."""
134
+ return cast(CompiledTableDeployment | BlockedTableDeployment,
135
+ execute({"text": text, "format": format, "configuration": configuration},
136
+ timeout_seconds, operation="deployment"))
137
+
138
+
139
+ def verify_table_deployment(bundle: dict[str, object], *, timeout_seconds: float = 30) -> dict[str, object]:
140
+ """Recompile a bundle; hosts must additionally verify their trusted digest."""
141
+ return execute({"bundle": bundle}, timeout_seconds, operation="verify_deployment")
142
+
143
+
144
+ def normalize_row_scope(input: dict[str, object], *, context: dict[str, object],
145
+ timeout_seconds: float = 30) -> dict[str, object]:
146
+ """Normalize row_scope with exact host bindings and lifecycle/native admission."""
147
+ return execute({"input": input, "context": context}, timeout_seconds, operation="row_scope")
148
+
149
+
150
+ def generate_python_client(text: str, *, package: str, format: Literal["json", "yaml"] = "json",
151
+ records: list[RecordSelection] | None = None,
152
+ actions: list[ActionSelection] | None = None,
153
+ timeout_seconds: float = 30) -> PythonClientResult:
154
+ request: dict[str, object] = {"text": text, "package": package, "format": format}
155
+ if records is not None:
156
+ request["records"] = records
157
+ if actions is not None:
158
+ request["actions"] = actions
159
+ return cast(PythonClientResult, execute(request, timeout_seconds))
160
+
161
+
162
+ def generate_pack_tools(request: dict[str, object], *, timeout_seconds: float = 30) -> dict[str, object]:
163
+ """Compile the complete ``umf.pack-tools/1`` request through pinned Rust.
164
+
165
+ The result's generated, partial, and blocked statuses are ordinary compiler
166
+ outcomes. This wrapper preserves the request and result profiles and adds
167
+ no source parsing or generation behavior in Python.
168
+ """
169
+ if type(request) is not dict:
170
+ raise TypeError("request must be a dict")
171
+ return execute(request, timeout_seconds, operation="pack_tools")
172
+
173
+
174
+ __all__ = [
175
+ "ActionSelection",
176
+ "BlockedTableDeployment",
177
+ "BlockedTableMigration",
178
+ "CompiledTableDeployment",
179
+ "CompiledTableMigration",
180
+ "GeneratedFile",
181
+ "GenerationError",
182
+ "PythonClientResult",
183
+ "RecordSelection",
184
+ "ReviewedChangeCandidate",
185
+ "TableDeploymentConfiguration",
186
+ "TableDeploymentDiagnostic",
187
+ "TableMigrationDiscoveryOptions",
188
+ "TableMigrationPredecessor",
189
+ "__version__",
190
+ "compile_table_deployment",
191
+ "compile_table_migration",
192
+ "discover_table_migration_changes",
193
+ "generate_python_client",
194
+ "generate_pack_tools",
195
+ "normalize_row_scope",
196
+ "verify_table_deployment",
197
+ "verify_table_migration",
198
+ ]
@@ -0,0 +1,47 @@
1
+ # SPDX-License-Identifier: MIT OR Apache-2.0
2
+ """Installed generate/check CLI. No executable discovery or external JS process."""
3
+ from __future__ import annotations
4
+
5
+ import argparse
6
+ import json
7
+ import sys
8
+ from pathlib import Path
9
+
10
+ from . import generate_python_client
11
+ from ._writer import check_package, write_package
12
+
13
+
14
+ def main(argv: list[str] | None = None) -> int:
15
+ parser = argparse.ArgumentParser(prog="umf-codegen", allow_abbrev=False)
16
+ parser.add_argument("command", choices=("generate", "check"))
17
+ parser.add_argument("--schema", required=True, type=Path)
18
+ parser.add_argument("--package", required=True)
19
+ parser.add_argument("--output", required=True, type=Path)
20
+ argv = sys.argv[1:] if argv is None else argv
21
+ for flag in ("--schema", "--package", "--output"):
22
+ if sum(item.split("=", 1)[0] == flag for item in argv) > 1:
23
+ parser.error("option may only appear once: " + flag)
24
+ args = parser.parse_args(argv)
25
+ try:
26
+ result = generate_python_client(args.schema.read_bytes().decode("utf-8"), package=args.package,
27
+ format="yaml" if args.schema.suffix.lower() in (".yaml", ".yml") else "json")
28
+ if args.command == "check":
29
+ differences = check_package(args.output, result)
30
+ for path in differences:
31
+ print(path, file=sys.stderr)
32
+ return int(bool(differences))
33
+ write_package(args.output, result)
34
+ print(json.dumps({"package": args.package, "sourceDigest": result["sourceDigest"], "files": len(result["files"])}))
35
+ return 0
36
+ except Exception as error: # noqa: BLE001 -- sanitize errors at the CLI process boundary
37
+ response = {"code": getattr(error, "code", "GENERATION_FAILED"), "message": str(error)}
38
+ for name in ("path", "written", "recovery"):
39
+ value = getattr(error, name, None)
40
+ if value is not None:
41
+ response[name] = value
42
+ print(json.dumps(response), file=sys.stderr)
43
+ return 1
44
+
45
+
46
+ if __name__ == "__main__":
47
+ sys.exit(main())
@@ -0,0 +1,2 @@
1
+ # SPDX-License-Identifier: MIT OR Apache-2.0
2
+ """Compatibility import for callers of the former private bridge module."""