openapi-python-client 0.23.1__tar.gz → 0.24.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 (110) hide show
  1. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/PKG-INFO +11 -1
  2. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/README.md +10 -0
  3. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/__init__.py +1 -0
  4. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/config.py +3 -0
  5. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/bodies.py +2 -1
  6. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/openapi.py +24 -3
  7. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/schemas.py +8 -1
  8. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/responses.py +14 -10
  9. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/client.py.jinja +38 -13
  10. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/helpers.jinja +3 -1
  11. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/model.py.jinja +13 -4
  12. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/pyproject.toml +1 -1
  13. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/.gitignore +0 -0
  14. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/LICENSE +0 -0
  15. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/__main__.py +0 -0
  16. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/cli.py +0 -0
  17. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/__init__.py +0 -0
  18. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/errors.py +0 -0
  19. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/__init__.py +0 -0
  20. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/any.py +0 -0
  21. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/boolean.py +0 -0
  22. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/const.py +0 -0
  23. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/date.py +0 -0
  24. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/datetime.py +0 -0
  25. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/enum_property.py +0 -0
  26. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/file.py +0 -0
  27. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/float.py +0 -0
  28. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/int.py +0 -0
  29. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/list_property.py +0 -0
  30. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/literal_enum_property.py +0 -0
  31. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/merge_properties.py +0 -0
  32. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/model_property.py +0 -0
  33. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/none.py +0 -0
  34. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/property.py +0 -0
  35. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/protocol.py +0 -0
  36. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/string.py +0 -0
  37. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/union.py +0 -0
  38. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/parser/properties/uuid.py +0 -0
  39. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/py.typed +0 -0
  40. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/3.0.3.md +0 -0
  41. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/3.1.0.md +0 -0
  42. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/__init__.py +0 -0
  43. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/data_type.py +0 -0
  44. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/LICENSE +0 -0
  45. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/README.md +0 -0
  46. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/__init__.py +0 -0
  47. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/callback.py +0 -0
  48. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/components.py +0 -0
  49. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/contact.py +0 -0
  50. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/discriminator.py +0 -0
  51. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/encoding.py +0 -0
  52. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/example.py +0 -0
  53. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/external_documentation.py +0 -0
  54. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/header.py +0 -0
  55. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/info.py +0 -0
  56. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/license.py +0 -0
  57. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/link.py +0 -0
  58. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/media_type.py +0 -0
  59. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flow.py +0 -0
  60. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/oauth_flows.py +0 -0
  61. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/open_api.py +0 -0
  62. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/operation.py +0 -0
  63. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/parameter.py +0 -0
  64. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/path_item.py +0 -0
  65. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/paths.py +0 -0
  66. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/reference.py +0 -0
  67. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/request_body.py +0 -0
  68. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/response.py +0 -0
  69. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/responses.py +0 -0
  70. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/schema.py +0 -0
  71. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/security_requirement.py +0 -0
  72. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/security_scheme.py +0 -0
  73. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/server.py +0 -0
  74. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/server_variable.py +0 -0
  75. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/tag.py +0 -0
  76. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/openapi_schema_pydantic/xml.py +0 -0
  77. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/schema/parameter_location.py +0 -0
  78. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/.gitignore.jinja +0 -0
  79. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/README.md.jinja +0 -0
  80. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/api_init.py.jinja +0 -0
  81. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/endpoint_init.py.jinja +0 -0
  82. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/endpoint_macros.py.jinja +0 -0
  83. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/endpoint_module.py.jinja +0 -0
  84. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/errors.py.jinja +0 -0
  85. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/int_enum.py.jinja +0 -0
  86. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/literal_enum.py.jinja +0 -0
  87. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/models_init.py.jinja +0 -0
  88. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/package_init.py.jinja +0 -0
  89. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/any_property.py.jinja +0 -0
  90. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/boolean_property.py.jinja +0 -0
  91. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/const_property.py.jinja +0 -0
  92. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/date_property.py.jinja +0 -0
  93. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/datetime_property.py.jinja +0 -0
  94. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/enum_property.py.jinja +0 -0
  95. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/file_property.py.jinja +0 -0
  96. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/float_property.py.jinja +0 -0
  97. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/helpers.jinja +0 -0
  98. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/int_property.py.jinja +0 -0
  99. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/list_property.py.jinja +0 -0
  100. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/literal_enum_property.py.jinja +0 -0
  101. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/model_property.py.jinja +0 -0
  102. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/property_macros.py.jinja +0 -0
  103. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/union_property.py.jinja +0 -0
  104. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/property_templates/uuid_property.py.jinja +0 -0
  105. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/pyproject.toml.jinja +0 -0
  106. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/pyproject_ruff.toml.jinja +0 -0
  107. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/setup.py.jinja +0 -0
  108. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/str_enum.py.jinja +0 -0
  109. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/templates/types.py.jinja +0 -0
  110. {openapi_python_client-0.23.1 → openapi_python_client-0.24.0}/openapi_python_client/utils.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: openapi-python-client
