Skip to content

Commit a683c06

Browse files
feat: Add new client parameters: encoding
1 parent af09640 commit a683c06

File tree

4 files changed

+49
-20
lines changed

4 files changed

+49
-20
lines changed

openapi_python_client/__init__.py

+21-12
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ class Project:
4444
project_name_override: Optional[str] = None
4545
package_name_override: Optional[str] = None
4646
package_version_override: Optional[str] = None
47+
encoding: Optional[str] = None
4748

4849
def __init__(self, *, openapi: GeneratorData, meta: MetaType, custom_template_path: Optional[Path] = None) -> None:
4950
self.openapi: GeneratorData = openapi
@@ -137,15 +138,17 @@ def _create_package(self) -> None:
137138
package_init = self.package_dir / "__init__.py"
138139

139140
package_init_template = self.env.get_template("package_init.py.jinja")
140-
package_init.write_text(package_init_template.render(description=self.package_description))
141+
package_init.write_text(
142+
package_init_template.render(description=self.package_description), encoding=self.encoding
143+
)
141144

142145
if self.meta != MetaType.NONE:
143146
pytyped = self.package_dir / "py.typed"
144-
pytyped.write_text("# Marker file for PEP 561")
147+
pytyped.write_text("# Marker file for PEP 561", encoding=self.encoding)
145148

146149
types_template = self.env.get_template("types.py.jinja")
147150
types_path = self.package_dir / "types.py"
148-
types_path.write_text(types_template.render())
151+
types_path.write_text(types_template.render(), encoding=self.encoding)
149152

150153
def _build_metadata(self) -> None:
151154
if self.meta == MetaType.NONE:
@@ -167,7 +170,7 @@ def _build_metadata(self) -> None:
167170
# .gitignore
168171
git_ignore_path = self.project_dir / ".gitignore"
169172
git_ignore_template = self.env.get_template(".gitignore.jinja")
170-
git_ignore_path.write_text(git_ignore_template.render())
173+
git_ignore_path.write_text(git_ignore_template.render(), encoding=self.encoding)
171174

172175
def _build_pyproject_toml(self, *, use_poetry: bool) -> None:
173176
template = "pyproject.toml.jinja" if use_poetry else "pyproject_no_poetry.toml.jinja"
@@ -204,7 +207,7 @@ def _build_models(self) -> None:
204207
model_template = self.env.get_template("model.py.jinja")
205208
for model in self.openapi.models.values():
206209
module_path = models_dir / f"{model.reference.module_name}.py"
207-
module_path.write_text(model_template.render(model=model))
210+
module_path.write_text(model_template.render(model=model), encoding=self.encoding)
208211
imports.append(import_string_from_reference(model.reference))
209212

210213
# Generate enums
@@ -213,25 +216,25 @@ def _build_models(self) -> None:
213216
for enum in self.openapi.enums.values():
214217
module_path = models_dir / f"{enum.reference.module_name}.py"
215218
if enum.value_type is int:
216-
module_path.write_text(int_enum_template.render(enum=enum))
219+
module_path.write_text(int_enum_template.render(enum=enum), encoding=self.encoding)
217220
else:
218-
module_path.write_text(str_enum_template.render(enum=enum))
221+
module_path.write_text(str_enum_template.render(enum=enum), encoding=self.encoding)
219222
imports.append(import_string_from_reference(enum.reference))
220223

221224
models_init_template = self.env.get_template("models_init.py.jinja")
222-
models_init.write_text(models_init_template.render(imports=imports))
225+
models_init.write_text(models_init_template.render(imports=imports), encoding=self.encoding)
223226

224227
def _build_api(self) -> None:
225228
# Generate Client
226229
client_path = self.package_dir / "client.py"
227230
client_template = self.env.get_template("client.py.jinja")
228-
client_path.write_text(client_template.render())
231+
client_path.write_text(client_template.render(), encoding=self.encoding)
229232

230233
# Generate endpoints
231234
api_dir = self.package_dir / "api"
232235
api_dir.mkdir()
233236
api_init = api_dir / "__init__.py"
234-
api_init.write_text('""" Contains methods for accessing the API """')
237+
api_init.write_text('""" Contains methods for accessing the API """', encoding=self.encoding)
235238

236239
endpoint_template = self.env.get_template("endpoint_module.py.jinja")
237240
for tag, collection in self.openapi.endpoint_collections_by_tag.items():
@@ -242,7 +245,7 @@ def _build_api(self) -> None:
242245

243246
for endpoint in collection.endpoints:
244247
module_path = tag_dir / f"{snake_case(endpoint.name)}.py"
245-
module_path.write_text(endpoint_template.render(endpoint=endpoint))
248+
module_path.write_text(endpoint_template.render(endpoint=endpoint), encoding=self.encoding)
246249

247250

