From 3e7732f7e39ee0fd3e13d0768ac2e3891590a0a0 Mon Sep 17 00:00:00 2001 From: dongfangtianyu <7629022+dongfangtianyu@users.noreply.github.com> Date: Mon, 8 Feb 2021 21:27:04 +0800 Subject: [PATCH 1/6] feat: Add new client parameters: encoding --- openapi_python_client/__init__.py | 65 +++++++++++++++++++++---------- openapi_python_client/cli.py | 5 ++- tests/test___init__.py | 18 ++++----- tests/test_cli.py | 27 ++++++++++--- 4 files changed, 80 insertions(+), 35 deletions(-) diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index 8c97d45e9..9ab7821a1 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -44,10 +44,19 @@ class Project: project_name_override: Optional[str] = None package_name_override: Optional[str] = None package_version_override: Optional[str] = None - - def __init__(self, *, openapi: GeneratorData, meta: MetaType, custom_template_path: Optional[Path] = None) -> None: + encoding: Optional[str] = None + + def __init__( + self, + *, + openapi: GeneratorData, + meta: MetaType, + custom_template_path: Optional[Path] = None, + encoding: Optional[str] = None, + ) -> None: self.openapi: GeneratorData = openapi self.meta: MetaType = meta + self.encoding = encoding package_loader = PackageLoader(__package__) loader: BaseLoader @@ -137,15 +146,17 @@ def _create_package(self) -> None: package_init = self.package_dir / "__init__.py" package_init_template = self.env.get_template("package_init.py.jinja") - package_init.write_text(package_init_template.render(description=self.package_description)) + package_init.write_text( + package_init_template.render(description=self.package_description), encoding=self.encoding + ) if self.meta != MetaType.NONE: pytyped = self.package_dir / "py.typed" - pytyped.write_text("# Marker file for PEP 561") + pytyped.write_text("# Marker file for PEP 561", encoding=self.encoding) types_template = self.env.get_template("types.py.jinja") types_path = self.package_dir / "types.py" - types_path.write_text(types_template.render()) + types_path.write_text(types_template.render(), encoding=self.encoding) def _build_metadata(self) -> None: if self.meta == MetaType.NONE: @@ -161,13 +172,14 @@ def _build_metadata(self) -> None: readme.write_text( readme_template.render( project_name=self.project_name, description=self.package_description, package_name=self.package_name - ) + ), + encoding=self.encoding, ) # .gitignore git_ignore_path = self.project_dir / ".gitignore" git_ignore_template = self.env.get_template(".gitignore.jinja") - git_ignore_path.write_text(git_ignore_template.render()) + git_ignore_path.write_text(git_ignore_template.render(), encoding=self.encoding) def _build_pyproject_toml(self, *, use_poetry: bool) -> None: template = "pyproject.toml.jinja" if use_poetry else "pyproject_no_poetry.toml.jinja" @@ -179,7 +191,8 @@ def _build_pyproject_toml(self, *, use_poetry: bool) -> None: package_name=self.package_name, version=self.version, description=self.package_description, - ) + ), + encoding=self.encoding, ) def _build_setup_py(self) -> None: @@ -191,7 +204,8 @@ def _build_setup_py(self) -> None: package_name=self.package_name, version=self.version, description=self.package_description, - ) + ), + encoding=self.encoding, ) def _build_models(self) -> None: @@ -204,7 +218,7 @@ def _build_models(self) -> None: model_template = self.env.get_template("model.py.jinja") for model in self.openapi.models.values(): module_path = models_dir / f"{model.reference.module_name}.py" - module_path.write_text(model_template.render(model=model)) + module_path.write_text(model_template.render(model=model), encoding=self.encoding) imports.append(import_string_from_reference(model.reference)) # Generate enums @@ -213,25 +227,25 @@ def _build_models(self) -> None: for enum in self.openapi.enums.values(): module_path = models_dir / f"{enum.reference.module_name}.py" if enum.value_type is int: - module_path.write_text(int_enum_template.render(enum=enum)) + module_path.write_text(int_enum_template.render(enum=enum), encoding=self.encoding) else: - module_path.write_text(str_enum_template.render(enum=enum)) + module_path.write_text(str_enum_template.render(enum=enum), encoding=self.encoding) imports.append(import_string_from_reference(enum.reference)) models_init_template = self.env.get_template("models_init.py.jinja") - models_init.write_text(models_init_template.render(imports=imports)) + models_init.write_text(models_init_template.render(imports=imports), encoding=self.encoding) def _build_api(self) -> None: # Generate Client client_path = self.package_dir / "client.py" client_template = self.env.get_template("client.py.jinja") - client_path.write_text(client_template.render()) + client_path.write_text(client_template.render(), encoding=self.encoding) # Generate endpoints api_dir = self.package_dir / "api" api_dir.mkdir() api_init = api_dir / "__init__.py" - api_init.write_text('""" Contains methods for accessing the API """') + api_init.write_text('""" Contains methods for accessing the API """', encoding=self.encoding) endpoint_template = self.env.get_template("endpoint_module.py.jinja") for tag, collection in self.openapi.endpoint_collections_by_tag.items(): @@ -241,11 +255,15 @@ def _build_api(self) -> None: for endpoint in collection.endpoints: module_path = tag_dir / f"{snake_case(endpoint.name)}.py" - module_path.write_text(endpoint_template.render(endpoint=endpoint)) + module_path.write_text(endpoint_template.render(endpoint=endpoint), encoding=self.encoding) def _get_project_for_url_or_path( - url: Optional[str], path: Optional[Path], meta: MetaType, custom_template_path: Optional[Path] = None + url: Optional[str], + path: Optional[Path], + meta: MetaType, + custom_template_path: Optional[Path] = None, + encoding: Optional[str] = None, ) -> Union[Project, GeneratorError]: data_dict = _get_document(url=url, path=path) if isinstance(data_dict, GeneratorError): @@ -253,11 +271,16 @@ def _get_project_for_url_or_path( openapi = GeneratorData.from_dict(data_dict) if isinstance(openapi, GeneratorError): return openapi - return Project(openapi=openapi, custom_template_path=custom_template_path, meta=meta) + return Project(openapi=openapi, custom_template_path=custom_template_path, meta=meta, encoding=encoding) def create_new_client( - *, url: Optional[str], path: Optional[Path], meta: MetaType, custom_template_path: Optional[Path] = None + *, + url: Optional[str], + path: Optional[Path], + meta: MetaType, + custom_template_path: Optional[Path] = None, + encoding: Optional[str] = None, ) -> Sequence[GeneratorError]: """ Generate the client library @@ -265,7 +288,9 @@ def create_new_client( Returns: A list containing any errors encountered when generating. """ - project = _get_project_for_url_or_path(url=url, path=path, custom_template_path=custom_template_path, meta=meta) + project = _get_project_for_url_or_path( + url=url, path=path, custom_template_path=custom_template_path, meta=meta, encoding=encoding + ) if isinstance(project, GeneratorError): return [project] return project.build() diff --git a/openapi_python_client/cli.py b/openapi_python_client/cli.py index ca8565691..131baae5c 100644 --- a/openapi_python_client/cli.py +++ b/openapi_python_client/cli.py @@ -116,6 +116,7 @@ def generate( url: Optional[str] = typer.Option(None, help="A URL to read the JSON from"), path: Optional[pathlib.Path] = typer.Option(None, help="A path to the JSON file"), custom_template_path: Optional[pathlib.Path] = typer.Option(None, **custom_template_path_options), # type: ignore + encoding: Optional[str] = typer.Option(None, help="Set file encoding for client files"), # type: ignore meta: MetaType = _meta_option, ) -> None: """ Generate a new OpenAPI Client library """ @@ -127,7 +128,9 @@ def generate( if url and path: typer.secho("Provide either --url or --path, not both", fg=typer.colors.RED) raise typer.Exit(code=1) - errors = create_new_client(url=url, path=path, meta=meta, custom_template_path=custom_template_path) + errors = create_new_client( + url=url, path=path, meta=meta, custom_template_path=custom_template_path, encoding=encoding + ) handle_errors(errors) diff --git a/tests/test___init__.py b/tests/test___init__.py index d45108181..2a9377bea 100644 --- a/tests/test___init__.py +++ b/tests/test___init__.py @@ -23,7 +23,7 @@ def test__get_project_for_url_or_path(mocker): _get_document.assert_called_once_with(url=url, path=path) from_dict.assert_called_once_with(data_dict) - _Project.assert_called_once_with(openapi=openapi, custom_template_path=None, meta=MetaType.POETRY) + _Project.assert_called_once_with(openapi=openapi, custom_template_path=None, meta=MetaType.POETRY, encoding=None) assert project == _Project.return_value @@ -76,7 +76,7 @@ def test_create_new_client(mocker): result = create_new_client(url=url, path=path, meta=MetaType.POETRY) _get_project_for_url_or_path.assert_called_once_with( - url=url, path=path, custom_template_path=None, meta=MetaType.POETRY + url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, encoding=None ) project.build.assert_called_once() assert result == project.build.return_value @@ -95,7 +95,7 @@ def test_create_new_client_project_error(mocker): result = create_new_client(url=url, path=path, meta=MetaType.POETRY) _get_project_for_url_or_path.assert_called_once_with( - url=url, path=path, custom_template_path=None, meta=MetaType.POETRY + url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, encoding=None ) assert result == [error] @@ -392,9 +392,9 @@ def test__build_metadata_poetry(self, mocker): project_name=project.project_name, package_name=project.package_name, ) - readme_path.write_text.assert_called_once_with(readme_template.render()) + readme_path.write_text.assert_called_once_with(readme_template.render(), encoding=None) git_ignore_template.render.assert_called_once() - git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render()) + git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding=None) project._build_pyproject_toml.assert_called_once_with(use_poetry=True) def test__build_metadata_setup(self, mocker): @@ -429,9 +429,9 @@ def test__build_metadata_setup(self, mocker): project_name=project.project_name, package_name=project.package_name, ) - readme_path.write_text.assert_called_once_with(readme_template.render()) + readme_path.write_text.assert_called_once_with(readme_template.render(), encoding=None) git_ignore_template.render.assert_called_once() - git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render()) + git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding=None) project._build_pyproject_toml.assert_called_once_with(use_poetry=False) project._build_setup_py.assert_called_once() @@ -475,7 +475,7 @@ def test__build_pyproject_toml(self, mocker, use_poetry): version=project.version, description=project.package_description, ) - pyproject_path.write_text.assert_called_once_with(pyproject_template.render()) + pyproject_path.write_text.assert_called_once_with(pyproject_template.render(), encoding=None) def test__build_setup_py(self, mocker): from openapi_python_client import MetaType, Project @@ -505,7 +505,7 @@ def test__build_setup_py(self, mocker): version=project.version, description=project.package_description, ) - setup_path.write_text.assert_called_once_with(setup_template.render()) + setup_path.write_text.assert_called_once_with(setup_template.render(), encoding=None) def test__reformat(mocker): diff --git a/tests/test_cli.py b/tests/test_cli.py index 1c1619a28..85e43a27f 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -31,13 +31,16 @@ def test_config_arg(mocker, _create_new_client): config_path = "config/path" path = "cool/path" + encoding = "utf-8" - result = runner.invoke(app, [f"--config={config_path}", "generate", f"--path={path}"], catch_exceptions=False) + result = runner.invoke( + app, [f"--config={config_path}", "generate", f"--path={path}", f"--encoding={encoding}"], catch_exceptions=False + ) assert result.exit_code == 0 load_config.assert_called_once_with(path=Path(config_path)) _create_new_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding="utf-8" ) @@ -82,7 +85,9 @@ def test_generate_url(self, _create_new_client): result = runner.invoke(app, ["generate", f"--url={url}"]) assert result.exit_code == 0 - _create_new_client.assert_called_once_with(url=url, path=None, custom_template_path=None, meta=MetaType.POETRY) + _create_new_client.assert_called_once_with( + url=url, path=None, custom_template_path=None, meta=MetaType.POETRY, encoding=None + ) def test_generate_path(self, _create_new_client): path = "cool/path" @@ -92,7 +97,7 @@ def test_generate_path(self, _create_new_client): assert result.exit_code == 0 _create_new_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding=None ) def test_generate_meta(self, _create_new_client): @@ -103,7 +108,19 @@ def test_generate_meta(self, _create_new_client): assert result.exit_code == 0 _create_new_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.NONE + url=None, path=Path(path), custom_template_path=None, meta=MetaType.NONE, encoding=None + ) + + def test_generate_encoding(self, _create_new_client): + path = "cool/path" + encoding = "utf-8" + from openapi_python_client.cli import MetaType, app + + result = runner.invoke(app, ["generate", f"--path={path}", f"--encoding={encoding}"]) + + assert result.exit_code == 0 + _create_new_client.assert_called_once_with( + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding="utf-8" ) def test_generate_handle_errors(self, _create_new_client): From 1fd0ced144eaf085fd0a693af108c7f9f569cfba Mon Sep 17 00:00:00 2001 From: dongfangtianyu <7629022+dongfangtianyu@users.noreply.github.com> Date: Mon, 15 Feb 2021 08:17:11 +0800 Subject: [PATCH 2/6] fix: Modify the parameter name encoding to file_encoding, and set the default is UTF-8 --- openapi_python_client/__init__.py | 25 ++++++++++++++++--------- openapi_python_client/cli.py | 23 ++++++++++++++++++++--- tests/test___init__.py | 24 +++++++++++++----------- tests/test_cli.py | 22 ++++++++++++---------- 4 files changed, 61 insertions(+), 33 deletions(-) diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index 9ab7821a1..95936d03e 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -44,7 +44,7 @@ class Project: project_name_override: Optional[str] = None package_name_override: Optional[str] = None package_version_override: Optional[str] = None - encoding: Optional[str] = None + file_encoding: str def __init__( self, @@ -52,11 +52,11 @@ def __init__( openapi: GeneratorData, meta: MetaType, custom_template_path: Optional[Path] = None, - encoding: Optional[str] = None, + file_encoding: str = "utf-8", ) -> None: self.openapi: GeneratorData = openapi self.meta: MetaType = meta - self.encoding = encoding + self.encoding = file_encoding package_loader = PackageLoader(__package__) loader: BaseLoader @@ -263,7 +263,7 @@ def _get_project_for_url_or_path( path: Optional[Path], meta: MetaType, custom_template_path: Optional[Path] = None, - encoding: Optional[str] = None, + file_encoding: str = "utf-8", ) -> Union[Project, GeneratorError]: data_dict = _get_document(url=url, path=path) if isinstance(data_dict, GeneratorError): @@ -271,7 +271,7 @@ def _get_project_for_url_or_path( openapi = GeneratorData.from_dict(data_dict) if isinstance(openapi, GeneratorError): return openapi - return Project(openapi=openapi, custom_template_path=custom_template_path, meta=meta, encoding=encoding) + return Project(openapi=openapi, custom_template_path=custom_template_path, meta=meta, file_encoding=file_encoding) def create_new_client( @@ -280,7 +280,7 @@ def create_new_client( path: Optional[Path], meta: MetaType, custom_template_path: Optional[Path] = None, - encoding: Optional[str] = None, + file_encoding: str = "utf-8", ) -> Sequence[GeneratorError]: """ Generate the client library @@ -289,7 +289,7 @@ def create_new_client( A list containing any errors encountered when generating. """ project = _get_project_for_url_or_path( - url=url, path=path, custom_template_path=custom_template_path, meta=meta, encoding=encoding + url=url, path=path, custom_template_path=custom_template_path, meta=meta, file_encoding=file_encoding ) if isinstance(project, GeneratorError): return [project] @@ -297,7 +297,12 @@ def create_new_client( def update_existing_client( - *, url: Optional[str], path: Optional[Path], meta: MetaType, custom_template_path: Optional[Path] = None + *, + url: Optional[str], + path: Optional[Path], + meta: MetaType, + custom_template_path: Optional[Path] = None, + file_encoding: str = "utf-8", ) -> Sequence[GeneratorError]: """ Update an existing client library @@ -305,7 +310,9 @@ def update_existing_client( Returns: A list containing any errors encountered when generating. """ - project = _get_project_for_url_or_path(url=url, path=path, custom_template_path=custom_template_path, meta=meta) + project = _get_project_for_url_or_path( + url=url, path=path, custom_template_path=custom_template_path, meta=meta, file_encoding=file_encoding + ) if isinstance(project, GeneratorError): return [project] return project.update() diff --git a/openapi_python_client/cli.py b/openapi_python_client/cli.py index 131baae5c..1f94f37ea 100644 --- a/openapi_python_client/cli.py +++ b/openapi_python_client/cli.py @@ -1,3 +1,4 @@ +import codecs import pathlib from pprint import pformat from typing import Optional, Sequence @@ -116,7 +117,7 @@ def generate( url: Optional[str] = typer.Option(None, help="A URL to read the JSON from"), path: Optional[pathlib.Path] = typer.Option(None, help="A path to the JSON file"), custom_template_path: Optional[pathlib.Path] = typer.Option(None, **custom_template_path_options), # type: ignore - encoding: Optional[str] = typer.Option(None, help="Set file encoding for client files"), # type: ignore + file_encoding: str = typer.Option("utf-8", help="Encoding used when writing generated"), meta: MetaType = _meta_option, ) -> None: """ Generate a new OpenAPI Client library """ @@ -128,8 +129,15 @@ def generate( if url and path: typer.secho("Provide either --url or --path, not both", fg=typer.colors.RED) raise typer.Exit(code=1) + + try: + codecs.getencoder(file_encoding) + except LookupError: + typer.secho("Unknown encoding : {}".format(file_encoding), fg=typer.colors.RED) + raise typer.Exit(code=1) + errors = create_new_client( - url=url, path=path, meta=meta, custom_template_path=custom_template_path, encoding=encoding + url=url, path=path, meta=meta, custom_template_path=custom_template_path, file_encoding=file_encoding ) handle_errors(errors) @@ -140,6 +148,7 @@ def update( path: Optional[pathlib.Path] = typer.Option(None, help="A path to the JSON file"), custom_template_path: Optional[pathlib.Path] = typer.Option(None, **custom_template_path_options), # type: ignore meta: MetaType = _meta_option, + file_encoding: str = typer.Option("utf-8", help="Encoding used when writing generated"), ) -> None: """ Update an existing OpenAPI Client library """ from . import update_existing_client @@ -151,5 +160,13 @@ def update( typer.secho("Provide either --url or --path, not both", fg=typer.colors.RED) raise typer.Exit(code=1) - errors = update_existing_client(url=url, path=path, meta=meta, custom_template_path=custom_template_path) + try: + codecs.getencoder(file_encoding) + except LookupError: + typer.secho("Unknown encoding : {}".format(file_encoding), fg=typer.colors.RED) + raise typer.Exit(code=1) + + errors = update_existing_client( + url=url, path=path, meta=meta, custom_template_path=custom_template_path, file_encoding=file_encoding + ) handle_errors(errors) diff --git a/tests/test___init__.py b/tests/test___init__.py index 2a9377bea..3d2547d89 100644 --- a/tests/test___init__.py +++ b/tests/test___init__.py @@ -23,7 +23,9 @@ def test__get_project_for_url_or_path(mocker): _get_document.assert_called_once_with(url=url, path=path) from_dict.assert_called_once_with(data_dict) - _Project.assert_called_once_with(openapi=openapi, custom_template_path=None, meta=MetaType.POETRY, encoding=None) + _Project.assert_called_once_with( + openapi=openapi, custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" + ) assert project == _Project.return_value @@ -76,7 +78,7 @@ def test_create_new_client(mocker): result = create_new_client(url=url, path=path, meta=MetaType.POETRY) _get_project_for_url_or_path.assert_called_once_with( - url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, encoding=None + url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) project.build.assert_called_once() assert result == project.build.return_value @@ -95,7 +97,7 @@ def test_create_new_client_project_error(mocker): result = create_new_client(url=url, path=path, meta=MetaType.POETRY) _get_project_for_url_or_path.assert_called_once_with( - url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, encoding=None + url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) assert result == [error] @@ -113,7 +115,7 @@ def test_update_existing_client(mocker): result = update_existing_client(url=url, path=path, meta=MetaType.POETRY) _get_project_for_url_or_path.assert_called_once_with( - url=url, path=path, custom_template_path=None, meta=MetaType.POETRY + url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) project.update.assert_called_once() assert result == project.update.return_value @@ -132,7 +134,7 @@ def test_update_existing_client_project_error(mocker): result = update_existing_client(url=url, path=path, meta=MetaType.POETRY) _get_project_for_url_or_path.assert_called_once_with( - url=url, path=path, custom_template_path=None, meta=MetaType.POETRY + url=url, path=path, custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) assert result == [error] @@ -392,9 +394,9 @@ def test__build_metadata_poetry(self, mocker): project_name=project.project_name, package_name=project.package_name, ) - readme_path.write_text.assert_called_once_with(readme_template.render(), encoding=None) + readme_path.write_text.assert_called_once_with(readme_template.render(), encoding="utf-8") git_ignore_template.render.assert_called_once() - git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding=None) + git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding="utf-8") project._build_pyproject_toml.assert_called_once_with(use_poetry=True) def test__build_metadata_setup(self, mocker): @@ -429,9 +431,9 @@ def test__build_metadata_setup(self, mocker): project_name=project.project_name, package_name=project.package_name, ) - readme_path.write_text.assert_called_once_with(readme_template.render(), encoding=None) + readme_path.write_text.assert_called_once_with(readme_template.render(), encoding="utf-8") git_ignore_template.render.assert_called_once() - git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding=None) + git_ignore_path.write_text.assert_called_once_with(git_ignore_template.render(), encoding="utf-8") project._build_pyproject_toml.assert_called_once_with(use_poetry=False) project._build_setup_py.assert_called_once() @@ -475,7 +477,7 @@ def test__build_pyproject_toml(self, mocker, use_poetry): version=project.version, description=project.package_description, ) - pyproject_path.write_text.assert_called_once_with(pyproject_template.render(), encoding=None) + pyproject_path.write_text.assert_called_once_with(pyproject_template.render(), encoding="utf-8") def test__build_setup_py(self, mocker): from openapi_python_client import MetaType, Project @@ -505,7 +507,7 @@ def test__build_setup_py(self, mocker): version=project.version, description=project.package_description, ) - setup_path.write_text.assert_called_once_with(setup_template.render(), encoding=None) + setup_path.write_text.assert_called_once_with(setup_template.render(), encoding="utf-8") def test__reformat(mocker): diff --git a/tests/test_cli.py b/tests/test_cli.py index 85e43a27f..aadc5f734 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -31,16 +31,18 @@ def test_config_arg(mocker, _create_new_client): config_path = "config/path" path = "cool/path" - encoding = "utf-8" + file_encoding = "utf-8" result = runner.invoke( - app, [f"--config={config_path}", "generate", f"--path={path}", f"--encoding={encoding}"], catch_exceptions=False + app, + [f"--config={config_path}", "generate", f"--path={path}", f"--file-encoding={file_encoding}"], + catch_exceptions=False, ) assert result.exit_code == 0 load_config.assert_called_once_with(path=Path(config_path)) _create_new_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding="utf-8" + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) @@ -86,7 +88,7 @@ def test_generate_url(self, _create_new_client): assert result.exit_code == 0 _create_new_client.assert_called_once_with( - url=url, path=None, custom_template_path=None, meta=MetaType.POETRY, encoding=None + url=url, path=None, custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) def test_generate_path(self, _create_new_client): @@ -97,7 +99,7 @@ def test_generate_path(self, _create_new_client): assert result.exit_code == 0 _create_new_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding=None + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) def test_generate_meta(self, _create_new_client): @@ -108,7 +110,7 @@ def test_generate_meta(self, _create_new_client): assert result.exit_code == 0 _create_new_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.NONE, encoding=None + url=None, path=Path(path), custom_template_path=None, meta=MetaType.NONE, file_encoding="utf-8" ) def test_generate_encoding(self, _create_new_client): @@ -116,11 +118,11 @@ def test_generate_encoding(self, _create_new_client): encoding = "utf-8" from openapi_python_client.cli import MetaType, app - result = runner.invoke(app, ["generate", f"--path={path}", f"--encoding={encoding}"]) + result = runner.invoke(app, ["generate", f"--path={path}", f"--file-encoding={encoding}"]) assert result.exit_code == 0 _create_new_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, encoding="utf-8" + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) def test_generate_handle_errors(self, _create_new_client): @@ -192,7 +194,7 @@ def test_update_url(self, _update_existing_client): assert result.exit_code == 0 _update_existing_client.assert_called_once_with( - url=url, path=None, custom_template_path=None, meta=MetaType.POETRY + url=url, path=None, custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) def test_update_path(self, _update_existing_client): @@ -203,5 +205,5 @@ def test_update_path(self, _update_existing_client): assert result.exit_code == 0 _update_existing_client.assert_called_once_with( - url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) From e1dbdc5e79356e46c86b9a1facb11822be8133b8 Mon Sep 17 00:00:00 2001 From: dongfangtianyu <7629022+dongfangtianyu@users.noreply.github.com> Date: Mon, 15 Feb 2021 08:33:36 +0800 Subject: [PATCH 3/6] fix: test coverage (openapi_python_client/cli.py) --- tests/test_cli.py | 36 ++++++++++++++++++++++++++++++++++-- 1 file changed, 34 insertions(+), 2 deletions(-) diff --git a/tests/test_cli.py b/tests/test_cli.py index aadc5f734..d5bc2c69e 100644 --- a/tests/test_cli.py +++ b/tests/test_cli.py @@ -115,16 +115,26 @@ def test_generate_meta(self, _create_new_client): def test_generate_encoding(self, _create_new_client): path = "cool/path" - encoding = "utf-8" + file_encoding = "utf-8" from openapi_python_client.cli import MetaType, app - result = runner.invoke(app, ["generate", f"--path={path}", f"--file-encoding={encoding}"]) + result = runner.invoke(app, ["generate", f"--path={path}", f"--file-encoding={file_encoding}"]) assert result.exit_code == 0 _create_new_client.assert_called_once_with( url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) + def test_generate_encoding_errors(self, _create_new_client): + path = "cool/path" + file_encoding = "error-file-encoding" + from openapi_python_client.cli import MetaType, app + + result = runner.invoke(app, ["generate", f"--path={path}", f"--file-encoding={file_encoding}"]) + + assert result.exit_code == 1 + assert result.output == "Unknown encoding : {}\n".format(file_encoding) + def test_generate_handle_errors(self, _create_new_client): _create_new_client.return_value = [GeneratorError(detail="this is a message")] path = "cool/path" @@ -207,3 +217,25 @@ def test_update_path(self, _update_existing_client): _update_existing_client.assert_called_once_with( url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" ) + + def test_update_encoding(self, _update_existing_client): + path = "cool/path" + file_encoding = "utf-8" + from openapi_python_client.cli import MetaType, app + + result = runner.invoke(app, ["update", f"--path={path}", f"--file-encoding={file_encoding}"]) + + assert result.exit_code == 0 + _update_existing_client.assert_called_once_with( + url=None, path=Path(path), custom_template_path=None, meta=MetaType.POETRY, file_encoding="utf-8" + ) + + def test_update_encoding_errors(self, _update_existing_client): + path = "cool/path" + file_encoding = "error-file-encoding" + from openapi_python_client.cli import MetaType, app + + result = runner.invoke(app, ["update", f"--path={path}", f"--file-encoding={file_encoding}"]) + + assert result.exit_code == 1 + assert result.output == "Unknown encoding : {}\n".format(file_encoding) From c37268bb5aea88bb7501c5c28b50b259145b77ca Mon Sep 17 00:00:00 2001 From: dongfangtianyu <7629022+dongfangtianyu@users.noreply.github.com> Date: Tue, 16 Feb 2021 18:19:41 +0800 Subject: [PATCH 4/6] fix: Modify the parameter name encoding to file_encoding, --- openapi_python_client/__init__.py | 31 +++++++++++++++---------------- 1 file changed, 15 insertions(+), 16 deletions(-) diff --git a/openapi_python_client/__init__.py b/openapi_python_client/__init__.py index 95936d03e..b5ad8afeb 100644 --- a/openapi_python_client/__init__.py +++ b/openapi_python_client/__init__.py @@ -44,7 +44,6 @@ class Project: project_name_override: Optional[str] = None package_name_override: Optional[str] = None package_version_override: Optional[str] = None - file_encoding: str def __init__( self, @@ -56,7 +55,7 @@ def __init__( ) -> None: self.openapi: GeneratorData = openapi self.meta: MetaType = meta - self.encoding = file_encoding + self.file_encoding = file_encoding package_loader = PackageLoader(__package__) loader: BaseLoader @@ -147,16 +146,16 @@ def _create_package(self) -> None: package_init_template = self.env.get_template("package_init.py.jinja") package_init.write_text( - package_init_template.render(description=self.package_description), encoding=self.encoding + package_init_template.render(description=self.package_description), encoding=self.file_encoding ) if self.meta != MetaType.NONE: pytyped = self.package_dir / "py.typed" - pytyped.write_text("# Marker file for PEP 561", encoding=self.encoding) + pytyped.write_text("# Marker file for PEP 561", encoding=self.file_encoding) types_template = self.env.get_template("types.py.jinja") types_path = self.package_dir / "types.py" - types_path.write_text(types_template.render(), encoding=self.encoding) + types_path.write_text(types_template.render(), encoding=self.file_encoding) def _build_metadata(self) -> None: if self.meta == MetaType.NONE: @@ -173,13 +172,13 @@ def _build_metadata(self) -> None: readme_template.render( project_name=self.project_name, description=self.package_description, package_name=self.package_name ), - encoding=self.encoding, + encoding=self.file_encoding, ) # .gitignore git_ignore_path = self.project_dir / ".gitignore" git_ignore_template = self.env.get_template(".gitignore.jinja") - git_ignore_path.write_text(git_ignore_template.render(), encoding=self.encoding) + git_ignore_path.write_text(git_ignore_template.render(), encoding=self.file_encoding) def _build_pyproject_toml(self, *, use_poetry: bool) -> None: template = "pyproject.toml.jinja" if use_poetry else "pyproject_no_poetry.toml.jinja" @@ -192,7 +191,7 @@ def _build_pyproject_toml(self, *, use_poetry: bool) -> None: version=self.version, description=self.package_description, ), - encoding=self.encoding, + encoding=self.file_encoding, ) def _build_setup_py(self) -> None: @@ -205,7 +204,7 @@ def _build_setup_py(self) -> None: version=self.version, description=self.package_description, ), - encoding=self.encoding, + encoding=self.file_encoding, ) def _build_models(self) -> None: @@ -218,7 +217,7 @@ def _build_models(self) -> None: model_template = self.env.get_template("model.py.jinja") for model in self.openapi.models.values(): module_path = models_dir / f"{model.reference.module_name}.py" - module_path.write_text(model_template.render(model=model), encoding=self.encoding) + module_path.write_text(model_template.render(model=model), encoding=self.file_encoding) imports.append(import_string_from_reference(model.reference)) # Generate enums @@ -227,25 +226,25 @@ def _build_models(self) -> None: for enum in self.openapi.enums.values(): module_path = models_dir / f"{enum.reference.module_name}.py" if enum.value_type is int: - module_path.write_text(int_enum_template.render(enum=enum), encoding=self.encoding) + module_path.write_text(int_enum_template.render(enum=enum), encoding=self.file_encoding) else: - module_path.write_text(str_enum_template.render(enum=enum), encoding=self.encoding) + module_path.write_text(str_enum_template.render(enum=enum), encoding=self.file_encoding) imports.append(import_string_from_reference(enum.reference)) models_init_template = self.env.get_template("models_init.py.jinja") - models_init.write_text(models_init_template.render(imports=imports), encoding=self.encoding) + models_init.write_text(models_init_template.render(imports=imports), encoding=self.file_encoding) def _build_api(self) -> None: # Generate Client client_path = self.package_dir / "client.py" client_template = self.env.get_template("client.py.jinja") - client_path.write_text(client_template.render(), encoding=self.encoding) + client_path.write_text(client_template.render(), encoding=self.file_encoding) # Generate endpoints api_dir = self.package_dir / "api" api_dir.mkdir() api_init = api_dir / "__init__.py" - api_init.write_text('""" Contains methods for accessing the API """', encoding=self.encoding) + api_init.write_text('""" Contains methods for accessing the API """', encoding=self.file_encoding) endpoint_template = self.env.get_template("endpoint_module.py.jinja") for tag, collection in self.openapi.endpoint_collections_by_tag.items(): @@ -255,7 +254,7 @@ def _build_api(self) -> None: for endpoint in collection.endpoints: module_path = tag_dir / f"{snake_case(endpoint.name)}.py" - module_path.write_text(endpoint_template.render(endpoint=endpoint), encoding=self.encoding) + module_path.write_text(endpoint_template.render(endpoint=endpoint), encoding=self.file_encoding) def _get_project_for_url_or_path( From 41af1f9feece4caa8aa082ce3dbca09d4978aa34 Mon Sep 17 00:00:00 2001 From: dongfangtianyu <7629022+dongfangtianyu@users.noreply.github.com> Date: Tue, 16 Feb 2021 18:29:49 +0800 Subject: [PATCH 5/6] docs: Add CHANGELOG entry for #330 --- CHANGELOG.md | 1 + 1 file changed, 1 insertion(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 3924cb1b1..4ea0eaf1f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,6 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixes `Enum` deserialization when the value is `UNSET`. - Add handling of application/vnd.api+json media type. - Support passing models into query parameters (#316). Thanks @forest-benchling! +- New `--file-encoding`command line option, set encoding used when writing generated, default: utf-8 (#330). ### Changes From eebcc2ba15784252c70f37ff24670c0a10c33367 Mon Sep 17 00:00:00 2001 From: Ethan Mann Date: Tue, 16 Feb 2021 14:54:05 -0500 Subject: [PATCH 6/6] Update CHANGELOG.md --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 4ea0eaf1f..462ba252c 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -22,7 +22,7 @@ and this project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0 - Fixes `Enum` deserialization when the value is `UNSET`. - Add handling of application/vnd.api+json media type. - Support passing models into query parameters (#316). Thanks @forest-benchling! -- New `--file-encoding`command line option, set encoding used when writing generated, default: utf-8 (#330). +- New `--file-encoding` command line option (#330). Sets the encoding used when writing generated files (defaults to utf-8). Thanks @dongfangtianyu! ### Changes