8000 Config is now converted to a pydantic schema. Got rid of icky globals… · emann/openapi-python-client@a8c90b6 · GitHub
[go: up one dir, main page]

Skip to content

Commit a8c90b6

Browse files
committed
Config is now converted to a pydantic schema. Got rid of icky globals for config options
1 parent 5b6af6f commit a8c90b6

File tree

7 files changed

+88
-57
lines changed

7 files changed

+88
-57
lines changed

mypy.ini

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,9 @@ disallow_untyped_defs = True
44
warn_redundant_casts = True
55
strict_equality = True
66

7+
[mypy-importlib_metadata]
8+
ignore_missing_imports = True
9+
710
[mypy-stringcase]
811
ignore_missing_imports = True
912

openapi_python_client/__init__.py

Lines changed: 6 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@
99

1010
import httpcore
1111
import httpx
12-
import yaml
1312
from jinja2 import Environment, PackageLoader
1413

1514
from openapi_python_client import utils
@@ -18,9 +17,9 @@
1817
from .parser.errors import GeneratorError
1918

2019
if sys.version_info.minor == 7: # version did not exist in 3.7, need to use a backport
21-
from importlib_metadata import version # type: ignore
20+
from importlib_metadata import version
2221
else:
23-
from importlib.metadata import version # type: ignore
22+
from importlib.metadata import version
2423

2524

2625
__version__ = version(__package__)
@@ -39,21 +38,6 @@ def _get_project_for_url_or_path(url: Optional[str], path: Optional[Path]) -> Un
3938
return _Project(openapi=openapi)
4039

4140