3
- Version: 0.23.1
3
+ Version: 0.24.0
4
4
  Summary: Generate modern Python clients from OpenAPI
5
5
  Project-URL: repository, https://github.com/openapi-generators/openapi-python-client
6
6
  Author-email: Dylan Anthony <contact@dylananthony.com>
@@ -131,6 +131,16 @@ class_overrides:
131
131
 
132
132
  The easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the `models` folder.
133
133
 
134
+ ### docstrings_on_attributes
135
+
136
+ By default, when `openapi-python-client` generates a model class, it includes a list of attributes and their
137
+ descriptions in the docstring for the class. If you set this option to `true`, then the attribute descriptions
138
+ will be put in docstrings for the attributes themselves, and will not be in the class docstring.
139
+
140
+ ```yaml
141
+ docstrings_on_attributes: true
142
+ ```
143
+
134
144
  ### literal_enums
135
145
 
136
146
  By default, `openapi-python-client` generates classes inheriting for `Enum` for enums. It can instead use `Literal`
@@ -97,6 +97,16 @@ class_overrides:
97
97
 
98
98
  The easiest way to find what needs to be overridden is probably to generate your client and go look at everything in the `models` folder.
99
99
 
100
+ ### docstrings_on_attributes
101
+
102
+ By default, when `openapi-python-client` generates a model class, it includes a list of attributes and their
103
+ descriptions in the docstring for the class. If you set this option to `true`, then the attribute descriptions
104
+ will be put in docstrings for the attributes themselves, and will not be in the class docstring.
105
+
106
+ ```yaml
107
+ docstrings_on_attributes: true
108
+ ```
109
+
100
110
  ### literal_enums
101
111
 
102
112
  By default, `openapi-python-client` generates classes inheriting for `Enum` for enums. It can instead use `Literal`
@@ -90,6 +90,7 @@ class Project:
90
90
 
91
91
  self.env.filters.update(TEMPLATE_FILTERS)
