datamodel-code-generator 0.31.1__py3-none-any.whl → 0.32.0__py3-none-any.whl

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.

Potentially problematic release.


This version of datamodel-code-generator might be problematic. Click here for more details.

@@ -258,6 +258,7 @@ def generate( # noqa: PLR0912, PLR0913, PLR0914, PLR0915
258
258
  field_include_all_keys: bool = False,
259
259
  field_extra_keys_without_x_prefix: set[str] | None = None,
260
260
  openapi_scopes: list[OpenAPIScope] | None = None,
261
+ include_path_parameters: bool = False,
261
262
  graphql_scopes: list[GraphQLScope] | None = None, # noqa: ARG001
262
263
  wrap_string_literal: bool | None = None,
263
264
  use_title_as_name: bool = False,
@@ -327,6 +328,7 @@ def generate( # noqa: PLR0912, PLR0913, PLR0914, PLR0915
327
328
 
328
329
  parser_class: type[Parser] = OpenAPIParser
329
330
  kwargs["openapi_scopes"] = openapi_scopes
331
+ kwargs["include_path_parameters"] = include_path_parameters
330
332
  elif input_file_type == InputFileType.GraphQL:
331
333
  from datamodel_code_generator.parser.graphql import GraphQLParser # noqa: PLC0415
332
334
 
@@ -547,7 +549,8 @@ def generate( # noqa: PLR0912, PLR0913, PLR0914, PLR0915
547
549
  path.parent.mkdir(parents=True)
548
550
  file = path.open("wt", encoding=encoding)
549
551
 
550
- print(custom_file_header or header.format(filename), file=file)
552
+ safe_filename = filename.replace("\n", " ").replace("\r", " ") if filename else ""
553
+ print(custom_file_header or header.format(safe_filename), file=file)
551
554
  if body:
552
555
  print(file=file)
553
556
  print(body.rstrip(), file=file)
@@ -287,6 +287,7 @@ class Config(BaseModel):
287
287
  field_include_all_keys: bool = False
288
288
  field_extra_keys_without_x_prefix: Optional[set[str]] = None # noqa: UP045
289
289
  openapi_scopes: Optional[list[OpenAPIScope]] = [OpenAPIScope.Schemas] # noqa: UP045
290
+ include_path_parameters: bool = False
290
291
  wrap_string_literal: Optional[bool] = None # noqa: UP045
291
292
  use_title_as_name: bool = False
292
293
  use_operation_id_as_name: bool = False
@@ -500,6 +501,7 @@ def main(args: Sequence[str] | None = None) -> Exit: # noqa: PLR0911, PLR0912,
500
501
  field_include_all_keys=config.field_include_all_keys,
501
502
  field_extra_keys_without_x_prefix=config.field_extra_keys_without_x_prefix,
502
503
  openapi_scopes=config.openapi_scopes,
504
+ include_path_parameters=config.include_path_parameters,
503
505
  wrap_string_literal=config.wrap_string_literal,
504
506
  use_title_as_name=config.use_title_as_name,
505
507
  use_operation_id_as_name=config.use_operation_id_as_name,
@@ -500,6 +500,12 @@ openapi_options.add_argument(
500
500
  action="store_true",
501
501
  default=None,
502
502
  )
503
+ openapi_options.add_argument(
504
+ "--include-path-parameters",
505
+ help="Include path parameters in generated parameter models in addition to query parameters (Only OpenAPI)",
506
+ action="store_true",
507
+ default=None,
508
+ )
503
509
  openapi_options.add_argument(
504
510
  "--validation",
505
511
  help="Deprecated: Enable validation (Only OpenAPI). this option is deprecated. it will be removed in future "
@@ -141,7 +141,7 @@ number_kwargs: set[str] = {
141
141
 
142
142
  string_kwargs: set[str] = {"minItems", "maxItems", "minLength", "maxLength", "pattern"}
143
143
 
144
- byes_kwargs: set[str] = {"minLength", "maxLength"}
144
+ bytes_kwargs: set[str] = {"minLength", "maxLength"}
145
145
 
146
146
  escape_characters = str.maketrans({
147
147
  "'": r"\'",
@@ -296,7 +296,7 @@ class DataTypeManager(_DataTypeManager):
296
296
  return self.type_map[types]
297
297
 
298
298
  def get_data_bytes_type(self, types: Types, **kwargs: Any) -> DataType:
299
- data_type_kwargs: dict[str, Any] = self.transform_kwargs(kwargs, byes_kwargs)
299
+ data_type_kwargs: dict[str, Any] = self.transform_kwargs(kwargs, bytes_kwargs)
300
300
  strict = StrictTypes.bytes in self.strict_types
301
301
  if data_type_kwargs and not strict:
302
302
  return self.data_type.from_import(IMPORT_CONBYTES, kwargs=data_type_kwargs)
@@ -1,5 +1,5 @@
1
1
  {%- if description %}
2
- # {{ description }}
2
+ # {{ description | replace('\n', '\n# ') }}
3
3
  {%- endif %}
4
4
  {%- if fields|length > 1 %}
5
5
  {{ class_name }}: TypeAlias = Union[
@@ -389,6 +389,7 @@ class Parser(ABC):
389
389
  python_version=target_python_version,
390
390
  use_standard_collections=use_standard_collections,
391
391
  use_generic_container_types=use_generic_container_types,
392
+ use_non_positive_negative_number_constrained_types=use_non_positive_negative_number_constrained_types,
392
393
  strict_types=strict_types,
393
394
  use_union_operator=use_union_operator,
394
395
  use_pendulum=use_pendulum,
@@ -308,6 +308,7 @@ class GraphQLParser(Parser):
308
308
  required=False,
309
309
  alias="__typename",
310
310
  use_one_literal_as_default=True,
311
+ use_default_kwarg=self.use_default_kwarg,
311
312
  has_default=True,
312
313
  )
313
314
 
@@ -211,6 +211,33 @@ class JsonSchemaObject(BaseModel):
211
211
  return value.replace("#", "#/")
212
212
  return value
213
213
 
214
+ @field_validator("required", mode="before")
215
+ def validate_required(cls, value: Any) -> Any: # noqa: N805
216
+ if value is None:
217
+ return []
218
+ if isinstance(value, list): # noqa: PLR1702
219
+ # Filter to only include valid strings, excluding invalid objects
220
+ required_fields: list[str] = []
221
+ for item in value:
222
+ if isinstance(item, str):
223
+ required_fields.append(item)
224
+
225
+ # In some cases, the required field can include "anyOf", "oneOf", or "allOf" as a dict (#2297)
226
+ elif isinstance(item, dict):
227
+ for key, val in item.items():
228
+ if isinstance(val, list):
229
+ # If 'anyOf' or "oneOf" is present, we won't include it in required fields
230
+ if key in {"anyOf", "oneOf"}:
231
+ continue
232
+
233
+ if key == "allOf":
234
+ # If 'allOf' is present, we include them as required fields
235
+ required_fields.extend(sub_item for sub_item in val if isinstance(sub_item, str))
236
+
237
+ value = required_fields
238
+
239
+ return value
240
+
214
241
  items: Optional[Union[list[JsonSchemaObject], JsonSchemaObject, bool]] = None # noqa: UP007, UP045
215
242
  uniqueItems: Optional[bool] = None # noqa: N815, UP045
216
243
  type: Optional[Union[str, list[str]]] = None # noqa: UP007, UP045
@@ -1376,6 +1403,7 @@ class JsonSchemaParser(Parser):
1376
1403
  custom_template_dir=self.custom_template_dir,
1377
1404
  type_=_get_type(obj.type, obj.format) if self.use_subclass_enum and isinstance(obj.type, str) else None,
1378
1405
  default=obj.default if obj.has_default else UNDEFINED,
1406
+ treat_dot_as_module=self.treat_dot_as_module,
1379
1407
  )
1380
1408
  self.results.append(enum)
1381
1409
  return self.data_type(reference=reference_)
@@ -1552,7 +1580,7 @@ class JsonSchemaParser(Parser):
1552
1580
  raw: dict[str, Any],
1553
1581
  path: list[str],
1554
1582
  ) -> None:
1555
- self.parse_obj(name, self.SCHEMA_OBJECT_TYPE.parse_obj(raw), path)
1583
+ self.parse_obj(name, self.SCHEMA_OBJECT_TYPE.model_validate(raw), path)
1556
1584
 
1557
1585
  def parse_obj(
1558
1586
  self,
@@ -189,6 +189,7 @@ class OpenAPIParser(JsonSchemaParser):
189
189
  field_include_all_keys: bool = False,
190
190
  field_extra_keys_without_x_prefix: set[str] | None = None,
191
191
  openapi_scopes: list[OpenAPIScope] | None = None,
192
+ include_path_parameters: bool = False,
192
193
  wrap_string_literal: bool | None = False,
193
194
  use_title_as_name: bool = False,
194
195
  use_operation_id_as_name: bool = False,
@@ -299,6 +300,7 @@ class OpenAPIParser(JsonSchemaParser):
299
300
  parent_scoped_naming=parent_scoped_naming,
300
301
  )
301
302
  self.open_api_scopes: list[OpenAPIScope] = openapi_scopes or [OpenAPIScope.Schemas]
303
+ self.include_path_parameters: bool = include_path_parameters
302
304
 
303
305
  def get_ref_model(self, ref: str) -> dict[str, Any]:
304
306
  ref_file, ref_path = self.model_resolver.resolve_ref(ref).split("#", 1)
@@ -351,13 +353,17 @@ class OpenAPIParser(JsonSchemaParser):
351
353
  name: str,
352
354
  request_body: RequestBodyObject,
353
355
  path: list[str],
354
- ) -> None:
356
+ ) -> dict[str, DataType]:
357
+ data_types: dict[str, DataType] = {}
355
358
  for (
356
359
  media_type,
357
360
  media_obj,
358
361
  ) in request_body.content.items():
359
362
  if isinstance(media_obj.schema_, JsonSchemaObject):
360
- self.parse_schema(name, media_obj.schema_, [*path, media_type])
363
+ data_types[media_type] = self.parse_schema(name, media_obj.schema_, [*path, media_type])
364
+ elif media_obj.schema_ is not None:
365
+ data_types[media_type] = self.get_ref_data_type(media_obj.schema_.ref)
366
+ return data_types
361
367
 
362
368
  def parse_responses(
363
369
  self,
@@ -414,15 +420,24 @@ class OpenAPIParser(JsonSchemaParser):
414
420
  name: str,
415
421
  parameters: list[ReferenceObject | ParameterObject],
416
422
  path: list[str],
417
- ) -> None:
423
+ ) -> DataType | None:
418
424
  fields: list[DataModelFieldBase] = []
419
425
  exclude_field_names: set[str] = set()
420
426
  reference = self.model_resolver.add(path, name, class_name=True, unique=True)
421
427
  for parameter_ in parameters:
422
428
  parameter = self.resolve_object(parameter_, ParameterObject)
423
429
  parameter_name = parameter.name
424
- if not parameter_name or parameter.in_ != ParameterLocation.query:
430
+ if (
431
+ not parameter_name
432
+ or parameter.in_ not in {ParameterLocation.query, ParameterLocation.path}
433
+ or (parameter.in_ == ParameterLocation.path and not self.include_path_parameters)
434
+ ):
425
435
  continue
436
+
437
+ if any(field.original_name == parameter_name for field in fields):
438
+ msg = f"Parameter name '{parameter_name}' is used more than once."
439
+ raise Exception(msg) # noqa: TRY002
440
+
426
441
  field_name, alias = self.model_resolver.get_valid_field_name_and_alias(
427
442
  field_name=parameter_name, excludes=exclude_field_names
428
443
  )
@@ -500,6 +515,9 @@ class OpenAPIParser(JsonSchemaParser):
500
515
  treat_dot_as_module=self.treat_dot_as_module,
501
516
  )
502
517
  )
