pyrpc-codegen 0.3.3__tar.gz → 0.6.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.
- {pyrpc_codegen-0.3.3 → pyrpc_codegen-0.6.1}/PKG-INFO +1 -1
- pyrpc_codegen-0.6.1/README.md +21 -0
- {pyrpc_codegen-0.3.3 → pyrpc_codegen-0.6.1}/pyproject.toml +1 -1
- {pyrpc_codegen-0.3.3 → pyrpc_codegen-0.6.1}/src/pyrpc_codegen/ts_codegen.py +5 -3
- pyrpc_codegen-0.6.1/tests/test_codegen.py +91 -0
- {pyrpc_codegen-0.3.3 → pyrpc_codegen-0.6.1}/.gitignore +0 -0
- {pyrpc_codegen-0.3.3 → pyrpc_codegen-0.6.1}/src/pyrpc_codegen/__init__.py +0 -0
- {pyrpc_codegen-0.3.3 → pyrpc_codegen-0.6.1}/src/pyrpc_codegen/templates/client.ts.j2 +0 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
# pyrpc-codegen
|
|
2
|
+
|
|
3
|
+
Code generation utilities for [pyRPC](https://pyrpc.com). Generates TypeScript type definitions from Python procedure schemas.
|
|
4
|
+
|
|
5
|
+
## What it does
|
|
6
|
+
|
|
7
|
+
- `generate_typescript_client(schemas)` - generates TypeScript interface source code from a schema dict
|
|
8
|
+
- `save_typescript_client(schemas, output_path)` - generates and writes TypeScript types to a file
|
|
9
|
+
- `DEFAULT_OUTPUT` - default output filename constant
|
|
10
|
+
|
|
11
|
+
## Installation
|
|
12
|
+
|
|
13
|
+
Installed automatically as a dependency of `pyrpc-core`:
|
|
14
|
+
|
|
15
|
+
```bash
|
|
16
|
+
uv add pyrpc-core
|
|
17
|
+
```
|
|
18
|
+
|
|
19
|
+
## License
|
|
20
|
+
|
|
21
|
+
MIT
|
|
@@ -141,10 +141,12 @@ def generate_typescript_client(schemas: Dict[str, Any]) -> str:
|
|
|
141
141
|
)
|
|
142
142
|
|
|
143
143
|
|
|
144
|
-
def save_typescript_client(schemas: Dict[str, Any], output_path: str
|
|
145
|
-
content = generate_typescript_client(schemas)
|
|
144
|
+
def save_typescript_client(schemas: Dict[str, Any], output_path: str):
|
|
146
145
|
if not os.path.isabs(output_path):
|
|
147
|
-
|
|
146
|
+
raise ValueError(
|
|
147
|
+
"save_typescript_client requires an absolute path"
|
|
148
|
+
)
|
|
149
|
+
content = generate_typescript_client(schemas)
|
|
148
150
|
os.makedirs(os.path.dirname(output_path), exist_ok=True)
|
|
149
151
|
with open(output_path, "w", encoding="utf-8") as f:
|
|
150
152
|
f.write(content)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import os
|
|
3
|
+
import tempfile
|
|
4
|
+
import pytest
|
|
5
|
+
from pyrpc_core import rpc, default_router, get_registry_schema
|
|
6
|
+
from pyrpc_codegen import generate_typescript_client, save_typescript_client
|
|
7
|
+
|
|
8
|
+
|
|
9
|
+
@pytest.fixture(autouse=True)
|
|
10
|
+
def clear_registry():
|
|
11
|
+
default_router._procedures.clear()
|
|
12
|
+
|
|
13
|
+
|
|
14
|
+
def test_generate_typescript_client():
|
|
15
|
+
@rpc
|
|
16
|
+
def add(a: int, b: int) -> int:
|
|
17
|
+
"""Add two numbers."""
|
|
18
|
+
return a + b
|
|
19
|
+
|
|
20
|
+
schemas = get_registry_schema(default_router)
|
|
21
|
+
content = generate_typescript_client(schemas)
|
|
22
|
+
|
|
23
|
+
assert "export interface Types" in content
|
|
24
|
+
assert "add(a: number, b: number): Promise<number>;" in content
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
def test_generate_typescript_client_empty():
|
|
28
|
+
schemas = get_registry_schema(default_router)
|
|
29
|
+
content = generate_typescript_client(schemas)
|
|
30
|
+
assert "export interface Types {" in content
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def test_save_typescript_client_from_file():
|
|
34
|
+
schemas = {
|
|
35
|
+
"greet": {
|
|
36
|
+
"name": "greet",
|
|
37
|
+
"doc": "Say hello",
|
|
38
|
+
"parameters": [
|
|
39
|
+
{"name": "name", "type": "<class 'str'>", "required": True, "default": None}
|
|
40
|
+
],
|
|
41
|
+
"return_type": "<class 'str'>",
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
|
|
45
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
46
|
+
schema_file = os.path.join(tmpdir, "schema.json")
|
|
47
|
+
with open(schema_file, "w") as f:
|
|
48
|
+
json.dump(schemas, f)
|
|
49
|
+
|
|
50
|
+
from pyrpc_core.cli import _load_schema
|
|
51
|
+
loaded = _load_schema(schema_file)
|
|
52
|
+
assert loaded == schemas
|
|
53
|
+
|
|
54
|
+
output_file = os.path.join(tmpdir, "types.ts")
|
|
55
|
+
save_typescript_client(schemas, output_file)
|
|
56
|
+
|
|
57
|
+
with open(output_file) as f:
|
|
58
|
+
content = f.read()
|
|
59
|
+
|
|
60
|
+
assert "export interface Types" in content
|
|
61
|
+
assert "greet(name: string): Promise<string>;" in content
|
|
62
|
+
|
|
63
|
+
|
|
64
|
+
def test_save_typescript_client_serialized_schema():
|
|
65
|
+
@rpc
|
|
66
|
+
def add(a: int) -> int:
|
|
67
|
+
return a
|
|
68
|
+
|
|
69
|
+
schemas = get_registry_schema(default_router)
|
|
70
|
+
|
|
71
|
+
serializable = {}
|
|
72
|
+
for name, schema in schemas.items():
|
|
73
|
+
serializable[name] = {
|
|
74
|
+
"name": schema.name,
|
|
75
|
+
"doc": schema.doc or "",
|
|
76
|
+
"parameters": [
|
|
77
|
+
{"name": p.name, "type": p.type, "required": p.required, "default": p.default}
|
|
78
|
+
for p in schema.parameters
|
|
79
|
+
],
|
|
80
|
+
"return_type": schema.return_type,
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
with tempfile.TemporaryDirectory() as tmpdir:
|
|
84
|
+
output_file = os.path.join(tmpdir, "types.ts")
|
|
85
|
+
save_typescript_client(serializable, output_file)
|
|
86
|
+
|
|
87
|
+
with open(output_file) as f:
|
|
88
|
+
content = f.read()
|
|
89
|
+
|
|
90
|
+
assert "export interface Types" in content
|
|
91
|
+
assert "add(a: number): Promise<number>;" in content
|
|
File without changes
|
|
File without changes
|
|
File without changes
|