92
92
  self.env.globals.update(
93
+ config=config,
93
94
  utils=utils,
94
95
  python_identifier=lambda x: utils.PythonIdentifier(x, config.field_prefix),
95
96
  class_name=lambda x: utils.ClassName(x, config.field_prefix),
@@ -41,6 +41,7 @@ class ConfigFile(BaseModel):
41
41
  package_version_override: Optional[str] = None
42
42
  use_path_prefixes_for_title_model_names: bool = True
43
43
  post_hooks: Optional[list[str]] = None
44
+ docstrings_on_attributes: bool = False
44
45
  field_prefix: str = "field_"
45
46
  generate_all_tags: bool = False
46
47
  http_timeout: int = 5
@@ -70,6 +71,7 @@ class Config:
70
71
  package_version_override: Optional[str]
71
72
  use_path_prefixes_for_title_model_names: bool
72
73
  post_hooks: list[str]
74
+ docstrings_on_attributes: bool
73
75
  field_prefix: str
74
76
  generate_all_tags: bool
75
77
  http_timeout: int
@@ -111,6 +113,7 @@ class Config:
111
113
  package_version_override=config_file.package_version_override,
112
114
  use_path_prefixes_for_title_model_names=config_file.use_path_prefixes_for_title_model_names,
113
115
  post_hooks=post_hooks,
116
+ docstrings_on_attributes=config_file.docstrings_on_attributes,
114
117
  field_prefix=config_file.field_prefix,
115
118
  generate_all_tags=config_file.generate_all_tags,
116
119
  http_timeout=config_file.http_timeout,
@@ -9,6 +9,7 @@ from openapi_python_client.parser.properties import (
9
9
  Schemas,
10
10
  property_from_data,
11
11
  )
12
+ from openapi_python_client.parser.properties.schemas import get_reference_simple_name
12
13
 
13
14
  from .. import schema as oai
14
15
  from ..config import Config
@@ -138,7 +139,7 @@ def _resolve_reference(
138
139
  references_seen = []
139
140
  while isinstance(body, oai.Reference) and body.ref not in references_seen:
140
141
  references_seen.append(body.ref)
141
- body = request_bodies.get(body.ref.split("/")[-1])
142
+ body = request_bodies.get(get_reference_simple_name(body.ref))
142
143
  if isinstance(body, oai.Reference):
143
144
  return ParseError(detail="Circular $ref in request body", data=body)
144
145
  if body is None and references_seen:
@@ -51,6 +51,7 @@ class EndpointCollection:
51
51
  schemas: Schemas,
52
52
  parameters: Parameters,
53
53
  request_bodies: dict[str, Union[oai.RequestBody, oai.Reference]],
54
+ responses: dict[str, Union[oai.Response, oai.Reference]],
54
55
  config: Config,
55
56
  ) -> tuple[dict[utils.PythonIdentifier, "EndpointCollection"], Schemas, Parameters]:
56
57
  """Parse the openapi paths data to get EndpointCollections by tag"""
@@ -78,6 +79,7 @@ class EndpointCollection:
78
79
  schemas=schemas,
79
80
  parameters=parameters,
80
81
  request_bodies=request_bodies,
82
+ responses=responses,
81
83
  config=config,
82
84
  )
83
85
  # Add `PathItem` parameters
@@ -151,7 +153,12 @@ class Endpoint:
151
153
 
152
154
  @staticmethod
153
155
  def _add_responses(
154
- *, endpoint: "Endpoint", data: oai.Responses, schemas: Schemas, config: Config
156
+ *,
157
+ endpoint: "Endpoint",
158
+ data: oai.Responses,
159
+ schemas: Schemas,
160
+ responses: dict[str, Union[oai.Response, oai.Reference]],
161
+ config: Config,
155
162
  ) -> tuple["Endpoint", Schemas]:
156
163
  endpoint = deepcopy(endpoint)
157
164
  for code, response_data in data.items():
@@ -174,6 +181,7 @@ class Endpoint:
174
181
  status_code=status_code,
175
182
  data=response_data,
176
183
  schemas=schemas,
184
+ responses=responses,
177
185
  parent_name=endpoint.name,
178
186
  config=config,
179
187
  )
@@ -403,6 +411,7 @@ class Endpoint:
403
411
  schemas: Schemas,
404
412
  parameters: Parameters,
405
413
  request_bodies: dict[str, Union[oai.RequestBody, oai.Reference]],
414
+ responses: dict[str, Union[oai.Response, oai.Reference]],
406
415
  config: Config,
407
416
  ) -> tuple[Union["Endpoint", ParseError], Schemas, Parameters]:
408
417
  """Construct an endpoint from the OpenAPI data"""
@@ -431,7 +440,13 @@ class Endpoint:
431
440
  )