518
+ return self.data_type(reference=reference)
519
+
520
+ return None
503
521
 
504
522
  def parse_operation(
505
523
  self,
@@ -518,7 +536,9 @@ class OpenAPIParser(JsonSchemaParser):
518
536
  path_name = operation.operationId
519
537
  method = ""
520
538
  self.parse_all_parameters(
521
- self._get_model_name(path_name, method, suffix="ParametersQuery"),
539
+ self._get_model_name(
540
+ path_name, method, suffix="Parameters" if self.include_path_parameters else "ParametersQuery"
541
+ ),
522
542
  operation.parameters,
523
543
  [*path, "parameters"],
524
544
  )
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datamodel-code-generator
3
- Version: 0.31.1
3
+ Version: 0.32.0
4
4
  Summary: Datamodel Code Generator
5
5
  Project-URL: Homepage, https://github.com/koxudaxi/datamodel-code-generator
6
6
  Project-URL: Source, https://github.com/koxudaxi/datamodel-code-generator
@@ -552,6 +552,9 @@ Template customization:
552
552
  option (require black 20.8b0 or later)
553
553
 
554
554
  OpenAPI-only options:
555
+ --include-path-parameters
556
+ Include path parameters in generated parameter models in addition to
557
+ query parameters (Only OpenAPI)
555
558
  --openapi-scopes {schemas,paths,tags,parameters} [{schemas,paths,tags,parameters} ...]
556
559
  Scopes of OpenAPI model generation (default: schemas)
557
560
  --strict-nullable Treat default field as a non-nullable field (Only OpenAPI)
@@ -1,6 +1,6 @@
1
- datamodel_code_generator/__init__.py,sha256=H6ZnGum3Xw1u1o2e7a6gLjA09Vm2DlXo_Vm8GRrTUlY,20602
2
- datamodel_code_generator/__main__.py,sha256=Z9g_NGrnxV63MRuqtUUpPW48felXmVxwGBtWWkgNlj4,22803
3
- datamodel_code_generator/arguments.py,sha256=3GrwOmcqOpBIuZgkg0_3AFO1iKH9Mj0MryQ4PqJmThY,17147
1
+ datamodel_code_generator/__init__.py,sha256=5WIAPB0SYL-VFLIfC8OKl9euih2S6IfZ6otV7ZWCXKY,20809
2
+ datamodel_code_generator/__main__.py,sha256=RtiTFNKB-UAL54ywMB8mSllkYhE9h-GZOe_h9ztmOM8,22913
3
+ datamodel_code_generator/arguments.py,sha256=JdU1DvV4wMFdmaqqYiTQ2eafLyK2LhztwjTiwekEwIg,17368
4
4
  datamodel_code_generator/format.py,sha256=ZlnTCAl1H4og685smvCBSzexgpYbZtyYLIrt7lwUNcY,8934
5
5
  datamodel_code_generator/http.py,sha256=LE94GC7I9D8lWIg_YAGWedfy0XNxOXTmiYKuNMTwouo,887
6
6
  datamodel_code_generator/imports.py,sha256=Nq83WbEGCegntg3WX4VbKfzAIs84alZ7IrYyNPrlUbc,5517
@@ -25,7 +25,7 @@ datamodel_code_generator/model/pydantic/base_model.py,sha256=0ZsoQfjhhRTMlvsThGE
25
25
  datamodel_code_generator/model/pydantic/custom_root_type.py,sha256=VJpEAmGFe3TzMKrR5YvR7PJ3pfGHcYytO1zhQrWyoWg,299
26
26
  datamodel_code_generator/model/pydantic/dataclass.py,sha256=jgjkqQk71CQP4RbTcPGSEOQDNqjTQnzFavvl5LjWTBw,455
27
27
  datamodel_code_generator/model/pydantic/imports.py,sha256=nWPiLgDeYNPHcAs8M-gaUUZg1daQRHdBPpjYuX3b5u4,2225
28
- datamodel_code_generator/model/pydantic/types.py,sha256=ttTiDsQ6FV3h4C_NTEhvPUmUpeqxBNQt-DJJFpKZS8s,13356
28
+ datamodel_code_generator/model/pydantic/types.py,sha256=pI6LTvjT3ddiIYylR2MZ1Hq3Wem3pie6gedpGxyzyF4,13358
29
29
  datamodel_code_generator/model/pydantic_v2/__init__.py,sha256=YHfOs8prPBsrQmYm0kJATSyU0wafQTqKNd24e2-KGJE,1344
30
30
  datamodel_code_generator/model/pydantic_v2/base_model.py,sha256=ztDpXrifLVGABElvAgg-h5rulgQHxDG40DQ_Nr91JHg,8723
31
31
  datamodel_code_generator/model/pydantic_v2/imports.py,sha256=K3XD2kF9YCKmo5_7b2ipV5bGUrjz0avS-SiyDMVIpF0,299
@@ -36,7 +36,7 @@ datamodel_code_generator/model/template/Scalar.jinja2,sha256=Ss22-mYG3Vez-pbqmW2
36
36
  datamodel_code_generator/model/template/TypedDict.jinja2,sha256=J_Pe_CiuvTOb-EUCExXPaeTEFzn2keyrKB0wglZ8HgA,135
37
37
  datamodel_code_generator/model/template/TypedDictClass.jinja2,sha256=URwp5__WyR8G21Hoyc17aMzoast-NppXnXe19VFi5wQ,377
38
38
  datamodel_code_generator/model/template/TypedDictFunction.jinja2,sha256=KjSij5_w4ow4a12SR3orYOndmXGkIvJBBUN735bQ6G0,321
39
- datamodel_code_generator/model/template/Union.jinja2,sha256=sq7o--2ESUSfIL4kCfgnr5ZXPFa_VeioqbATTY-N-5I,258
39
+ datamodel_code_generator/model/template/Union.jinja2,sha256=Sx_aqvNPOr75YmbVDfgfzZiBo71DWjzqu7kz-6j8JMY,282
40
40
  datamodel_code_generator/model/template/dataclass.jinja2,sha256=c3gs1ZwDEwLpmZ2PpOEWjHjfdl6kPP64xm18mt9lZMk,1007
41
41
  datamodel_code_generator/model/template/msgspec.jinja2,sha256=qMuFOH6SFFh558wImdI6uIjG4Mtam3J_ox8Hmgqkv0g,1174
42
42
  datamodel_code_generator/model/template/root.jinja2,sha256=3OTtibxLcGA-FMdR0QDCJUJQgf_kRW0OafeCTPFSFFo,162
@@ -48,12 +48,12 @@ datamodel_code_generator/model/template/pydantic_v2/BaseModel.jinja2,sha256=i1Wg
48
48
  datamodel_code_generator/model/template/pydantic_v2/ConfigDict.jinja2,sha256=xHvBYrh__32O1xRCSl6_u5zbyYIjB8a5k8fZiTo0spY,149
49
49
  datamodel_code_generator/model/template/pydantic_v2/RootModel.jinja2,sha256=XQBlML7Hm5hN6_AExENNvVc_yxNWijcIfTTbbmegCpE,1223
50
50
  datamodel_code_generator/parser/__init__.py,sha256=3XtFcDPocaetfjmWFqj_CubqNCDipb7vXZHsYKdJXXU,851
51
- datamodel_code_generator/parser/base.py,sha256=4B4UeEjCfl_IdRak_qi5Wx8sUx5bX8Xt-Z0CmfsWsks,62940
52
- datamodel_code_generator/parser/graphql.py,sha256=TNLxy-0wWJSpCm6HK5fKooZdaJodcwQqVr0J29ao3J8,23330
53
- datamodel_code_generator/parser/jsonschema.py,sha256=oFSZOyLL3K0tneH09t2lNKdWcbmR_r5OjCyWKPq2Jxc,71114
54
- datamodel_code_generator/parser/openapi.py,sha256=kI4kqVBG96rdAVb8z0l4gF6QpcylgVoGjlK_-KToZRg,27607
55
- datamodel_code_generator-0.31.1.dist-info/METADATA,sha256=ZFqob9ufiN1g9KBorISN9qxipHDlsoTChiKZZWpNZ2o,25577
56
- datamodel_code_generator-0.31.1.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
- datamodel_code_generator-0.31.1.dist-info/entry_points.txt,sha256=cJVcHiEViQMANaoM5C1xR5hzmyCqH6hHHMpV8W00in8,77
58
- datamodel_code_generator-0.31.1.dist-info/licenses/LICENSE,sha256=K54Lwc6_jduycsy8oFFjQEeSSuEiqvVIjCGIXOMnuTQ,1068
59
- datamodel_code_generator-0.31.1.dist-info/RECORD,,
51
+ datamodel_code_generator/parser/base.py,sha256=nYL7JjmsfsZHIPgIr5Mp4Gzy2BC2-EAm-ZFrMZMR6yw,63055
52
+ datamodel_code_generator/parser/graphql.py,sha256=x5Jge8xZiaup9jMhX6jVKncme_D5FmSoEWmXIKtguVo,23384
53
+ datamodel_code_generator/parser/jsonschema.py,sha256=Y5jZtjZmg6ewo3J44RUSLq01sqA0ugW5eezK9b90Qtk,72412
54
+ datamodel_code_generator/parser/openapi.py,sha256=nVZoO4BvVbh_jVCtzjcXZAuVMrlQUQo4ZbBqZC-JBB0,28529
55
+ datamodel_code_generator-0.32.0.dist-info/METADATA,sha256=xryfSH-rOwdjyJX2HPeFzkDLcG-D5yiWU5jpY5F8A1Y,25754
56
+ datamodel_code_generator-0.32.0.dist-info/WHEEL,sha256=qtCwoSJWgHk21S1Kb4ihdzI2rlJ1ZKaIurTj_ngOhyQ,87
57
+ datamodel_code_generator-0.32.0.dist-info/entry_points.txt,sha256=cJVcHiEViQMANaoM5C1xR5hzmyCqH6hHHMpV8W00in8,77
58
+ datamodel_code_generator-0.32.0.dist-info/licenses/LICENSE,sha256=K54Lwc6_jduycsy8oFFjQEeSSuEiqvVIjCGIXOMnuTQ,1068
59
+ datamodel_code_generator-0.32.0.dist-info/RECORD,,