Skip to content

Commit 489bc79

Browse files
committed
- Added the autoformat option to the CLI
- Added black as a possible auto formatter - Added options to the main tests - Added autoformat as doc to the latest release
1 parent 9e58209 commit 489bc79

7 files changed

Lines changed: 87 additions & 17 deletions

File tree

docs/references/index.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,5 +16,6 @@ Arguments:
1616
Options:
1717
```console
1818
--library The library to use. Defaults to `httpx`.
19+
--autoformat Specifies which auto formattool to apply to the generated code. Defaults to `black`.
1920
-h, --help Show this help message and exit.
2021
```

pyproject.toml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,10 +24,10 @@ openapi-schema-pydantic = "^1.2.3"
2424
Jinja2 = "^3.1.2"
2525
autopep8 = "^1.6.0"
2626
click = "^8.1.3"
27+
black = ">=21.10b0"
2728

2829
[tool.poetry.dev-dependencies]
2930
Pygments = ">=2.10.0"
30-
black = ">=21.10b0"
3131
coverage = {extras = ["toml"], version = "^6.4.1"}
3232
darglint = ">=1.8.1"
3333
flake8 = ">=3.0.1"

src/openapi_python_generator/__main__.py

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
import click
44

55
from openapi_python_generator import __version__
6-
from openapi_python_generator.common import HTTPLibrary
6+
from openapi_python_generator.common import HTTPLibrary, AutoFormat
77
from openapi_python_generator.generate_data import generate_data
88

99

@@ -14,19 +14,28 @@
1414
"--library",
1515
default=HTTPLibrary.httpx,
1616
type=HTTPLibrary,
17-
help="HTTP library to use in the generation of the client. Currently only httpx is supported.",
17+
help="HTTP library to use in the generation of the client.",
18+
)
19+
@click.option(
20+
"--autoformat",
21+
default=AutoFormat.black,
22+
type=AutoFormat,
23+
help="Option to choose which auto formatter is applied.",
1824
)
1925
@click.version_option(version=__version__)
2026
def main(
21-
source: str, output: str, library: Optional[HTTPLibrary] = HTTPLibrary.httpx
27+
source: str,
28+
output: str,
29+
library: Optional[HTTPLibrary] = HTTPLibrary.httpx,
30+
autoformat: Optional[AutoFormat] = AutoFormat.black,
2231
) -> None:
2332
"""
2433
Generate Python code from an OpenAPI 3.0 specification.
2534
2635
Provide a SOURCE (file or URL) containing the OpenAPI 3 specification and
2736
an OUTPUT path, where the resulting client is created.
2837
"""
29-
generate_data(source, output, library)
38+
generate_data(source, output, library, autoformat)
3039

3140

3241
if __name__ == "__main__": # pragma: no cover

src/openapi_python_generator/common.py

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,16 @@ class HTTPLibrary(str, Enum):
1414
aiohttp = "aiohttp"
1515

1616

