pydantic-openapi-generator 2.3.0__tar.gz → 2.5.0__tar.gz

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.
Files changed (41) hide show
  1. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/PKG-INFO +2 -1
  2. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/pyproject.toml +2 -1
  3. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/__main__.py +8 -0
  4. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/__init__.py +5 -0
  5. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/base_parameter.py +73 -0
  6. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/class_var_parameter.py +60 -0
  7. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/function_parameter.py +47 -0
  8. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/generator_config.py +33 -0
  9. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/kwarg_parameter.py +56 -0
  10. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/loader.py +17 -0
  11. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/parameter_source.py +7 -0
  12. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/parameter_union.py +16 -0
  13. pydantic_openapi_generator-2.5.0/src/pydantic_openapi_generator/config/utils.py +56 -0
  14. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/generate_data.py +7 -0
  15. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/client_generator.py +266 -9
  16. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/generator.py +5 -1
  17. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/async_client_httpx_pydantic_2.jinja2 +86 -25
  18. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/sync_client_httpx_pydantic_2.jinja2 +86 -25
  19. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/models.py +32 -3
  20. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/parsers/openapi_30.py +5 -0
  21. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/parsers/openapi_31.py +5 -0
  22. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/.gitignore +0 -0
  23. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/LICENSE +0 -0
  24. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/README.md +0 -0
  25. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/__init__.py +0 -0
  26. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/common.py +0 -0
  27. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/__init__.py +0 -0
  28. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/__init__.py +0 -0
  29. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/common.py +0 -0
  30. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/exception_generator.py +0 -0
  31. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/jinja_config.py +0 -0
  32. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/model_generator.py +0 -0
  33. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/alias_union.jinja2 +0 -0
  34. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/discriminator_enum.jinja2 +0 -0
  35. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/enum.jinja2 +0 -0
  36. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/http_exception.jinja2 +0 -0
  37. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/models.jinja2 +0 -0
  38. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/language_converters/python/templates/models_pydantic_2.jinja2 +0 -0
  39. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/parsers/__init__.py +0 -0
  40. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/py.typed +0 -0
  41. {pydantic_openapi_generator-2.3.0 → pydantic_openapi_generator-2.5.0}/src/pydantic_openapi_generator/version_detector.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: pydantic-openapi-generator
3
- Version: 2.3.0
3
+ Version: 2.5.0
4
4
  Summary: Openapi Python Generator
5
5
  Project-URL: Homepage, https://github.com/mattcoulter7/pydantic-openapi-generator
6
6
  Project-URL: Repository, https://github.com/mattcoulter7/pydantic-openapi-generator
@@ -20,6 +20,7 @@ Requires-Dist: isort>=5.10.1
20
20
  Requires-Dist: jinja2<4,>=3.1.2
21
21
  Requires-Dist: openapi-pydantic<0.6,>=0.5.1
22
22
  Requires-Dist: orjson<4,>=3.9.15
23
+ Requires-Dist: pydantic-di>=0.3.1
23
24
  Requires-Dist: pydantic<3,>=2.10.2
24
25
  Requires-Dist: pyyaml<7,>=6.0.2
25
26
  Description-Content-Type: text/markdown
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "pydantic-openapi-generator"
3
- version = "2.3.0"
3
+ version = "2.5.0"
4
4
  description = "Openapi Python Generator"
5
5
  authors = [
6
6
  { name = "Marco Müllner", email = "muellnermarco@gmail.com" },
@@ -27,6 +27,7 @@ dependencies = [
27
27
  "openapi-pydantic>=0.5.1,<0.6",
28
28
  "pyyaml>=6.0.2,<7",
29
29
  "importlib-metadata>=8.7.0,<9",
30
+ "pydantic-di>=0.3.1",
30
31
  ]
31
32
 
32
33
  [project.urls]
@@ -52,6 +52,12 @@ from pydantic_openapi_generator.generate_data import generate_data
52
52
  show_default=True,
53
53
  help="Option to choose which auto formatter is applied.",
54
54
  )
55
+ @click.option(
56
+ "--config-path",
57
+ type=click.Path(exists=True, dir_okay=False),
58
+ default=None,
59
+ help="Optional YAML configuration for generated client parameters.",
60
+ )
55
61
  @click.version_option(version=__version__)