432
441
  if isinstance(result, ParseError):
433
442
  return result, schemas, parameters
434
- result, schemas = Endpoint._add_responses(endpoint=result, data=data.responses, schemas=schemas, config=config)
443
+ result, schemas = Endpoint._add_responses(
444
+ endpoint=result,
445
+ data=data.responses,
446
+ schemas=schemas,
447
+ responses=responses,
448
+ config=config,
449
+ )
435
450
  if isinstance(result, ParseError):
436
451
  return result, schemas, parameters
437
452
  bodies, schemas = body_from_data(
@@ -521,8 +536,14 @@ class GeneratorData:
521
536
  config=config,
522
537
  )
523
538
  request_bodies = (openapi.components and openapi.components.requestBodies) or {}
539
+ responses = (openapi.components and openapi.components.responses) or {}
524
540
  endpoint_collections_by_tag, schemas, parameters = EndpointCollection.from_data(
525
- data=openapi.paths, schemas=schemas, parameters=parameters, request_bodies=request_bodies, config=config
541
+ data=openapi.paths,
542
+ schemas=schemas,
543
+ parameters=parameters,
544
+ request_bodies=request_bodies,
545
+ responses=responses,
546
+ config=config,
526
547
  )
527
548
 
528
549
  enums = (
@@ -46,6 +46,13 @@ def parse_reference_path(ref_path_raw: str) -> Union[ReferencePath, ParseError]:
46
46
  return cast(ReferencePath, parsed.fragment)
47
47
 
48
48
 
49
+ def get_reference_simple_name(ref_path: str) -> str:
50
+ """
51
+ Takes a path like `/components/schemas/NameOfThing` and returns a string like `NameOfThing`.
52
+ """
53
+ return ref_path.split("/")[-1]
54
+
55
+
49
56
  @define
50
57
  class Class:
51
58
  """Represents Python class which will be generated from an OpenAPI schema"""
@@ -56,7 +63,7 @@ class Class:
56
63
  @staticmethod
57
64
  def from_string(*, string: str, config: Config) -> "Class":
58
65
  """Get a Class from an arbitrary string"""
59
- class_name = string.split("/")[-1] # Get rid of ref path stuff
66
+ class_name = get_reference_simple_name(string) # Get rid of ref path stuff
60
67
  class_name = ClassName(class_name, config.field_prefix)
61
68
  override = config.class_overrides.get(class_name)
62
69
 
@@ -6,6 +6,7 @@ from typing import Optional, TypedDict, Union
6
6
  from attrs import define
7
7
 
8
8
  from openapi_python_client import utils
9
+ from openapi_python_client.parser.properties.schemas import get_reference_simple_name, parse_reference_path
9
10
 
10
11
  from .. import Config
11
12
  from .. import schema as oai
@@ -79,11 +80,12 @@ def empty_response(
79
80
  )
80
81
 
81
82
 
82
- def response_from_data(
83
+ def response_from_data( # noqa: PLR0911
83
84
  *,
84
85
  status_code: HTTPStatus,
85
86
  data: Union[oai.Response, oai.Reference],
86
87
  schemas: Schemas,
88
+ responses: dict[str, Union[oai.Response, oai.Reference]],
87
89
  parent_name: str,
88
90
  config: Config,
89
91
  ) -> tuple[Union[Response, ParseError], Schemas]:
@@ -91,15 +93,17 @@ def response_from_data(
91
93
 
92
94
  response_name = f"response_{status_code}"
93
95
  if isinstance(data, oai.Reference):
94
- return (
95
- empty_response(
96
- status_code=status_code,
97
- response_name=response_name,
98
- config=config,
99
- data=data,
100
- ),
101
- schemas,
102
- )
96
+ ref_path = parse_reference_path(data.ref)
97
+ if isinstance(ref_path, ParseError):
98
+ return ref_path, schemas
99
+ if not ref_path.startswith("/components/responses/"):
100
+ return ParseError(data=data, detail=f"$ref to {data.ref} not allowed in responses"), schemas
101
+ resp_data = responses.get(get_reference_simple_name(ref_path), None)
102
+ if not resp_data:
103
+ return ParseError(data=data, detail=f"Could not find reference: {data.ref}"), schemas
104
+ if not isinstance(resp_data, oai.Response):
105
+ return ParseError(data=data, detail="Top-level $ref inside components/responses is not supported"), schemas
106
+ data = resp_data
103
107
 
104
108
  content = data.content
105
109
  if not content:
@@ -5,6 +5,31 @@ from attrs import define, field, evolve
5
5
  import httpx
6
6
 
7
7
 
8
+ {% set attrs_info = {
9
+ "raise_on_unexpected_status": namespace(
10
+ type="bool",
11
+ default="field(default=False, kw_only=True)",
12
+ docstring="Whether or not to raise an errors.UnexpectedStatus if the API returns a status code"
13
+ " that was not documented in the source OpenAPI document. Can also be provided as a keyword"
14
+ " argument to the constructor."
15
+ ),
16
+ "token": namespace(type="str", default="", docstring="The token to use for authentication"),
17
+ "prefix": namespace(type="str", default='"Bearer"', docstring="The prefix to use for the Authorization header"),
18
+ "auth_header_name": namespace(type="str", default='"Authorization"', docstring="The name of the Authorization header"),
19
+ } %}
20
+
21
+ {% macro attr_in_class_docstring(name) %}
22
+ {{ name }}: {{ attrs_info[name].docstring }}
23
+ {%- endmacro %}
24
+
25
+ {% macro declare_attr(name) %}
26
+ {% set attr = attrs_info[name] %}
27
+ {{ name }}: {{ attr.type }}{% if attr.default %} = {{ attr.default }}{% endif %}
28
+ {% if attr.docstring and config.docstrings_on_attributes +%}
29
+ """{{ attr.docstring }}"""
30
+ {%- endif %}
31
+ {% endmacro %}
32
+
8
33
  @define
9
34
  class Client:
10
35
  """A class for keeping track of data related to the API
@@ -29,14 +54,14 @@ class Client:
29
54
  ``httpx_args``: A dictionary of additional arguments to be passed to the ``httpx.Client`` and ``httpx.AsyncClient`` constructor.
30
55
  {% endmacro %}
31
56
  {{ httpx_args_docstring() }}
57
+ {% if not config.docstrings_on_attributes %}
32
58
 
33
59
  Attributes:
34
- raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
35
- status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
36
- argument to the constructor.
60
+ {{ attr_in_class_docstring("raise_on_unexpected_status") | wordwrap(101) | indent(12) }}
61
+ {% endif %}
37
62
  """
38
63
  {% macro attributes() %}
39
- raise_on_unexpected_status: bool = field(default=False, kw_only=True)
64
+ {{ declare_attr("raise_on_unexpected_status") | indent(4) }}
40
65
  _base_url: str = field(alias="base_url")
41
66
  _cookies: dict[str, str] = field(factory=dict, kw_only=True, alias="cookies")
42
67
  _headers: dict[str, str] = field(factory=dict, kw_only=True, alias="headers")
@@ -147,20 +172,20 @@ class AuthenticatedClient:
147
172
  """A Client which has been authenticated for use on secured endpoints
148
173
 
149
174
  {{ httpx_args_docstring() }}
175
+ {% if not config.docstrings_on_attributes %}
150
176
 
151
177
  Attributes:
152
- raise_on_unexpected_status: Whether or not to raise an errors.UnexpectedStatus if the API returns a
153
- status code that was not documented in the source OpenAPI document. Can also be provided as a keyword
154
- argument to the constructor.
155
- token: The token to use for authentication
156
- prefix: The prefix to use for the Authorization header
157
- auth_header_name: The name of the Authorization header
178
+ {{ attr_in_class_docstring("raise_on_unexpected_status") | wordwrap(101) | indent(12) }}
179
+ {{ attr_in_class_docstring("token") | indent(8) }}
180
+ {{ attr_in_class_docstring("prefix") | indent(8) }}
181
+ {{ attr_in_class_docstring("auth_header_name") | indent(8) }}
182
+ {% endif %}
158
183
  """
159
184
 
160
185
  {{ attributes() }}
161
- token: str
162
- prefix: str = "Bearer"
163
- auth_header_name: str = "Authorization"
186
+ {{ declare_attr("token") | indent(4) }}
187
+ {{ declare_attr("prefix") | indent(4) }}
188
+ {{ declare_attr("auth_header_name") | indent(4) }}
164
189
 
165
190
  {{ builders("AuthenticatedClient") }}
166
191
  {{ httpx_stuff("AuthenticatedClient", "self._headers[self.auth_header_name] = f\"{self.prefix} {self.token}\" if self.prefix else self.token") }}
@@ -1,8 +1,10 @@
1
- {% macro safe_docstring(content) %}
1
+ {% macro safe_docstring(content, omit_if_empty=False) %}
2
2
  {# This macro returns the provided content as a docstring, set to a raw string if it contains a backslash #}
3
+ {% if (not omit_if_empty) or (content | trim) %}
3
4
  {% if '\\' in content -%}
4
5
  r""" {{ content }} """
5
6
  {%- else -%}
6
7
  """ {{ content }} """
7
8
  {%- endif -%}
9
+ {% endif %}
8
10
  {% endmacro %}
@@ -47,25 +47,34 @@ T = TypeVar("T", bound="{{ class_name }}")
47
47
  {{ model.example | string | wordwrap(112) | indent(12) }}
48
48
 
49
49
  {% endif %}
50
- {% if model.required_properties or model.optional_properties %}
50
+ {% if (not config.docstrings_on_attributes) and (model.required_properties or model.optional_properties) %}
51
51
  Attributes:
52
52
  {% for property in model.required_properties + model.optional_properties %}
53
53
  {{ property.to_docstring() | wordwrap(112) | indent(12) }}
54
54
  {% endfor %}{% endif %}
55
55
  {% endmacro %}
56
56
 
57
+ {% macro declare_property(property) %}
58
+ {%- if config.docstrings_on_attributes and property.description -%}
59
+ {{ property.to_string() }}
60
+ {{ safe_docstring(property.description, omit_if_empty=True) | wordwrap(112) }}
61
+ {%- else -%}
62
+ {{ property.to_string() }}
63
+ {%- endif -%}
64
+ {% endmacro %}
65
+
57
66
  @_attrs_define
58
67
  class {{ class_name }}:
59
- {{ safe_docstring(class_docstring_content(model)) | indent(4) }}
68
+ {{ safe_docstring(class_docstring_content(model), omit_if_empty=config.docstrings_on_attributes) | indent(4) }}
60
69
 
61
70
  {% for property in model.required_properties + model.optional_properties %}
62
71
  {% if property.default is none and property.required %}
63
- {{ property.to_string() }}
72
+ {{ declare_property(property) | indent(4) }}
64
73
  {% endif %}
65
74
  {% endfor %}
66
75
  {% for property in model.required_properties + model.optional_properties %}
67
76
  {% if property.default is not none or not property.required %}
68
- {{ property.to_string() }}
77
+ {{ declare_property(property) | indent(4) }}
69
78
  {% endif %}
70
79
  {% endfor %}
71
80
  {% if model.additional_properties %}
@@ -18,7 +18,7 @@ dependencies = [
18
18
  "typing-extensions>=4.8.0,<5.0.0",
19
19
  ]
20
20
  name = "openapi-python-client"
21
- version = "0.23.1"
21
+ version = "0.24.0"
22
22
  description = "Generate modern Python clients from OpenAPI"
23
23
  keywords = [
24
24
  "OpenAPI",