17+
class AutoFormat(str, Enum):
18+
"""
19+
Enum for the available autoformat options
20+
"""
21+
22+
autopep8 = "autopep8"
23+
black = "black"
24+
none = "none"
25+
26+
1727
library_config_dict: Dict[Optional[HTTPLibrary], LibraryConfig] = {
1828
HTTPLibrary.httpx: LibraryConfig(
1929
name="httpx",

src/openapi_python_generator/generate_data.py

Lines changed: 30 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
from pathlib import Path
22
from typing import Optional, Union
33

4+
import black
45
import click
56
import httpx
67
from httpx import ConnectError, ConnectTimeout
@@ -9,20 +10,32 @@
910
import autopep8
1011

1112
from openapi_schema_pydantic import OpenAPI
12-
from .common import HTTPLibrary, library_config_dict
13+
from .common import HTTPLibrary, library_config_dict, AutoFormat
1314
from .language_converters.python.generator import generator
1415
from .language_converters.python.jinja_config import JINJA_ENV, SERVICE_TEMPLATE
1516
from .models import ConversionResult
1617

1718

18-
def write_code(path: Path, content):
19+
def write_code(
20+
path: Path, content, autoformat: Optional[AutoFormat] = AutoFormat.black
21+
) -> None:
1922
"""
2023
Write the content to the file at the given path.
24+
:param autoformat: The autoformat applied to the code written.
2125
:param path: The path to the file.
2226
:param content: The content to write.
2327
"""
2428
with open(path, "w") as f:
25-
f.write(autopep8.fix_code(content))
29+
if autoformat == AutoFormat.black:
30+
f.write(
31+
black.format_file_contents(
32+
content, fast=False, mode=black.FileMode(line_length=120)
33+
)
34+
)
35+
elif autoformat == AutoFormat.autopep8:
36+
f.write(autopep8.fix_code(content, options={"max_line_length": 120}))
37+
else:
38+
f.write(content)
2639

2740

2841
def get_open_api(source: Union[str, Path]) -> OpenAPI:
@@ -54,11 +67,16 @@ def get_open_api(source: Union[str, Path]) -> OpenAPI:
5467
raise
5568

5669

57-
def write_data(data: ConversionResult, output: Union[str, Path]):
70+
def write_data(
71+
data: ConversionResult,
72+
output: Union[str, Path],
73+
autoformat: Optional[AutoFormat] = AutoFormat.black,
74+
) -> None:
5875
"""
5976
This function will firstly create the folderstrucutre of output, if it doesn't exist. Then it will create the
6077
models from data.models into the models sub module of the output folder. After this, the services will be created
6178
into the services sub module of the output folder.
79+
:param autoformat: The autoformat applied to the code written.
6280
:param data: The data to write.
6381
:param output: The path to the output folder.
6482
"""
@@ -79,12 +97,13 @@ def write_data(data: ConversionResult, output: Union[str, Path]):
7997
# Write the models.
8098
for model in data.models:
8199
files.append(model.file_name)
82-
write_code(models_path / f"{model.file_name}.py", model.content)
100+
write_code(models_path / f"{model.file_name}.py", model.content, autoformat)
83101

84102
# Create models.__init__.py file containing imports to all models.
85103
write_code(
86104
models_path / "__init__.py",
87105
"\n".join([f"from .{file} import *" for file in files]),
106+
autoformat,
88107
)
89108

90109
files = []
@@ -97,33 +116,37 @@ def write_data(data: ConversionResult, output: Union[str, Path]):
97116
write_code(
98117
services_path / f"{service.file_name}.py",
99118
JINJA_ENV.get_template(SERVICE_TEMPLATE).render(**service.dict()),
119+
autoformat,
100120
)
101121

102122
# Create services.__init__.py file containing imports to all services.
103123
write_code(
104124
services_path / "__init__.py",
105125
"\n".join([f"from .{file} import *" for file in files]),
126+
autoformat,
106127
)
107128

108129
# Write the api_config.py file.
109-
write_code(Path(output) / "api_config.py", data.api_config.content)
130+
write_code(Path(output) / "api_config.py", data.api_config.content, autoformat)
110131

111132
# Write the __init__.py file.
112133
write_code(
113134
Path(output) / "__init__.py",
114135
"from .models import *\nfrom .services import *\nfrom .api_config import *",
136+
autoformat,
115137
)
116138

117139

118140
def generate_data(
119141
source: Union[str, Path],
120142
output: Union[str, Path],
121143
library: Optional[HTTPLibrary] = HTTPLibrary.httpx,
144+
autoformat: Optional[AutoFormat] = AutoFormat.black,
122145
) -> None:
123146
"""
124147
Generate Python code from an OpenAPI 3.0 specification.
125148
"""
126149
data = get_open_api(source)
127150
click.echo(f"Generating data from {source}")
128151
result = generator(data, library_config_dict[library])
129-
write_data(result, output)
152+
write_data(result, output, autoformat)

tests/test_generate_data.py

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
import pytest
22
from httpx import ConnectError
33

4-
from openapi_python_generator.common import library_config_dict, HTTPLibrary
4+
from openapi_python_generator.common import library_config_dict, HTTPLibrary, AutoFormat
55
from openapi_python_generator.generate_data import (
66
get_open_api,
77
write_data,
@@ -43,9 +43,12 @@ def test_generate_data(model_data_with_cleanup):
4343
assert (test_result_path / "__init__.py").is_file()
4444

4545

46-
def test_write_data(model_data_with_cleanup):
46+
@pytest.mark.parametrize(
47+
"autoformat", [AutoFormat.black, AutoFormat.autopep8, AutoFormat.none]
48+
)
49+
def test_write_data(model_data_with_cleanup, autoformat):
4750
result = generator(model_data_with_cleanup, library_config_dict[HTTPLibrary.httpx])
48-
write_data(result, test_result_path)
51+
write_data(result, test_result_path, autoformat)
4952

5053
assert test_result_path.exists()
5154
assert test_result_path.is_dir()

tests/test_main.py

Lines changed: 26 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,6 +3,7 @@
33
from click.testing import CliRunner
44

55
from openapi_python_generator.__main__ import main
6+
from openapi_python_generator.common import HTTPLibrary, AutoFormat
67
from tests.conftest import test_data_path, test_result_path
78

89

@@ -12,7 +13,30 @@ def runner() -> CliRunner:
1213
return CliRunner()
1314

1415

15-
def test_main_succeeds(runner: CliRunner, model_data_with_cleanup) -> None:
16+
@pytest.mark.parametrize(
17+
"library,autoformat",
18+
[
19+
(HTTPLibrary.httpx, AutoFormat.black),
20+
(HTTPLibrary.httpx, AutoFormat.autopep8),
21+
(HTTPLibrary.httpx, AutoFormat.none),
22+
(HTTPLibrary.requests, AutoFormat.black),
23+
(HTTPLibrary.requests, AutoFormat.autopep8),
24+
(HTTPLibrary.requests, AutoFormat.none),
25+
],
26+
)
27+
def test_main_succeeds(
28+
runner: CliRunner, model_data_with_cleanup, library, autoformat
29+
) -> None:
1630
"""It exits with a status code of zero."""
17-
result = runner.invoke(main, [str(test_data_path), str(test_result_path)])
31+
result = runner.invoke(
32+
main,
33+
[
34+
str(test_data_path),
35+
str(test_result_path),
36+
"--library",
37+
library.value,
38+
"--autoformat",
39+
autoformat.value,
40+
],
41+
)
1842
assert result.exit_code == 0

0 commit comments

Comments
 (0)