openapi-client-codegen 0.1.4__py3-none-any.whl → 0.1.6__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.
- openapi_client_codegen/cli.py +57 -68
- openapi_client_codegen/client.py +6 -1
- openapi_client_codegen/orchestrator.py +24 -82
- {openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/METADATA +2 -1
- {openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/RECORD +9 -10
- openapi_client_codegen/naming.py +0 -26
- {openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/WHEEL +0 -0
- {openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/entry_points.txt +0 -0
- {openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/licenses/LICENSE +0 -0
- {openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/licenses/NOTICE +0 -0
openapi_client_codegen/cli.py
CHANGED
|
@@ -3,71 +3,21 @@ from pathlib import Path
|
|
|
3
3
|
from tempfile import TemporaryDirectory
|
|
4
4
|
from typing import Annotated
|
|
5
5
|
|
|
6
|
-
from typer import
|
|
6
|
+
from typer import Option, Typer
|
|
7
7
|
|
|
8
8
|
from .client import generate_client
|
|
9
9
|
from .downgrade import downgrade_openapi_3_1_to_3_0
|
|
10
|
-
from .
|
|
11
|
-
from .orchestrator import SpecProducer, generate_projects
|
|
10
|
+
from .orchestrator import ClientNaming, ProjectsConfig, SpecProducer
|
|
12
11
|
from .templates import regenerate_templates
|
|
13
12
|
|
|
14
13
|
app = Typer(pretty_exceptions_show_locals=False)
|
|
15
14
|
|
|
16
15
|
|
|
17
16
|
@app.command()
|
|
18
|
-
def downgrade(
|
|
19
|
-
input_file: Annotated[Path, Argument(help="OpenAPI 3.1 JSON to downgrade to 3.0.3")],
|
|
20
|
-
output_file: Annotated[Path | None, Argument(help="Write here instead of overwriting input_file")] = None,
|
|
21
|
-
) -> None:
|
|
22
|
-
schema = json.loads(input_file.read_text(encoding="utf-8"))
|
|
23
|
-
downgrade_openapi_3_1_to_3_0(schema)
|
|
24
|
-
destination = output_file if output_file is not None else input_file
|
|
25
|
-
destination.write_text(json.dumps(schema, indent=2), encoding="utf-8")
|
|
26
|
-
|
|
27
|
-
|
|
28
|
-
@app.command()
|
|
29
|
-
def generate(
|
|
30
|
-
spec_file: Annotated[Path, Argument(help="OpenAPI 3.0 spec JSON to generate from")],
|
|
31
|
-
output_dir: Annotated[Path, Argument(help="Directory to sync the generated client into")],
|
|
32
|
-
root_name: Annotated[str, Option(help="Root name handed to DefaultNamingPolicy")],
|
|
33
|
-
project: Annotated[str, Option(help="Project path; its last segment names the client")],
|
|
34
|
-
generator: Annotated[str, Option(help="openapi-generator generator name")] = "csharp",
|
|
35
|
-
npm_scope: Annotated[str | None, Option(help="npm scope composing the UPM package identity")] = None,
|
|
36
|
-
license_spdx: Annotated[str | None, Option(help="SPDX license id written to package.json")] = None,
|
|
37
|
-
repository_url: Annotated[str | None, Option(help="git repository URL written to package.json")] = None,
|
|
38
|
-
) -> None:
|
|
39
|
-
with TemporaryDirectory() as templates_directory_string:
|
|
40
|
-
templates_directory = Path(templates_directory_string)
|
|
41
|
-
templates_dir = templates_directory if generator == "csharp" else None
|
|
42
|
-
if templates_dir is not None:
|
|
43
|
-
regenerate_templates(templates_dir)
|
|
44
|
-
|
|
45
|
-
generate_client(
|
|
46
|
-
spec_file.read_text(encoding="utf-8"),
|
|
47
|
-
generator,
|
|
48
|
-
output_dir,
|
|
49
|
-
DefaultNamingPolicy(root_name)(project),
|
|
50
|
-
templates_dir=templates_dir,
|
|
51
|
-
npm_scope=npm_scope,
|
|
52
|
-
license_spdx=license_spdx,
|
|
53
|
-
repository_url=repository_url,
|
|
54
|
-
)
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
@app.command("generate-projects")
|
|
58
17
|
def generate_projects_command(
|
|
59
|
-
config: Annotated[
|
|
60
|
-
|
|
61
|
-
generated_root: Annotated[Path, Option(help="Root directory the generated clients sync into")],
|
|
62
|
-
spec_command: Annotated[
|
|
63
|
-
str,
|
|
64
|
-
Option(
|
|
65
|
-
help="Shell command printing the project's raw OpenAPI JSON to stdout; runs with the project directory as cwd"
|
|
66
|
-
),
|
|
18
|
+
config: Annotated[
|
|
19
|
+
Path, Option(help="JSON config carrying the projects mapping, the client identity, and the spec command")
|
|
67
20
|
],
|
|
68
|
-
npm_scope: Annotated[str | None, Option(help="npm scope composing the UPM package identity")] = None,
|
|
69
|
-
license_spdx: Annotated[str | None, Option(help="SPDX license id written to package.json")] = None,
|
|
70
|
-
repository_url: Annotated[str | None, Option(help="git repository URL written to package.json")] = None,
|
|
71
21
|
project: Annotated[str | None, Option(help="Generate only this project, as keyed in the config")] = None,
|
|
72
22
|
client: Annotated[str | None, Option(help="Generate only this client generator")] = None,
|
|
73
23
|
no_cache: Annotated[
|
|
@@ -75,17 +25,56 @@ def generate_projects_command(
|
|
|
75
25
|
] = False,
|
|
76
26
|
root: Annotated[Path, Option(help="Repository root the project paths resolve against")] = Path(),
|
|
77
27
|
) -> None:
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
86
|
-
|
|
87
|
-
|
|
88
|
-
|
|
89
|
-
|
|
90
|
-
|
|
91
|
-
|
|
28
|
+
settings = ProjectsConfig.model_validate_json(config.read_text(encoding="utf-8"))
|
|
29
|
+
root = root.resolve()
|
|
30
|
+
dump_spec = SpecProducer(settings.spec_command, env=settings.spec_env)
|
|
31
|
+
|
|
32
|
+
with TemporaryDirectory() as templates_directory_string:
|
|
33
|
+
templates_directory = Path(templates_directory_string)
|
|
34
|
+
regenerate_templates(templates_directory)
|
|
35
|
+
|
|
36
|
+
for project_name, clients in settings.projects.items():
|
|
37
|
+
if project is not None and project != project_name:
|
|
38
|
+
continue
|
|
39
|
+
|
|
40
|
+
project_directory = root / project_name
|
|
41
|
+
print(f"Producing OpenAPI spec for project: {project_directory}")
|
|
42
|
+
|
|
43
|
+
openapi_json = json.loads(dump_spec(project_directory))
|
|
44
|
+
downgrade_openapi_3_1_to_3_0(openapi_json)
|
|
45
|
+
openapi_spec = json.dumps(openapi_json, indent=2)
|
|
46
|
+
|
|
47
|
+
spec_path = project_directory / "openapi.json"
|
|
48
|
+
|
|
49
|
+
if spec_path.exists():
|
|
50
|
+
old_spec = spec_path.read_text(encoding="utf-8")
|
|
51
|
+
|
|
52
|
+
if openapi_spec == old_spec and not no_cache:
|
|
53
|
+
print("OpenAPI spec unchanged, skipping client generation")
|
|
54
|
+
continue
|
|
55
|
+
|
|
56
|
+
spec_path.write_text(openapi_spec, encoding="utf-8")
|
|
57
|
+
|
|
58
|
+
base = f"{project_name.rsplit('/', maxsplit=1)[-1]}-client"
|
|
59
|
+
dashed = f"{settings.root_name}-{base}"
|
|
60
|
+
names = ClientNaming(
|
|
61
|
+
base=base,
|
|
62
|
+
dashed=dashed,
|
|
63
|
+
underscored=dashed.replace("-", "_"),
|
|
64
|
+
camel=f"{settings.root_name.capitalize()}{''.join(part.capitalize() for part in base.split('-'))}",
|
|
65
|
+
)
|
|
66
|
+
|
|
67
|
+
for client_name in clients:
|
|
68
|
+
if client is not None and client_name != client:
|
|
69
|
+
continue
|
|
70
|
+
|
|
71
|
+
generate_client(
|
|
72
|
+
openapi_spec,
|
|
73
|
+
client_name,
|
|
74
|
+
settings.generated_root / client_name / names.base,
|
|
75
|
+
names,
|
|
76
|
+
templates_dir=templates_directory,
|
|
77
|
+
npm_scope=settings.npm_scope,
|
|
78
|
+
license_spdx=settings.license_spdx,
|
|
79
|
+
repository_url=settings.repository_url,
|
|
80
|
+
)
|
openapi_client_codegen/client.py
CHANGED
|
@@ -1,15 +1,20 @@
|
|
|
1
|
+
from __future__ import annotations
|
|
2
|
+
|
|
1
3
|
import json
|
|
2
4
|
from os import walk
|
|
3
5
|
from pathlib import Path
|
|
4
6
|
from shutil import copytree
|
|
5
7
|
from tempfile import NamedTemporaryFile, TemporaryDirectory
|
|
8
|
+
from typing import TYPE_CHECKING
|
|
6
9
|
|
|
7
10
|
from bashrun.bash import bash
|
|
8
11
|
|
|
9
12
|
from .resources import CONFIGS_DIR, IGNORE_FILE, OPENAPI_GENERATOR_CLI_VERSION
|
|
10
|
-
from .naming import ClientNaming
|
|
11
13
|
from .unity import write_unity_package_metadata
|
|
12
14
|
|
|
15
|
+
if TYPE_CHECKING:
|
|
16
|
+
from .orchestrator import ClientNaming
|
|
17
|
+
|
|
13
18
|
_HTTP_METHODS = ("get", "put", "post", "delete", "patch", "options", "head", "trace")
|
|
14
19
|
|
|
15
20
|
|
|
@@ -1,95 +1,37 @@
|
|
|
1
1
|
from __future__ import annotations
|
|
2
2
|
|
|
3
|
-
import
|
|
4
|
-
from collections.abc import Callable
|
|
3
|
+
from dataclasses import dataclass
|
|
5
4
|
from pathlib import Path
|
|
6
|
-
from tempfile import TemporaryDirectory
|
|
7
5
|
|
|
8
6
|
from bashrun.bash import bash_output
|
|
7
|
+
from pydantic import BaseModel, ConfigDict
|
|
9
8
|
|
|
10
|
-
from .client import generate_client
|
|
11
|
-
from .downgrade import downgrade_openapi_3_1_to_3_0
|
|
12
|
-
from .naming import DefaultNamingPolicy
|
|
13
|
-
from .templates import regenerate_templates
|
|
14
9
|
|
|
10
|
+
class ProjectsConfig(BaseModel):
|
|
11
|
+
model_config = ConfigDict(extra="forbid")
|
|
15
12
|
|
|
16
|
-
|
|
17
|
-
|
|
18
|
-
|
|
19
|
-
|
|
20
|
-
|
|
21
|
-
|
|
22
|
-
|
|
23
|
-
|
|
24
|
-
def generate_projects(
|
|
25
|
-
projects: dict[str, list[str]],
|
|
26
|
-
root_name: str,
|
|
27
|
-
generated_root: Path,
|
|
28
|
-
dump_spec: Callable[[Path], str],
|
|
29
|
-
npm_scope: str | None = None,
|
|
30
|
-
license_spdx: str | None = None,
|
|
31
|
-
repository_url: str | None = None,
|
|
32
|
-
project: str | None = None,
|
|
33
|
-
client: str | None = None,
|
|
34
|
-
no_cache: bool = False,
|
|
35
|
-
root: Path = Path(),
|
|
36
|
-
) -> None:
|
|
37
|
-
root = root.resolve()
|
|
38
|
-
naming = DefaultNamingPolicy(root_name)
|
|
39
|
-
|
|
40
|
-
with TemporaryDirectory() as templates_directory_string:
|
|
41
|
-
templates_directory = Path(templates_directory_string)
|
|
42
|
-
regenerate_templates(templates_directory)
|
|
43
|
-
|
|
44
|
-
for project_name, clients in projects.items():
|
|
45
|
-
if project is not None and project != project_name:
|
|
46
|
-
continue
|
|
47
|
-
|
|
48
|
-
openapi_spec = _produce_and_cache_spec(root / project_name, dump_spec, no_cache)
|
|
49
|
-
|
|
50
|
-
if openapi_spec is None:
|
|
51
|
-
continue
|
|
52
|
-
|
|
53
|
-
names = naming(project_name)
|
|
13
|
+
projects: dict[str, list[str]]
|
|
14
|
+
root_name: str
|
|
15
|
+
generated_root: Path
|
|
16
|
+
spec_command: str
|
|
17
|
+
spec_env: dict[str, str] | None = None
|
|
18
|
+
npm_scope: str | None = None
|
|
19
|
+
license_spdx: str | None = None
|
|
20
|
+
repository_url: str | None = None
|
|
54
21
|
|
|
55
|
-
for client_name in clients:
|
|
56
|
-
if client is not None and client_name != client:
|
|
57
|
-
continue
|
|
58
22
|
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
npm_scope=npm_scope,
|
|
66
|
-
license_spdx=license_spdx,
|
|
67
|
-
repository_url=repository_url,
|
|
68
|
-
)
|
|
23
|
+
@dataclass(frozen=True)
|
|
24
|
+
class ClientNaming:
|
|
25
|
+
base: str
|
|
26
|
+
dashed: str
|
|
27
|
+
underscored: str
|
|
28
|
+
camel: str
|
|
69
29
|
|
|
70
30
|
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
def _produce_and_cache_spec(project: Path, dump_spec: Callable[[Path], str], no_cache: bool) -> str | None:
|
|
78
|
-
print(f"Producing OpenAPI spec for project: {project}")
|
|
79
|
-
|
|
80
|
-
openapi_json = json.loads(dump_spec(project))
|
|
81
|
-
downgrade_openapi_3_1_to_3_0(openapi_json)
|
|
82
|
-
openapi_spec = json.dumps(openapi_json, indent=2)
|
|
83
|
-
|
|
84
|
-
spec_path = project / "openapi.json"
|
|
85
|
-
|
|
86
|
-
if spec_path.exists():
|
|
87
|
-
old_spec = spec_path.read_text(encoding="utf-8")
|
|
88
|
-
|
|
89
|
-
if openapi_spec == old_spec and not no_cache:
|
|
90
|
-
print("OpenAPI spec unchanged, skipping client generation")
|
|
91
|
-
return None
|
|
92
|
-
|
|
93
|
-
spec_path.write_text(openapi_spec, encoding="utf-8")
|
|
31
|
+
class SpecProducer:
|
|
32
|
+
def __init__(self, command: str, env: dict[str, str] | None = None) -> None:
|
|
33
|
+
self.command = command
|
|
34
|
+
self.env = env
|
|
94
35
|
|
|
95
|
-
|
|
36
|
+
def __call__(self, project: Path) -> str:
|
|
37
|
+
return bash_output(self.command, cwd=project, env=self.env)
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: openapi-client-codegen
|
|
3
|
-
Version: 0.1.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: OpenAPI client-generation wrapper: Litestar spec dump, 3.1->3.0 downgrade, patched openapi-generator templates, Unity package metadata
|
|
5
5
|
License-File: LICENSE
|
|
6
6
|
License-File: NOTICE
|
|
7
7
|
Requires-Python: >=3.13
|
|
8
8
|
Requires-Dist: bashrun>=0.1.0
|
|
9
|
+
Requires-Dist: pydantic>=2.11.7
|
|
9
10
|
Requires-Dist: typer>=0.17.4
|
|
@@ -1,9 +1,8 @@
|
|
|
1
1
|
openapi_client_codegen/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
2
|
-
openapi_client_codegen/cli.py,sha256=
|
|
3
|
-
openapi_client_codegen/client.py,sha256
|
|
2
|
+
openapi_client_codegen/cli.py,sha256=Gtv8sUzIf3othiPGcp2U6RPAbc8iQ1h1HRNe8s_FgNQ,3243
|
|
3
|
+
openapi_client_codegen/client.py,sha256=-lflu6eix2nCcHFkMrbCp0YgL9PVyQuLQS1r5Zfd0YQ,4736
|
|
4
4
|
openapi_client_codegen/downgrade.py,sha256=7cxQZJRgWR5lNpvyJT-6pg4lVj72LsMRfdYzsNF9DtY,5230
|
|
5
|
-
openapi_client_codegen/
|
|
6
|
-
openapi_client_codegen/orchestrator.py,sha256=83Kb1kT1R0fgfaq6MBA0HDBjw-L-Mo051cyqHROlSzI,3076
|
|
5
|
+
openapi_client_codegen/orchestrator.py,sha256=AU_KvKiCZBeRx9J3dPIQfQnNi23tyupQED6cSETQr5s,893
|
|
7
6
|
openapi_client_codegen/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
|
|
8
7
|
openapi_client_codegen/resources.py,sha256=Vavy0_zqot1eDrFpDJ_BT4Sbx47vh7zuclPjQtW3QMw,266
|
|
9
8
|
openapi_client_codegen/templates.py,sha256=ll3NQfdnpVgDOz4WJrEga5lHljEOOItSD1aeVP5Hp80,1198
|
|
@@ -18,9 +17,9 @@ openapi_client_codegen/_data/templates-patches/csharp/0004-csharp-support-hybrid
|
|
|
18
17
|
openapi_client_codegen/_data/templates-patches/csharp/0006-csharp-streaming-download-response.patch,sha256=ma-QkJA94jmN3scbJifaVPMcg_NNZ8klVO2HUrLMz_Y,2417
|
|
19
18
|
openapi_client_codegen/_data/templates-patches/csharp/0007-csharp-model-default-initializers.patch,sha256=_fIimm7K0Gh1IYE3_fYyhUom_g-Bm4HlN9jLgsP27IE,862
|
|
20
19
|
openapi_client_codegen/_data/templates-patches/csharp/0008-csharp-redirect-documentation-file.patch,sha256=HQXDgm_CzFYK4oxOoqBkYAz4wrKKPlYpLgTNHI_0IYc,1363
|
|
21
|
-
openapi_client_codegen-0.1.
|
|
22
|
-
openapi_client_codegen-0.1.
|
|
23
|
-
openapi_client_codegen-0.1.
|
|
24
|
-
openapi_client_codegen-0.1.
|
|
25
|
-
openapi_client_codegen-0.1.
|
|
26
|
-
openapi_client_codegen-0.1.
|
|
20
|
+
openapi_client_codegen-0.1.6.dist-info/METADATA,sha256=wXc2KsOyunO09qTp9UPPHXKYm_S8M10J55jIBNe_oQw,368
|
|
21
|
+
openapi_client_codegen-0.1.6.dist-info/WHEEL,sha256=W3fkpkm7-wf9vBI5Z-7s0eWkeM-spu78I8Neb98DeEg,87
|
|
22
|
+
openapi_client_codegen-0.1.6.dist-info/entry_points.txt,sha256=mw8FL3PBefHSxRjhBJunBk9G1efUKgxNXwAlghbc31E,74
|
|
23
|
+
openapi_client_codegen-0.1.6.dist-info/licenses/LICENSE,sha256=RFhQPdSOiMTguUX7JSoIuTxA7HVzCbj_p8WU36HjUQQ,10947
|
|
24
|
+
openapi_client_codegen-0.1.6.dist-info/licenses/NOTICE,sha256=jvglZza3GCdN7v4_TLuXUqX9C_uABlwAKUkcIeKwk_8,26
|
|
25
|
+
openapi_client_codegen-0.1.6.dist-info/RECORD,,
|
openapi_client_codegen/naming.py
DELETED
|
@@ -1,26 +0,0 @@
|
|
|
1
|
-
from dataclasses import dataclass
|
|
2
|
-
from typing import Protocol
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
@dataclass(frozen=True)
|
|
6
|
-
class ClientNaming:
|
|
7
|
-
base: str
|
|
8
|
-
dashed: str
|
|
9
|
-
underscored: str
|
|
10
|
-
camel: str
|
|
11
|
-
|
|
12
|
-
|
|
13
|
-
class NamingPolicy(Protocol):
|
|
14
|
-
def __call__(self, project: str) -> ClientNaming: ...
|
|
15
|
-
|
|
16
|
-
|
|
17
|
-
@dataclass(frozen=True)
|
|
18
|
-
class DefaultNamingPolicy:
|
|
19
|
-
root_name: str
|
|
20
|
-
|
|
21
|
-
def __call__(self, project: str) -> ClientNaming:
|
|
22
|
-
base = f"{project.rsplit('/', maxsplit=1)[-1]}-client"
|
|
23
|
-
dashed = f"{self.root_name}-{base}"
|
|
24
|
-
underscored = dashed.replace("-", "_")
|
|
25
|
-
camel = f"{self.root_name.capitalize()}{''.join(part.capitalize() for part in base.split('-'))}"
|
|
26
|
-
return ClientNaming(base=base, dashed=dashed, underscored=underscored, camel=camel)
|
|
File without changes
|
{openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/entry_points.txt
RENAMED
|
File without changes
|
{openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/licenses/LICENSE
RENAMED
|
File without changes
|
{openapi_client_codegen-0.1.4.dist-info → openapi_client_codegen-0.1.6.dist-info}/licenses/NOTICE
RENAMED
|
File without changes
|