42-
def load_config(*, path: Path) -> None:
43-
""" Loads config from provided Path """
44-
config_data = yaml.safe_load(path.read_text())
45-
46-
if "class_overrides" in config_data:
47-
from .parser import reference
48-
49-
for class_name, class_data in config_data["class_overrides"].items():
50-
reference.class_overrides[class_name] = reference.Reference(**class_data)
51-
52-
global project_name_override, package_name_override
53-
project_name_override = config_data.get("client_project_name_override")
54-
package_name_override = config_data.get("client_package_name_override")
55-
56-
5741
def create_new_client(*, url: Optional[str], path: Optional[Path]) -> Sequence[GeneratorError]:
5842
"""
5943
Generate the client library
@@ -102,15 +86,17 @@ def _get_document(*, url: Optional[str], path: Optional[Path]) -> Union[Dict[str
10286

10387
class _Project:
10488
TEMPLATE_FILTERS = {"snakecase": utils.snake_case}
89+
project_name_override: Optional[str] = None
90+
package_name_override: Optional[str] = None
10591

10692
def __init__(self, *, openapi: GeneratorData) -> None:
10793
self.openapi: GeneratorData = openapi
10894
self.env: Environment = Environment(loader=PackageLoader(__package__), trim_blocks=True, lstrip_blocks=True)
10995

110-
self.project_name: str = project_name_override or f"{openapi.title.replace(' ', '-').lower()}-client"
96+
self.project_name: str = self.project_name_override or f"{openapi.title.replace(' ', '-').lower()}-client"
11197
self.project_dir: Path = Path.cwd() / self.project_name
11298

113-
self.package_name: str = package_name_override or self.project_name.replace("-", "_")
99+
self.package_name: str = self.package_name_override or self.project_name.replace("-", "_")
114100
self.package_dir: Path = self.project_dir / self.package_name
115101
self.package_description = f"A client library for accessing {self.openapi.title}"
116102

openapi_python_client/cli.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,13 +18,13 @@ def _version_callback(value: bool) -> None:
1818

1919

2020
def _process_config(path: Optional[pathlib.Path]) -> None:
21-
from openapi_python_client import load_config
21+
from .config import Config
2222

2323
if not path:
2424
return
2525

2626
try:
27-
load_config(path=path)
27+
Config.load_from_path(path=path)
2828
except: # noqa
2929
raise typer.BadParameter("Unable to parse config")
3030

openapi_python_client/config.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
from pathlib import Path
2+
from typing import Dict, Optional
3+
4+
import yaml
5+
from pydantic import BaseModel
6+
7+
8+
class ClassOverride(BaseModel):
9+
class_name: str
10+
module_name: str
11+
12+
13+
class Config(BaseModel):
14+
class_overrides: Optional[Dict[str, ClassOverride]]
15+
project_name_override: Optional[str]
16+
package_name_override: Optional[str]
17+
18+
def load_config(self) -> None:
19+
""" Loads config from provided Path """
20+
21+
if self.class_overrides is not None:
22+
from .parser import reference
23+
24+
for class_name, class_data in self.class_overrides.items():
25+
reference.class_overrides[class_name] = reference.Reference(**dict(class_data))
26+
27+
from openapi_python_client import _Project
28+
29+
_Project.project_name_override = self.project_name_override
30+
_Project.package_name_override = self.package_name_override
31+
32+
@staticmethod
33+
def load_from_path(path: Path) -> None:
34+
config_data = yaml.safe_load(path.read_text())
35+
Config(**config_data).load_config()

tests/test___init__.py

Lines changed: 2 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -231,16 +231,15 @@ def test___init__(self, mocker):
231231
def test_project_and_package_name_overrides(self, mocker):
232232
openapi = mocker.MagicMock(title="My Test API")
233233

234-
import openapi_python_client as opc
235234
from openapi_python_client import _Project
236235

237-
opc.project_name_override = "my-special-project-name"
236+
_Project.project_name_override = "my-special-project-name"
238237
project = _Project(openapi=openapi)
239238

240239
assert project.project_name == "my-special-project-name"
241240
assert project.package_name == "my_special_project_name"
242241

243-
opc.package_name_override = "my_special_package_name"
242+
_Project.package_name_override = "my_special_package_name"
244243
project = _Project(openapi=openapi)
245244

246245
assert project.project_name == "my-special-project-name"
@@ -609,32 +608,3 @@ def test__get_errors(mocker):
609608
project = _Project(openapi=openapi)
610609

611610
assert project._get_errors() == [1, 2, 3]
612-
613-
614-
def test_load_config(mocker):
615-
my_data = {
616-
"class_overrides": {"_MyCLASSName": {"class_name": "MyClassName", "module_name": "my_module_name"}},
617-
"client_project_name_override": "special-project-name",
618-
"client_package_name_override": "special_package_name",
619-
}
620-
safe_load = mocker.patch("yaml.safe_load", return_value=my_data)
621-
fake_path = mocker.MagicMock(autospec=pathlib.Path)
622-
623-
import openapi_python_client as opc
624-
from openapi_python_client.parser import reference
625-
626-
reference.class_overrides = {}
627-
opc.project_name_override = None
628-
opc.package_name_override = None
629-
630-
opc.load_config(path=fake_path)
631-
632-
fake_path.read_text.assert_called_once()
633-
safe_load.assert_called_once_with(fake_path.read_text())
634-
from openapi_python_client.parser import reference
635-
636-
assert reference.class_overrides == {
637-
"_MyCLASSName": reference.Reference(class_name="MyClassName", module_name="my_module_name")
638-
}
639-
assert opc.project_name_override == "special-project-name"
640-
assert opc.package_name_override == "special_package_name"

tests/test_cli.py

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -25,8 +25,8 @@ def _create_new_client(mocker) -> MagicMock:
2525
return mocker.patch("openapi_python_client.create_new_client", return_value=[])
2626

2727

28-
def test_config(mocker, _create_new_client):
29-
load_config = mocker.patch("openapi_python_client.load_config")
28+
def test_config_arg(mocker, _create_new_client):
29+
load_config = mocker.patch("openapi_python_client.config.Config.load_from_path")
3030
from openapi_python_client.cli import app
3131

3232
config_path = "config/path"
@@ -40,7 +40,9 @@ def test_config(mocker, _create_new_client):
4040

4141

4242
def test_bad_config(mocker, _create_new_client):
43-
load_config = mocker.patch("openapi_python_client.load_config", side_effect=ValueError("Bad Config"))
43+
load_config = mocker.patch(
44+
"openapi_python_client.config.Config.load_from_path", side_effect=ValueError("Bad Config")
45+
)
4446
from openapi_python_client.cli import app
4547

4648
config_path = "config/path"

tests/test_config.py

Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
import pathlib
2+
3+
from openapi_python_client.config import Config
4+
5+
6+
def test_load_from_path(mocker):
7+
safe_load = mocker.patch("yaml.safe_load", return_value={})
8+
fake_path = mocker.MagicMock(autospec=pathlib.Path)
9+
load_config = mocker.patch("openapi_python_client.config.Config.load_config")
10+
11+
Config.load_from_path(fake_path)
12+
safe_load.assert_called()
13+
load_config.assert_called()
14+
15+
16+
class TestLoadConfig:
17+
def test_class_overrides(self):
18+
from openapi_python_client.parser import reference
19+
20+
override1 = {"class_name": "ExampleClass", "module_name": "example_module"}
21+
override2 = {"class_name": "DifferentClass", "module_name": "different_module"}
22+
config = Config(class_overrides={"Class1": override1, "Class2": override2})
23+
config.load_config()
24+
25+
assert reference.class_overrides["Class1"] == reference.Reference(**override1)
26+
assert reference.class_overrides["Class2"] == reference.Reference(**override2)
27+
28+
def test_project_and_package_name_overrides(self):
29+
config = Config(project_name_override="project-name", package_name_override="package_name")
30+
config.load_config()
31+
32+
from openapi_python_client import _Project
33+
34+
assert _Project.project_name_override == "project-name"
35+
assert _Project.package_name_override == "package_name"

0 commit comments

Comments
 (0)
0