56
62
  def main(
57
63
  source: str,
@@ -62,6 +68,7 @@ def main(
62
68
  custom_template_path: Optional[str] = None,
63
69
  pydantic_version: PydanticVersion = PydanticVersion.V2,
64
70
  formatter: Formatter = Formatter.BLACK,
71
+ config_path: Optional[str] = None,
65
72
  ) -> None:
66
73
  """
67
74
  Generate Python code from an OpenAPI 3.0+ specification.
@@ -78,6 +85,7 @@ def main(
78
85
  custom_template_path,
79
86
  pydantic_version,
80
87
  formatter,
88
+ config_path,
81
89
  )
82
90
 
83
91
 
@@ -0,0 +1,5 @@
1
+ from pydantic_openapi_generator.config.parameter_source import ParameterSource
2
+
3
+ __all__ = [
4
+ "ParameterSource",
5
+ ]
@@ -0,0 +1,73 @@
1
+ from abc import ABC, abstractmethod
2
+ from typing import Optional
3
+
4
+ from pydantic import BaseModel, ConfigDict
5
+
6
+ from pydantic_openapi_generator.config.utils import Parameter, parameter_base_type_hint
7
+ from pydantic_openapi_generator.language_converters.python import common
8
+ from pydantic_openapi_generator.models import GeneratedParameter
9
+
10
+
11
+ class BaseArgumentConfiguration(BaseModel, ABC):
12
+ model_config = ConfigDict(extra="forbid")
13
+
14
+ name: str
15
+ code_name: Optional[str] = None
16
+
17
+ def resolve_parameter(self, param: Parameter) -> GeneratedParameter:
18
+ code_name = self.resolved_code_name(param)
19
+ type_hint, default = self.method_type_and_default(param)
20
+
21
+ return GeneratedParameter(
22
+ wire_name=param.name,
23
+ code_name=code_name,
24
+ location=param.param_in, # type: ignore[arg-type]
25
+ type_hint=type_hint,
26
+ base_type_hint=parameter_base_type_hint(param),
27
+ required=param.required,
28
+ default=default,
29
+ source=self.type, # type: ignore[attr-defined]
30
+ is_secret=self.is_secret_parameter(),
31
+ field_type_hint=self.field_type_hint(param),
32
+ field_default=self.field_default(param),
33
+ getter_name=self.getter_name(code_name),
34
+ local_name=self.local_name(code_name),
35
+ value_expression=self.value_expression(code_name),
36
+ )
37
+
38
+ def resolved_code_name(self, param: Parameter) -> str:
39
+ if self.code_name:
40
+ return common.normalize_symbol(self.code_name)
41
+ return self.default_code_name(param.name)
42
+
43
+ @abstractmethod
44
+ def default_code_name(self, param_name: str) -> str:
45
+ raise NotImplementedError
46
+
47
+ @abstractmethod
48
+ def method_type_and_default(self, param: Parameter) -> tuple[str, Optional[str]]:
49
+ raise NotImplementedError
50
+
51
+ @abstractmethod
52
+ def field_type_hint(self, param: Parameter) -> Optional[str]:
53
+ raise NotImplementedError
54
+
55
+ @abstractmethod
56
+ def field_default(self, param: Parameter) -> Optional[str]:
57
+ raise NotImplementedError
58
+
59
+ @abstractmethod
60
+ def getter_name(self, code_name: str) -> Optional[str]:
61
+ raise NotImplementedError
62
+
63
+ @abstractmethod
64
+ def local_name(self, code_name: str) -> Optional[str]:
65
+ raise NotImplementedError
66
+
67
+ @abstractmethod
68
+ def value_expression(self, code_name: str) -> str:
69
+ raise NotImplementedError
70
+
71
+ @abstractmethod
72
+ def is_secret_parameter(self) -> bool:
73
+ raise NotImplementedError
@@ -0,0 +1,60 @@
1
+ from typing import Literal, Optional, override
2
+
3
+ from pydantic_openapi_generator.config.base_parameter import (
4
+ BaseArgumentConfiguration,
5
+ )
6
+ from pydantic_openapi_generator.config.parameter_source import ParameterSource
7
+ from pydantic_openapi_generator.config.utils import (
8
+ Parameter,
9
+ lower_code_name,
10
+ optional_override_type_and_default,
11
+ optional_type,
12
+ parameter_base_type_hint,
13
+ parameter_default,
14
+ )
15
+
16
+
17
+ class ClassVarArgumentConfiguration(BaseArgumentConfiguration):
18
+ type: Literal[ParameterSource.CLASS_VAR] = ParameterSource.CLASS_VAR
19
+ is_secret: bool = False
20
+
21
+ @override
22
+ def default_code_name(self, param_name: str) -> str:
23
+ return lower_code_name(param_name)
24
+
25
+ @override
26
+ def method_type_and_default(self, param: Parameter) -> tuple[str, Optional[str]]:
27
+ return optional_override_type_and_default(param)
28
+
29
+ @override
30
+ def field_type_hint(self, param: Parameter) -> str:
31
+ default = parameter_default(param)
32
+ base_type = "SecretStr" if self.is_secret else parameter_base_type_hint(param)
33
+
34
+ if param.required or default is not None:
35
+ return base_type
36
+
37
+ return optional_type(base_type)
38
+
39
+ @override
40
+ def field_default(self, param: Parameter) -> Optional[str]:
41
+ default = parameter_default(param)
42
+ if param.required:
43
+ return None
44
+ return default if default is not None else "None"
45
+
46
+ @override
47
+ def getter_name(self, code_name: str) -> Optional[str]:
48
+ return None
49
+
50
+ @override
51
+ def local_name(self, code_name: str) -> str:
52
+ return f"_{code_name}"
53
+
54
+ @override
55
+ def value_expression(self, code_name: str) -> str:
56
+ return self.local_name(code_name)
57
+
58
+ @override
59
+ def is_secret_parameter(self) -> bool:
60
+ return self.is_secret
@@ -0,0 +1,47 @@
1
+ from typing import Literal, Optional, override
2
+
3
+ from pydantic_openapi_generator.config.base_parameter import (
4
+ BaseArgumentConfiguration,
5
+ )
6
+ from pydantic_openapi_generator.config.parameter_source import ParameterSource
7
+ from pydantic_openapi_generator.config.utils import (
8
+ Parameter,
9
+ lower_code_name,
10
+ optional_override_type_and_default,
11
+ )
12
+
13
+
14
+ class FunctionArgumentConfiguration(BaseArgumentConfiguration):
15
+ type: Literal[ParameterSource.FUNCTION] = ParameterSource.FUNCTION
16
+
17
+ @override
18
+ def default_code_name(self, param_name: str) -> str:
19
+ return lower_code_name(param_name)
20
+
21
+ @override
22
+ def method_type_and_default(self, param: Parameter) -> tuple[str, Optional[str]]:
23
+ return optional_override_type_and_default(param)
24
+
25
+ @override
26
+ def field_type_hint(self, param: Parameter) -> Optional[str]:
27
+ return None
28
+
29
+ @override
30
+ def field_default(self, param: Parameter) -> Optional[str]:
31
+ return None
32
+
33
+ @override
34
+ def getter_name(self, code_name: str) -> str:
35
+ return f"get_{code_name}"
36
+
37
+ @override
38
+ def local_name(self, code_name: str) -> str:
39
+ return f"_{code_name}"
40
+
41
+ @override
42
+ def value_expression(self, code_name: str) -> str:
43
+ return self.local_name(code_name)
44
+
45
+ @override
46
+ def is_secret_parameter(self) -> bool:
47
+ return False
@@ -0,0 +1,33 @@
1
+ from pydantic import BaseModel, ConfigDict, Field, model_validator
2
+
3
+ from pydantic_openapi_generator.config.base_parameter import BaseArgumentConfiguration
4
+ from pydantic_openapi_generator.config.kwarg_parameter import KwargArgumentConfiguration
5
+ from pydantic_openapi_generator.config.parameter_union import ArgumentConfiguration
6
+
7
+
8
+ class PydanticOpenAPIGeneratorConfig(BaseModel):
9
+ model_config = ConfigDict(extra="forbid")
10
+
11
+ parameters: list[ArgumentConfiguration] = Field(default_factory=list)
12
+
13
+ def parameter_configuration_for(self, parameter_name: str) -> BaseArgumentConfiguration:
14
+ configured = self.parameters_by_name().get(parameter_name)
15
+ return configured if configured is not None else KwargArgumentConfiguration(name=parameter_name)
16
+
17
+ def parameters_by_name(self) -> dict[str, ArgumentConfiguration]:
18
+ return {parameter.name: parameter for parameter in self.parameters}
19
+
20
+ @model_validator(mode="after")
21
+ def validate_unique_parameter_names(self) -> "PydanticOpenAPIGeneratorConfig":
22
+ names: set[str] = set()
23
+ duplicates: set[str] = set()
24
+ for parameter in self.parameters:
25
+ if parameter.name in names:
26
+ duplicates.add(parameter.name)
27
+ names.add(parameter.name)
28
+
29
+ if duplicates:
30
+ duplicate_list = ", ".join(sorted(duplicates))
31
+ raise ValueError(f"Duplicate parameter configuration for: {duplicate_list}")
32
+
33
+ return self
@@ -0,0 +1,56 @@
1
+ from typing import Literal, Optional, override
2
+
3
+ from pydantic_openapi_generator.config.base_parameter import BaseArgumentConfiguration
4
+ from pydantic_openapi_generator.config.parameter_source import ParameterSource
5
+ from pydantic_openapi_generator.config.utils import (
6
+ Parameter,
7
+ optional_type,
8
+ parameter_base_type_hint,
9
+ parameter_default,
10
+ )
11
+ from pydantic_openapi_generator.language_converters.python import common
12
+
13
+
14
+ class KwargArgumentConfiguration(BaseArgumentConfiguration):
15
+ type: Literal[ParameterSource.KWARG] = ParameterSource.KWARG
16
+
17
+ @override
18
+ def default_code_name(self, param_name: str) -> str:
19
+ return common.normalize_symbol(param_name)
20
+
21
+ @override
22
+ def method_type_and_default(self, param: Parameter) -> tuple[str, Optional[str]]:
23
+ base_type = parameter_base_type_hint(param)
24
+ default = parameter_default(param)
25
+
26
+ if param.required:
27
+ return base_type, None
28
+
29
+ if default is not None:
30
+ return base_type, default
31
+
32
+ return optional_type(base_type), "None"
33
+
34
+ @override
35
+ def field_type_hint(self, param: Parameter) -> Optional[str]:
36
+ return None
37
+
38
+ @override
39
+ def field_default(self, param: Parameter) -> Optional[str]:
40
+ return None
41
+
42
+ @override
43
+ def getter_name(self, code_name: str) -> Optional[str]:
44
+ return None
45
+
46
+ @override
47
+ def local_name(self, code_name: str) -> Optional[str]:
48
+ return None
49
+
50
+ @override
51
+ def value_expression(self, code_name: str) -> str:
52
+ return code_name
53
+
54
+ @override
55
+ def is_secret_parameter(self) -> bool:
56
+ return False
@@ -0,0 +1,17 @@
1
+ from pathlib import Path
2
+ from typing import Optional
3
+
4
+ from pydantic_di.loaders import ObjectLoaderYaml
5
+
6
+ from pydantic_openapi_generator.config.generator_config import (
7
+ PydanticOpenAPIGeneratorConfig,
8
+ )
9
+
10
+
11
+ def load_config(config_path: Optional[str | Path]) -> PydanticOpenAPIGeneratorConfig:
12
+ if config_path is None:
13
+ return PydanticOpenAPIGeneratorConfig()
14
+
15
+ return ObjectLoaderYaml[PydanticOpenAPIGeneratorConfig](
16
+ path=Path(config_path),
17
+ ).load()
@@ -0,0 +1,7 @@
1
+ from enum import StrEnum
2
+
3
+
4
+ class ParameterSource(StrEnum):
5
+ KWARG = "Kwarg"
6
+ CLASS_VAR = "ClassVar"
7
+ FUNCTION = "Function"
@@ -0,0 +1,16 @@
1
+ from typing import Annotated
2
+
3
+ from pydantic import Field
4
+
5
+ from pydantic_openapi_generator.config.class_var_parameter import (
6
+ ClassVarArgumentConfiguration,
7
+ )
8
+ from pydantic_openapi_generator.config.function_parameter import (
9
+ FunctionArgumentConfiguration,
10
+ )
11
+ from pydantic_openapi_generator.config.kwarg_parameter import KwargArgumentConfiguration
12
+
13
+ ArgumentConfiguration = Annotated[
14
+ KwargArgumentConfiguration | ClassVarArgumentConfiguration | FunctionArgumentConfiguration,
15
+ Field(discriminator="type"),
16
+ ]
@@ -0,0 +1,56 @@
1
+ import re
2
+ from typing import Any, Optional, Union
3
+
4
+ from openapi_pydantic.v3.v3_0 import Reference as Reference30
5
+ from openapi_pydantic.v3.v3_0 import Schema as Schema30
6
+ from openapi_pydantic.v3.v3_0.parameter import Parameter as Parameter30
7
+ from openapi_pydantic.v3.v3_1 import Reference as Reference31
8
+ from openapi_pydantic.v3.v3_1 import Schema as Schema31
9
+ from openapi_pydantic.v3.v3_1.parameter import Parameter as Parameter31
10
+
11
+ from pydantic_openapi_generator.language_converters.python import common
12
+ from pydantic_openapi_generator.language_converters.python.model_generator import (
13
+ type_converter,
14
+ )
15
+
16
+ Parameter = Union[Parameter30, Parameter31]
17
+
18
+
19
+ def lower_code_name(value: str) -> str:
20
+ normalized = common.normalize_symbol(value)
21
+ parts = re.findall(r"[A-Z]+(?=[A-Z][a-z0-9]|$)|[A-Z]?[a-z0-9]+", normalized)
22
+ return "_".join(part.lower() for part in parts) or normalized.lower()
23
+
24
+
25
+ def literal_default(schema: Any) -> Optional[str]:
26
+ default = getattr(schema, "default", None)
27
+ return f"{default!r}" if default is not None else None
28
+
29
+
30
+ def optional_type(type_hint: str) -> str:
31
+ if type_hint.startswith("Optional[") and type_hint.endswith("]"):
32
+ return type_hint
33
+ return f"Optional[{type_hint}]"
34
+
35
+
36
+ def parameter_type_hint(param: Parameter, required: bool) -> str:
37
+ if isinstance(param.param_schema, (Schema30, Schema31)):
38
+ return type_converter(param.param_schema, required).converted_type
39
+ if isinstance(param.param_schema, (Reference30, Reference31)):
40
+ model_name = common.normalize_symbol(param.param_schema.ref.split("/")[-1])
41
+ return model_name if required else f"Optional[{model_name}]"
42
+ return "Any"
43
+
44
+
45
+ def parameter_base_type_hint(param: Parameter) -> str:
46
+ return parameter_type_hint(param, True)
47
+
48
+
49
+ def parameter_default(param: Parameter) -> Optional[str]:
50
+ if isinstance(param.param_schema, (Schema30, Schema31)):
51
+ return literal_default(param.param_schema)
52
+ return None
53
+
54
+
55
+ def optional_override_type_and_default(param: Parameter) -> tuple[str, Optional[str]]:
56
+ return optional_type(parameter_base_type_hint(param)), "None"
@@ -12,6 +12,8 @@ from httpx import ConnectError, ConnectTimeout
12
12
  from pydantic import ValidationError
13
13
 
14
14
  from .common import FormatOptions, Formatter, HTTPLibrary, PydanticVersion
15
+ from .config.generator_config import PydanticOpenAPIGeneratorConfig
16
+ from .config.loader import load_config
15
17
  from .models import ConversionResult
16
18
  from .parsers import (
17
19
  generate_code_3_0,
@@ -203,11 +205,14 @@ def generate_data(
203
205
  custom_template_path: Optional[str] = None,
204
206
  pydantic_version: PydanticVersion = PydanticVersion.V2,
205
207
  formatter: Formatter = Formatter.BLACK,
208
+ config_path: Optional[Union[str, Path]] = None,
209
+ config: Optional[PydanticOpenAPIGeneratorConfig] = None,
206
210
  ) -> None:
207
211
  """
208
212
  Generate Python code from an OpenAPI 3.0+ specification.
209
213
  """
210
214
  openapi_obj, version = get_open_api(source)
215
+ loaded_config = config if config is not None else load_config(config_path)
211
216
  click.echo(f"Generating data from {source} (OpenAPI {version})")
212
217
 
213
218
  # Use version-specific generator
@@ -219,6 +224,7 @@ def generate_data(
219
224
  use_orjson,
220
225
  custom_template_path,
221
226
  pydantic_version,
227
+ loaded_config,
222
228
  )
223
229
  elif version == "3.1":
224
230
  result = generate_code_3_1(
@@ -228,6 +234,7 @@ def generate_data(
228
234
  use_orjson,
229
235
  custom_template_path,
230
236
  pydantic_version,
237
+ loaded_config,
231
238
  )
232
239
  else:
233
240
  raise ValueError(f"Unsupported OpenAPI version: {version}")