248251
def _get_project_for_url_or_path(
@@ -258,7 +261,12 @@ def _get_project_for_url_or_path(
258261

259262

260263
def create_new_client(
261-
*, url: Optional[str], path: Optional[Path], meta: MetaType, custom_template_path: Optional[Path] = None
264+
*,
265+
url: Optional[str],
266+
path: Optional[Path],
267+
meta: MetaType,
268+
custom_template_path: Optional[Path] = None,
269+
encoding=Optional[str],
262270
) -> Sequence[GeneratorError]:
263271
"""
264272
Generate the client library
@@ -267,6 +275,7 @@ def create_new_client(
267275
A list containing any errors encountered when generating.
268276
"""
269277
project = _get_project_for_url_or_path(url=url, path=path, custom_template_path=custom_template_path, meta=meta)
278+
project.encoding = encoding
270279
if isinstance(project, GeneratorError):
271280
return [project]
272281
return project.build()

openapi_python_client/cli.py

+4-1
Original file line numberDiff line numberDiff line change
@@ -116,6 +116,7 @@ def generate(
116116
url: Optional[str] = typer.Option(None, help="A URL to read the JSON from"),
117117
path: Optional[pathlib.Path] = typer.Option(None, help="A path to the JSON file"),
118118
custom_template_path: Optional[pathlib.Path] = typer.Option(None, **custom_template_path_options), # type: ignore
119+
encoding: Optional[str] = typer.Option(None, help="Set file encoding for client files"), # type: ignore
119120
meta: MetaType = _meta_option,
120121
) -> None:
121122
""" Generate a new OpenAPI Client library """
@@ -127,7 +128,9 @@ def generate(
127128
if url and path:
128129
typer.secho("Provide either --url or --path, not both", fg=typer.colors.RED)
129130
raise typer.Exit(code=1)
130-
errors = create_new_client(url=url, path=path, meta=meta, custom_template_path=custom_template_path)
131+
errors = create_new_client(
132+
url=url, path=path, meta=meta, custom_template_path=custom_template_path, encoding=encoding
133+
)
131134
handle_errors(errors)
132135

133136

tests/test___init__.py

+2-2
Original file line numberDiff line numberDiff line change
@@ -394,7 +394,7 @@ def test__build_metadata_poetry(self, mocker):
394394
)
395395
readme_path.write_text.assert_called_once_with(readme_template.render())
396396
git_ignore_template.render.assert_called_once()
397-
git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render())
397+
git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding=None)
398398
project._build_pyproject_toml.assert_called_once_with(use_poetry=True)
399399

400400
def test__build_metadata_setup(self, mocker):
@@ -431,7 +431,7 @@ def test__build_metadata_setup(self, mocker):
431431
)
432432
readme_path.write_text.assert_called_once_with(readme_template.render())
433433
git_ignore_template.render.assert_called_once()
434-
git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render())
434+
git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding=None)
435435
project._build_pyproject_toml.assert_called_once_with(use_poetry=False)
436436
project._build_setup_py.assert_called_once()
437437

tests/test_cli.py

+22-5
Original file line numberDiff line numberDiff line change
@@ -31,13 +31,16 @@ def test_config_arg(mocker, _create_new_client):
3131

3232
config_path = "config/path"
3333
path = "cool/path"
34+
encoding = "utf-8"
3435

35-
result = runner.invoke(app, [f"--config={config_path}", "generate", f"--path={path}"], catch_exceptions=False)
36+
result = runner.invoke(
37+
app, [f"--config={config_path}", "generate", f"--path={path}", f"--encoding={encoding}"], catch_exceptions=False
38+
)
3639

3740
assert result.exit_code == 0
3841
load_config.assert_called_once_with(path=Path(config_path))
3942
_create_new_client.assert_called_once_with(
40-
url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY
43+
url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding="utf-8"
4144
)
4245

4346

@@ -82,7 +85,9 @@ def test_generate_url(self, _create_new_client):
8285
result = runner.invoke(app, ["generate", f"--url={url}"])
8386

8487
assert result.exit_code == 0
85-
_create_new_client.assert_called_once_with(url=url, path=None, custom_template_path=None, meta=MetaType.POETRY)
88+
_create_new_client.assert_called_once_with(
89+
url=url, path=None, custom_template_path=None, meta=MetaType.POETRY, encoding=None
90+
)
8691

8792
def test_generate_path(self, _create_new_client):
8893
path = "cool/path"
@@ -92,7 +97,7 @@ def test_generate_path(self, _create_new_client):
9297

9398
assert result.exit_code == 0
9499
_create_new_client.assert_called_once_with(
95-
url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY
100+
url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding=None
96101
)
97102

98103
def test_generate_meta(self, _create_new_client):
@@ -103,7 +108,19 @@ def test_generate_meta(self, _create_new_client):
103108

104109
assert result.exit_code == 0
105110
_create_new_client.assert_called_once_with(
106-
url=None, path=Path(path), custom_template_path=None, meta=MetaType.NONE
111+
url=None, path=Path(path), custom_template_path=None, meta=MetaType.NONE, encoding=None
112+
)
113+
114+
def test_generate_encoding(self, _create_new_client):
115+
path = "cool/path"
116+
encoding = "utf-8"
117+
from openapi_python_client.cli import MetaType, app
118+
119+
result = runner.invoke(app, ["generate", f"--path={path}", f"--encoding={encoding}"])
120+
121+
assert result.exit_code == 0
122+
_create_new_client.assert_called_once_with(
123+
url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding="utf-8"
107124
)
108125

109126
def test_generate_handle_errors(self, _create_new_client):

0 commit comments

Comments
 (0)