datamodel-code-generator 0.18.1__tar.gz → 0.20.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.
Potentially problematic release.
This version of datamodel-code-generator might be problematic. Click here for more details.
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/PKG-INFO +12 -51
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/README.md +10 -43
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/__init__.py +10 -4
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/__main__.py +23 -1
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/format.py +32 -2
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/imports.py +1 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/__init__.py +17 -3
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/base.py +7 -1
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/dataclass.py +8 -2
- datamodel_code_generator-0.20.0/datamodel_code_generator/model/improts.py +8 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/pydantic/types.py +1 -1
- datamodel_code_generator-0.20.0/datamodel_code_generator/model/template/TypedDict.jinja2 +5 -0
- datamodel_code_generator-0.20.0/datamodel_code_generator/model/template/TypedDictClass.jinja2 +17 -0
- datamodel_code_generator-0.20.0/datamodel_code_generator/model/template/TypedDictFunction.jinja2 +16 -0
- datamodel_code_generator-0.20.0/datamodel_code_generator/model/typed_dict.py +151 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/types.py +1 -1
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/parser/base.py +1 -6
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/parser/jsonschema.py +99 -33
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/parser/openapi.py +45 -54
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/types.py +13 -4
- datamodel_code_generator-0.20.0/datamodel_code_generator/version.py +1 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/pyproject.toml +5 -7
- datamodel_code_generator-0.18.1/datamodel_code_generator/model/improts.py +0 -4
- datamodel_code_generator-0.18.1/datamodel_code_generator/version.py +0 -1
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/LICENSE +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/http.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/enum.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/pydantic/__init__.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/pydantic/base_model.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/pydantic/custom_root_type.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/pydantic/dataclass.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/pydantic/imports.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/rootmodel.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/template/Enum.jinja2 +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/template/dataclass.jinja2 +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/template/pydantic/BaseModel.jinja2 +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/template/pydantic/BaseModel_root.jinja2 +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/template/pydantic/Config.jinja2 +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/template/pydantic/dataclass.jinja2 +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/model/template/root.jinja2 +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/parser/__init__.py +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/py.typed +0 -0
- {datamodel_code_generator-0.18.1 → datamodel_code_generator-0.20.0}/datamodel_code_generator/reference.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: datamodel-code-generator
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.20.0
|
|
4
4
|
Summary: Datamodel Code Generator
|
|
5
5
|
Home-page: https://github.com/koxudaxi/datamodel-code-generator
|
|
6
6
|
License: MIT
|
|
@@ -16,12 +16,6 @@ Classifier: Programming Language :: Python :: 3.8
|
|
|
16
16
|
Classifier: Programming Language :: Python :: 3.9
|
|
17
17
|
Classifier: Programming Language :: Python :: 3.10
|
|
18
18
|
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
-
Classifier: Programming Language :: Python :: 3
|
|
20
|
-
Classifier: Programming Language :: Python :: 3.10
|
|
21
|
-
Classifier: Programming Language :: Python :: 3.11
|
|
22
|
-
Classifier: Programming Language :: Python :: 3.7
|
|
23
|
-
Classifier: Programming Language :: Python :: 3.8
|
|
24
|
-
Classifier: Programming Language :: Python :: 3.9
|
|
25
19
|
Classifier: Programming Language :: Python :: Implementation :: CPython
|
|
26
20
|
Provides-Extra: http
|
|
27
21
|
Requires-Dist: PySnooper (>=0.4.1,<2.0.0)
|
|
@@ -32,7 +26,7 @@ Requires-Dist: httpx ; extra == "http"
|
|
|
32
26
|
Requires-Dist: inflect (>=4.1.0,<6.0)
|
|
33
27
|
Requires-Dist: isort (>=4.3.21,<6.0)
|
|
34
28
|
Requires-Dist: jinja2 (>=2.10.1,<4.0)
|
|
35
|
-
Requires-Dist: openapi-spec-validator (>=0.2.8,<=0.5.
|
|
29
|
+
Requires-Dist: openapi-spec-validator (>=0.2.8,<=0.5.2)
|
|
36
30
|
Requires-Dist: packaging
|
|
37
31
|
Requires-Dist: prance (>=0.18.2,<1.0)
|
|
38
32
|
Requires-Dist: pydantic[email] (>=1.10.0,<2.0.0) ; python_version >= "3.11" and python_version < "4.0"
|
|
@@ -44,10 +38,11 @@ Description-Content-Type: text/markdown
|
|
|
44
38
|
|
|
45
39
|
# datamodel-code-generator
|
|
46
40
|
|
|
47
|
-
This code generator creates [pydantic](https://docs.pydantic.dev/) model
|
|
41
|
+
This code generator creates [pydantic](https://docs.pydantic.dev/) model, [dataclasses.dataclass](https://docs.python.org/3/library/dataclasses.html) and [typing.TypedDict](https://docs.python.org/3/library/typing.html#typing.TypedDict) from an openapi file and others.
|
|
48
42
|
|
|
49
43
|
[](https://github.com/koxudaxi/datamodel-code-generator/actions?query=workflow%3ATest)
|
|
50
44
|
[](https://pypi.python.org/pypi/datamodel-code-generator)
|
|
45
|
+
[](https://anaconda.org/conda-forge/datamodel-code-generator)
|
|
51
46
|
[](https://pepy.tech/project/datamodel-code-generator)
|
|
52
47
|
[](https://pypi.python.org/pypi/datamodel-code-generator)
|
|
53
48
|
[](https://codecov.io/gh/koxudaxi/datamodel-code-generator)
|
|
@@ -68,7 +63,7 @@ To install `datamodel-code-generator`:
|
|
|
68
63
|
$ pip install datamodel-code-generator
|
|
69
64
|
```
|
|
70
65
|
|
|
71
|
-
## Simple
|
|
66
|
+
## Simple Usage
|
|
72
67
|
You can generate models from a local file.
|
|
73
68
|
```bash
|
|
74
69
|
$ datamodel-codegen --input api.yaml --output model.py
|
|
@@ -278,14 +273,14 @@ class Apis(BaseModel):
|
|
|
278
273
|
```
|
|
279
274
|
</details>
|
|
280
275
|
|
|
281
|
-
##
|
|
282
|
-
These OSS use datamodel-code-generator to generate many models.
|
|
276
|
+
## Projects that use datamodel-code-generator
|
|
277
|
+
These OSS projects use datamodel-code-generator to generate many models. See the following linked projects for real world examples and inspiration.
|
|
283
278
|
- [Netflix/consoleme](https://github.com/Netflix/consoleme)
|
|
284
279
|
- *[How do I generate models from the Swagger specification?](https://github.com/Netflix/consoleme/blob/master/docs/gitbook/faq.md#how-do-i-generate-models-from-the-swagger-specification)*
|
|
285
280
|
- [DataDog/integrations-core](https://github.com/DataDog/integrations-core)
|
|
286
281
|
- *[Config models](https://github.com/DataDog/integrations-core/blob/master/docs/developer/meta/config-models.md)*
|
|
287
282
|
- [awslabs/aws-lambda-powertools-python](https://github.com/awslabs/aws-lambda-powertools-python)
|
|
288
|
-
- *
|
|
283
|
+
- *Recommended for [advanced-use-cases](https://awslabs.github.io/aws-lambda-powertools-python/2.6.0/utilities/parser/#advanced-use-cases) in the official documentation*
|
|
289
284
|
- [open-metadata/OpenMetadata](https://github.com/open-metadata/OpenMetadata)
|
|
290
285
|
- [Makefile](https://github.com/open-metadata/OpenMetadata/blob/main/Makefile)
|
|
291
286
|
- [airbytehq/airbyte](https://github.com/airbytehq/airbyte)
|
|
@@ -303,6 +298,7 @@ These OSS use datamodel-code-generator to generate many models. We can learn abo
|
|
|
303
298
|
## Supported output types
|
|
304
299
|
- [pydantic](https://docs.pydantic.dev/).BaseModel
|
|
305
300
|
- [dataclasses.dataclass](https://docs.python.org/3/library/dataclasses.html)
|
|
301
|
+
- [typing.TypedDict](https://docs.python.org/3/library/typing.html#typing.TypedDict)
|
|
306
302
|
|
|
307
303
|
## Installation
|
|
308
304
|
|
|
@@ -328,7 +324,7 @@ You can genearte models from a URL.
|
|
|
328
324
|
```bash
|
|
329
325
|
$ datamodel-codegen --url https://<INPUT FILE URL> --output model.py
|
|
330
326
|
```
|
|
331
|
-
This method needs
|
|
327
|
+
This method needs the [http extra option](#http-extra-option)
|
|
332
328
|
|
|
333
329
|
|
|
334
330
|
## All Command Options
|
|
@@ -339,7 +335,7 @@ usage: datamodel-codegen [-h] [--input INPUT] [--url URL]
|
|
|
339
335
|
[--http-headers HTTP_HEADER [HTTP_HEADER ...]]
|
|
340
336
|
[--http-ignore-tls]
|
|
341
337
|
[--input-file-type {auto,openapi,jsonschema,json,yaml,dict,csv}]
|
|
342
|
-
[--output-model-type {pydantic.BaseModel,dataclasses.dataclass}]
|
|
338
|
+
[--output-model-type {pydantic.BaseModel,dataclasses.dataclass,typing.TypedDict}]
|
|
343
339
|
[--openapi-scopes {schemas,paths,tags,parameters} [{schemas,paths,tags,parameters} ...]]
|
|
344
340
|
[--output OUTPUT] [--base-class BASE_CLASS]
|
|
345
341
|
[--field-constraints] [--use-annotated]
|
|
@@ -390,7 +386,7 @@ options:
|
|
|
390
386
|
certificate
|
|
391
387
|
--input-file-type {auto,openapi,jsonschema,json,yaml,dict,csv}
|
|
392
388
|
Input file type (default: auto)
|
|
393
|
-
--output-model-type {pydantic.BaseModel,dataclasses.dataclass}
|
|
389
|
+
--output-model-type {pydantic.BaseModel,dataclasses.dataclass,typing.TypedDict}
|
|
394
390
|
Output model type (default: pydantic.BaseModel)
|
|
395
391
|
--openapi-scopes {schemas,paths,tags,parameters} [{schemas,paths,tags,parameters} ...]
|
|
396
392
|
Scopes of OpenAPI model generation (default: schemas)
|
|
@@ -496,41 +492,6 @@ options:
|
|
|
496
492
|
--version show version
|
|
497
493
|
```
|
|
498
494
|
|
|
499
|
-
|
|
500
|
-
## Implemented list
|
|
501
|
-
### OpenAPI 3 and JsonSchema
|
|
502
|
-
#### DataType
|
|
503
|
-
- string (include patter/minLength/maxLenght)
|
|
504
|
-
- number (include maximum/exclusiveMaximum/minimum/exclusiveMinimum/multipleOf/le/ge)
|
|
505
|
-
- integer (include maximum/exclusiveMaximum/minimum/exclusiveMinimum/multipleOf/le/ge)
|
|
506
|
-
- boolean
|
|
507
|
-
- array
|
|
508
|
-
- object
|
|
509
|
-
|
|
510
|
-
##### String Format
|
|
511
|
-
- date
|
|
512
|
-
- datetime
|
|
513
|
-
- time
|
|
514
|
-
- password
|
|
515
|
-
- email
|
|
516
|
-
- idn-email
|
|
517
|
-
- uuid (uuid1/uuid2/uuid3/uuid4/uuid5)
|
|
518
|
-
- ipv4
|
|
519
|
-
- ipv6
|
|
520
|
-
- ipv4-network
|
|
521
|
-
- ipv6-network
|
|
522
|
-
- hostname
|
|
523
|
-
- decimal
|
|
524
|
-
|
|
525
|
-
#### Other schema
|
|
526
|
-
- enum (as enum.Enum or typing.Literal)
|
|
527
|
-
- allOf (as Multiple inheritance)
|
|
528
|
-
- anyOf (as typing.Union)
|
|
529
|
-
- oneOf (as typing.Union)
|
|
530
|
-
- $ref ([http extra](#http-extra-option) is required when resolving $ref for remote files.)
|
|
531
|
-
- $id (for [JSONSchema](https://json-schema.org/understanding-json-schema/structuring.html#the-id-property))
|
|
532
|
-
|
|
533
|
-
|
|
534
495
|
## Related projects
|
|
535
496
|
### fastapi-code-generator
|
|
536
497
|
This code generator creates [FastAPI](https://github.com/tiangolo/fastapi) app from an openapi file.
|
|
@@ -1,9 +1,10 @@
|
|
|
1
1
|
# datamodel-code-generator
|
|
2
2
|
|
|
3
|
-
This code generator creates [pydantic](https://docs.pydantic.dev/) model
|
|
3
|
+
This code generator creates [pydantic](https://docs.pydantic.dev/) model, [dataclasses.dataclass](https://docs.python.org/3/library/dataclasses.html) and [typing.TypedDict](https://docs.python.org/3/library/typing.html#typing.TypedDict) from an openapi file and others.
|
|
4
4
|
|
|
5
5
|
[](https://github.com/koxudaxi/datamodel-code-generator/actions?query=workflow%3ATest)
|
|
6
6
|
[](https://pypi.python.org/pypi/datamodel-code-generator)
|
|
7
|
+
[](https://anaconda.org/conda-forge/datamodel-code-generator)
|
|
7
8
|
[](https://pepy.tech/project/datamodel-code-generator)
|
|
8
9
|
[](https://pypi.python.org/pypi/datamodel-code-generator)
|
|
9
10
|
[](https://codecov.io/gh/koxudaxi/datamodel-code-generator)
|
|
@@ -24,7 +25,7 @@ To install `datamodel-code-generator`:
|
|
|
24
25
|
$ pip install datamodel-code-generator
|
|
25
26
|
```
|
|
26
27
|
|
|
27
|
-
## Simple
|
|
28
|
+
## Simple Usage
|
|
28
29
|
You can generate models from a local file.
|
|
29
30
|
```bash
|
|
30
31
|
$ datamodel-codegen --input api.yaml --output model.py
|
|
@@ -234,14 +235,14 @@ class Apis(BaseModel):
|
|
|
234
235
|
```
|
|
235
236
|
</details>
|
|
236
237
|
|
|
237
|
-
##
|
|
238
|
-
These OSS use datamodel-code-generator to generate many models.
|
|
238
|
+
## Projects that use datamodel-code-generator
|
|
239
|
+
These OSS projects use datamodel-code-generator to generate many models. See the following linked projects for real world examples and inspiration.
|
|
239
240
|
- [Netflix/consoleme](https://github.com/Netflix/consoleme)
|
|
240
241
|
- *[How do I generate models from the Swagger specification?](https://github.com/Netflix/consoleme/blob/master/docs/gitbook/faq.md#how-do-i-generate-models-from-the-swagger-specification)*
|
|
241
242
|
- [DataDog/integrations-core](https://github.com/DataDog/integrations-core)
|
|
242
243
|
- *[Config models](https://github.com/DataDog/integrations-core/blob/master/docs/developer/meta/config-models.md)*
|
|
243
244
|
- [awslabs/aws-lambda-powertools-python](https://github.com/awslabs/aws-lambda-powertools-python)
|
|
244
|
-
- *
|
|
245
|
+
- *Recommended for [advanced-use-cases](https://awslabs.github.io/aws-lambda-powertools-python/2.6.0/utilities/parser/#advanced-use-cases) in the official documentation*
|
|
245
246
|
- [open-metadata/OpenMetadata](https://github.com/open-metadata/OpenMetadata)
|
|
246
247
|
- [Makefile](https://github.com/open-metadata/OpenMetadata/blob/main/Makefile)
|
|
247
248
|
- [airbytehq/airbyte](https://github.com/airbytehq/airbyte)
|
|
@@ -259,6 +260,7 @@ These OSS use datamodel-code-generator to generate many models. We can learn abo
|
|
|
259
260
|
## Supported output types
|
|
260
261
|
- [pydantic](https://docs.pydantic.dev/).BaseModel
|
|
261
262
|
- [dataclasses.dataclass](https://docs.python.org/3/library/dataclasses.html)
|
|
263
|
+
- [typing.TypedDict](https://docs.python.org/3/library/typing.html#typing.TypedDict)
|
|
262
264
|
|
|
263
265
|
## Installation
|
|
264
266
|
|
|
@@ -284,7 +286,7 @@ You can genearte models from a URL.
|
|
|
284
286
|
```bash
|
|
285
287
|
$ datamodel-codegen --url https://<INPUT FILE URL> --output model.py
|
|
286
288
|
```
|
|
287
|
-
This method needs
|
|
289
|
+
This method needs the [http extra option](#http-extra-option)
|
|
288
290
|
|
|
289
291
|
|
|
290
292
|
## All Command Options
|
|
@@ -295,7 +297,7 @@ usage: datamodel-codegen [-h] [--input INPUT] [--url URL]
|
|
|
295
297
|
[--http-headers HTTP_HEADER [HTTP_HEADER ...]]
|
|
296
298
|
[--http-ignore-tls]
|
|
297
299
|
[--input-file-type {auto,openapi,jsonschema,json,yaml,dict,csv}]
|
|
298
|
-
[--output-model-type {pydantic.BaseModel,dataclasses.dataclass}]
|
|
300
|
+
[--output-model-type {pydantic.BaseModel,dataclasses.dataclass,typing.TypedDict}]
|
|
299
301
|
[--openapi-scopes {schemas,paths,tags,parameters} [{schemas,paths,tags,parameters} ...]]
|
|
300
302
|
[--output OUTPUT] [--base-class BASE_CLASS]
|
|
301
303
|
[--field-constraints] [--use-annotated]
|
|
@@ -346,7 +348,7 @@ options:
|
|
|
346
348
|
certificate
|
|
347
349
|
--input-file-type {auto,openapi,jsonschema,json,yaml,dict,csv}
|
|
348
350
|
Input file type (default: auto)
|
|
349
|
-
--output-model-type {pydantic.BaseModel,dataclasses.dataclass}
|
|
351
|
+
--output-model-type {pydantic.BaseModel,dataclasses.dataclass,typing.TypedDict}
|
|
350
352
|
Output model type (default: pydantic.BaseModel)
|
|
351
353
|
--openapi-scopes {schemas,paths,tags,parameters} [{schemas,paths,tags,parameters} ...]
|
|
352
354
|
Scopes of OpenAPI model generation (default: schemas)
|
|
@@ -452,41 +454,6 @@ options:
|
|
|
452
454
|
--version show version
|
|
453
455
|
```
|
|
454
456
|
|
|
455
|
-
|
|
456
|
-
## Implemented list
|
|
457
|
-
### OpenAPI 3 and JsonSchema
|
|
458
|
-
#### DataType
|
|
459
|
-
- string (include patter/minLength/maxLenght)
|
|
460
|
-
- number (include maximum/exclusiveMaximum/minimum/exclusiveMinimum/multipleOf/le/ge)
|
|
461
|
-
- integer (include maximum/exclusiveMaximum/minimum/exclusiveMinimum/multipleOf/le/ge)
|
|
462
|
-
- boolean
|
|
463
|
-
- array
|
|
464
|
-
- object
|
|
465
|
-
|
|
466
|
-
##### String Format
|
|
467
|
-
- date
|
|
468
|
-
- datetime
|
|
469
|
-
- time
|
|
470
|
-
- password
|
|
471
|
-
- email
|
|
472
|
-
- idn-email
|
|
473
|
-
- uuid (uuid1/uuid2/uuid3/uuid4/uuid5)
|
|
474
|
-
- ipv4
|
|
475
|
-
- ipv6
|
|
476
|
-
- ipv4-network
|
|
477
|
-
- ipv6-network
|
|
478
|
-
- hostname
|
|
479
|
-
- decimal
|
|
480
|
-
|
|
481
|
-
#### Other schema
|
|
482
|
-
- enum (as enum.Enum or typing.Literal)
|
|
483
|
-
- allOf (as Multiple inheritance)
|
|
484
|
-
- anyOf (as typing.Union)
|
|
485
|
-
- oneOf (as typing.Union)
|
|
486
|
-
- $ref ([http extra](#http-extra-option) is required when resolving $ref for remote files.)
|
|
487
|
-
- $id (for [JSONSchema](https://json-schema.org/understanding-json-schema/structuring.html#the-id-property))
|
|
488
|
-
|
|
489
|
-
|
|
490
457
|
## Related projects
|
|
491
458
|
### fastapi-code-generator
|
|
492
459
|
This code generator creates [FastAPI](https://github.com/tiangolo/fastapi) app from an openapi file.
|
|
@@ -220,6 +220,7 @@ RAW_DATA_TYPES: List[InputFileType] = [
|
|
|
220
220
|
class DataModelType(Enum):
|
|
221
221
|
PydanticBaseModel = 'pydantic.BaseModel'
|
|
222
222
|
DataclassesDataclass = 'dataclasses.dataclass'
|
|
223
|
+
TypingTypedDict = 'typing.TypedDict'
|
|
223
224
|
|
|
224
225
|
|
|
225
226
|
class OpenAPIScope(Enum):
|
|
@@ -314,6 +315,7 @@ def generate(
|
|
|
314
315
|
capitalise_enum_members: bool = False,
|
|
315
316
|
keep_model_order: bool = False,
|
|
316
317
|
custom_file_header: Optional[str] = None,
|
|
318
|
+
custom_file_header_path: Optional[Path] = None,
|
|
317
319
|
) -> None:
|
|
318
320
|
remote_text_cache: DefaultPutDict[str, str] = DefaultPutDict()
|
|
319
321
|
if isinstance(input_, str):
|
|
@@ -397,7 +399,7 @@ def generate(
|
|
|
397
399
|
|
|
398
400
|
from datamodel_code_generator.model import get_data_model_types
|
|
399
401
|
|
|
400
|
-
data_model_types = get_data_model_types(output_model_type)
|
|
402
|
+
data_model_types = get_data_model_types(output_model_type, target_python_version)
|
|
401
403
|
parser = parser_class(
|
|
402
404
|
source=input_text or input_,
|
|
403
405
|
data_model_type=data_model_types.data_model,
|
|
@@ -427,7 +429,9 @@ def generate(
|
|
|
427
429
|
use_field_description=use_field_description,
|
|
428
430
|
use_default_kwarg=use_default_kwarg,
|
|
429
431
|
reuse_model=reuse_model,
|
|
430
|
-
enum_field_as_literal=
|
|
432
|
+
enum_field_as_literal=LiteralType.All
|
|
433
|
+
if output_model_type == DataModelType.TypingTypedDict
|
|
434
|
+
else enum_field_as_literal,
|
|
431
435
|
use_one_literal_as_default=use_one_literal_as_default,
|
|
432
436
|
set_default_enum_member=set_default_enum_member,
|
|
433
437
|
use_subclass_enum=use_subclass_enum,
|
|
@@ -488,6 +492,9 @@ def generate(
|
|
|
488
492
|
|
|
489
493
|
timestamp = datetime.now(timezone.utc).replace(microsecond=0).isoformat()
|
|
490
494
|
|
|
495
|
+
if custom_file_header is None and custom_file_header_path:
|
|
496
|
+
custom_file_header = custom_file_header_path.read_text(encoding=encoding)
|
|
497
|
+
|
|
491
498
|
header = """\
|
|
492
499
|
# generated by datamodel-codegen:
|
|
493
500
|
# filename: {}"""
|
|
@@ -497,8 +504,7 @@ def generate(
|
|
|
497
504
|
header += f'\n# version: {get_version()}'
|
|
498
505
|
|
|
499
506
|
file: Optional[IO[Any]]
|
|
500
|
-
for path,
|
|
501
|
-
body, filename = body_and_filename
|
|
507
|
+
for path, (body, filename) in modules.items():
|
|
502
508
|
if path is None:
|
|
503
509
|
file = None
|
|
504
510
|
else:
|
|
@@ -433,6 +433,15 @@ arg_parser.add_argument(
|
|
|
433
433
|
arg_parser.add_argument(
|
|
434
434
|
'--custom-file-header', help='Custom file header', type=str, default=None
|
|
435
435
|
)
|
|
436
|
+
|
|
437
|
+
arg_parser.add_argument(
|
|
438
|
+
'--custom-file-header-path',
|
|
439
|
+
help='Custom file header file path',
|
|
440
|
+
default=None,
|
|
441
|
+
type=str,
|
|
442
|
+
)
|
|
443
|
+
|
|
444
|
+
|
|
436
445
|
arg_parser.add_argument('--version', help='show version', action='store_true')
|
|
437
446
|
|
|
438
447
|
|
|
@@ -448,7 +457,9 @@ class Config(BaseModel):
|
|
|
448
457
|
return value
|
|
449
458
|
return cast(TextIOBase, Path(value).expanduser().resolve().open('rt'))
|
|
450
459
|
|
|
451
|
-
@validator(
|
|
460
|
+
@validator(
|
|
461
|
+
'input', 'output', 'custom_template_dir', 'custom_file_header_path', pre=True
|
|
462
|
+
)
|
|
452
463
|
def validate_path(cls, value: Any) -> Optional[Path]:
|
|
453
464
|
if value is None or isinstance(value, Path):
|
|
454
465
|
return value # pragma: no cover
|
|
@@ -488,6 +499,14 @@ class Config(BaseModel):
|
|
|
488
499
|
)
|
|
489
500
|
return values
|
|
490
501
|
|
|
502
|
+
@root_validator
|
|
503
|
+
def validate_custom_file_header(cls, values: Dict[str, Any]) -> Dict[str, Any]:
|
|
504
|
+
if values.get('custom_file_header') and values.get('custom_file_header_path'):
|
|
505
|
+
raise Error(
|
|
506
|
+
'`--custom_file_header_path` can not be used with `--custom_file_header`.'
|
|
507
|
+
) # pragma: no cover
|
|
508
|
+
return values
|
|
509
|
+
|
|
491
510
|
# Pydantic 1.5.1 doesn't support each_item=True correctly
|
|
492
511
|
@validator('http_headers', pre=True)
|
|
493
512
|
def validate_http_headers(cls, value: Any) -> Optional[List[Tuple[str, str]]]:
|
|
@@ -583,6 +602,7 @@ class Config(BaseModel):
|
|
|
583
602
|
capitalise_enum_members: bool = False
|
|
584
603
|
keep_model_order: bool = False
|
|
585
604
|
custom_file_header: Optional[str] = None
|
|
605
|
+
custom_file_header_path: Optional[Path] = None
|
|
586
606
|
|
|
587
607
|
def merge_args(self, args: Namespace) -> None:
|
|
588
608
|
set_args = {
|
|
@@ -742,6 +762,8 @@ def main(args: Optional[Sequence[str]] = None) -> Exit:
|
|
|
742
762
|
remove_special_field_name_prefix=config.remove_special_field_name_prefix,
|
|
743
763
|
capitalise_enum_members=config.capitalise_enum_members,
|
|
744
764
|
keep_model_order=config.keep_model_order,
|
|
765
|
+
custom_file_header=config.custom_file_header,
|
|
766
|
+
custom_file_header_path=config.custom_file_header_path,
|
|
745
767
|
)
|
|
746
768
|
return Exit.OK
|
|
747
769
|
except InvalidClassNameError as e:
|
|
@@ -9,6 +9,8 @@ import black
|
|
|
9
9
|
import isort
|
|
10
10
|
import toml
|
|
11
11
|
|
|
12
|
+
from datamodel_code_generator import cached_property
|
|
13
|
+
|
|
12
14
|
|
|
13
15
|
class PythonVersion(Enum):
|
|
14
16
|
PY_36 = '3.6'
|
|
@@ -18,13 +20,41 @@ class PythonVersion(Enum):
|
|
|
18
20
|
PY_310 = '3.10'
|
|
19
21
|
PY_311 = '3.11'
|
|
20
22
|
|
|
23
|
+
@cached_property
|
|
24
|
+
def _is_py_38_or_later(self) -> bool: # pragma: no cover
|
|
25
|
+
return self.value not in {self.PY_36.value, self.PY_37.value} # type: ignore
|
|
26
|
+
|
|
27
|
+
@cached_property
|
|
28
|
+
def _is_py_39_or_later(self) -> bool: # pragma: no cover
|
|
29
|
+
return self.value not in {self.PY_36.value, self.PY_37.value, self.PY_38.value} # type: ignore
|
|
30
|
+
|
|
31
|
+
@cached_property
|
|
32
|
+
def _is_py_310_or_later(self) -> bool: # pragma: no cover
|
|
33
|
+
return self.value not in {self.PY_36.value, self.PY_37.value, self.PY_38.value, self.PY_39.value} # type: ignore
|
|
34
|
+
|
|
35
|
+
@cached_property
|
|
36
|
+
def _is_py_311_or_later(self) -> bool: # pragma: no cover
|
|
37
|
+
return self.value not in {self.PY_36.value, self.PY_37.value, self.PY_38.value, self.PY_39.value, self.PY_310.value} # type: ignore
|
|
38
|
+
|
|
21
39
|
@property
|
|
22
40
|
def has_literal_type(self) -> bool:
|
|
23
|
-
return self.
|
|
41
|
+
return self._is_py_38_or_later
|
|
24
42
|
|
|
25
43
|
@property
|
|
26
44
|
def has_union_operator(self) -> bool: # pragma: no cover
|
|
27
|
-
return self.
|
|
45
|
+
return self._is_py_310_or_later
|
|
46
|
+
|
|
47
|
+
@property
|
|
48
|
+
def has_annotated_type(self) -> bool:
|
|
49
|
+
return self._is_py_39_or_later
|
|
50
|
+
|
|
51
|
+
@property
|
|
52
|
+
def has_typed_dict(self) -> bool:
|
|
53
|
+
return self._is_py_38_or_later
|
|
54
|
+
|
|
55
|
+
@property
|
|
56
|
+
def has_typed_dict_non_required(self) -> bool:
|
|
57
|
+
return self._is_py_311_or_later
|
|
28
58
|
|
|
29
59
|
|
|
30
60
|
if TYPE_CHECKING:
|
|
@@ -61,6 +61,7 @@ class Imports(DefaultDict[Optional[str], Set[str]]):
|
|
|
61
61
|
|
|
62
62
|
|
|
63
63
|
IMPORT_ANNOTATED = Import.from_full_path('typing.Annotated')
|
|
64
|
+
IMPORT_ANNOTATED_BACKPORT = Import.from_full_path('typing_extensions.Annotated')
|
|
64
65
|
IMPORT_ANY = Import.from_full_path('typing.Any')
|
|
65
66
|
IMPORT_LIST = Import.from_full_path('typing.List')
|
|
66
67
|
IMPORT_UNION = Import.from_full_path('typing.Union')
|
|
@@ -6,7 +6,7 @@ from ..types import DataTypeManager as DataTypeManagerABC
|
|
|
6
6
|
from .base import ConstraintsBase, DataModel, DataModelFieldBase
|
|
7
7
|
|
|
8
8
|
if TYPE_CHECKING:
|
|
9
|
-
from .. import DataModelType
|
|
9
|
+
from .. import DataModelType, PythonVersion
|
|
10
10
|
|
|
11
11
|
|
|
12
12
|
class DataModelSet(NamedTuple):
|
|
@@ -17,9 +17,11 @@ class DataModelSet(NamedTuple):
|
|
|
17
17
|
dump_resolve_reference_action: Optional[Callable[[Iterable[str]], str]]
|
|
18
18
|
|
|
19
19
|
|
|
20
|
-
def get_data_model_types(
|
|
20
|
+
def get_data_model_types(
|
|
21
|
+
data_model_type: DataModelType, target_python_version: PythonVersion
|
|
22
|
+
) -> DataModelSet:
|
|
21
23
|
from .. import DataModelType
|
|
22
|
-
from . import dataclass, pydantic, rootmodel
|
|
24
|
+
from . import dataclass, pydantic, rootmodel, typed_dict
|
|
23
25
|
from .types import DataTypeManager
|
|
24
26
|
|
|
25
27
|
if data_model_type == DataModelType.PydanticBaseModel:
|
|
@@ -38,6 +40,18 @@ def get_data_model_types(data_model_type: DataModelType) -> DataModelSet:
|
|
|
38
40
|
data_type_manager=DataTypeManager,
|
|
39
41
|
dump_resolve_reference_action=None,
|
|
40
42
|
)
|
|
43
|
+
elif data_model_type == DataModelType.TypingTypedDict:
|
|
44
|
+
return DataModelSet(
|
|
45
|
+
data_model=typed_dict.TypedDict
|
|
46
|
+
if target_python_version.has_typed_dict
|
|
47
|
+
else typed_dict.TypedDictBackport,
|
|
48
|
+
root_model=rootmodel.RootModel,
|
|
49
|
+
field_model=typed_dict.DataModelField
|
|
50
|
+
if target_python_version.has_typed_dict_non_required
|
|
51
|
+
else typed_dict.DataModelFieldBackport,
|
|
52
|
+
data_type_manager=DataTypeManager,
|
|
53
|
+
dump_resolve_reference_action=None,
|
|
54
|
+
)
|
|
41
55
|
raise ValueError(
|
|
42
56
|
f'{data_model_type} is unsupported data model type'
|
|
43
57
|
) # pragma: no cover
|
|
@@ -25,6 +25,7 @@ from jinja2 import Environment, FileSystemLoader, Template
|
|
|
25
25
|
from datamodel_code_generator import cached_property
|
|
26
26
|
from datamodel_code_generator.imports import (
|
|
27
27
|
IMPORT_ANNOTATED,
|
|
28
|
+
IMPORT_ANNOTATED_BACKPORT,
|
|
28
29
|
IMPORT_OPTIONAL,
|
|
29
30
|
IMPORT_UNION,
|
|
30
31
|
Import,
|
|
@@ -125,7 +126,12 @@ class DataModelFieldBase(_BaseModel):
|
|
|
125
126
|
) and not self.data_type.use_union_operator:
|
|
126
127
|
imports.append((IMPORT_OPTIONAL,))
|
|
127
128
|
if self.use_annotated:
|
|
128
|
-
|
|
129
|
+
import_annotated = (
|
|
130
|
+
IMPORT_ANNOTATED
|
|
131
|
+
if self.data_type.python_version.has_annotated_type
|
|
132
|
+
else IMPORT_ANNOTATED_BACKPORT
|
|
133
|
+
)
|
|
134
|
+
imports.append((import_annotated,))
|
|
129
135
|
return chain_as_tuple(*imports)
|
|
130
136
|
|
|
131
137
|
@property
|
|
@@ -12,6 +12,13 @@ from datamodel_code_generator.reference import Reference
|
|
|
12
12
|
from datamodel_code_generator.types import chain_as_tuple
|
|
13
13
|
|
|
14
14
|
|
|
15
|
+
def _has_field_assignment(field: DataModelFieldBase) -> bool:
|
|
16
|
+
return bool(field.field) or not (
|
|
17
|
+
field.required
|
|
18
|
+
or (field.represented_default == 'None' and field.strip_default_none)
|
|
19
|
+
)
|
|
20
|
+
|
|
21
|
+
|
|
15
22
|
class DataClass(DataModel):
|
|
16
23
|
TEMPLATE_FILE_PATH: ClassVar[str] = 'dataclass.jinja2'
|
|
17
24
|
DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = (IMPORT_DATACLASS,)
|
|
@@ -34,7 +41,7 @@ class DataClass(DataModel):
|
|
|
34
41
|
) -> None:
|
|
35
42
|
super().__init__(
|
|
36
43
|
reference=reference,
|
|
37
|
-
fields=fields,
|
|
44
|
+
fields=sorted(fields, key=_has_field_assignment, reverse=False),
|
|
38
45
|
decorators=decorators,
|
|
39
46
|
base_classes=base_classes,
|
|
40
47
|
custom_base_class=custom_base_class,
|
|
@@ -46,7 +53,6 @@ class DataClass(DataModel):
|
|
|
46
53
|
default=default,
|
|
47
54
|
nullable=nullable,
|
|
48
55
|
)
|
|
49
|
-
self.fields.sort(key=str, reverse=False)
|
|
50
56
|
|
|
51
57
|
@property
|
|
52
58
|
def imports(self) -> Tuple[Import, ...]:
|
|
@@ -0,0 +1,8 @@
|
|
|
1
|
+
from datamodel_code_generator.imports import Import
|
|
2
|
+
|
|
3
|
+
IMPORT_DATACLASS = Import.from_full_path('dataclasses.dataclass')
|
|
4
|
+
IMPORT_FIELD = Import.from_full_path('dataclasses.field')
|
|
5
|
+
IMPORT_TYPED_DICT = Import.from_full_path('typing.TypedDict')
|
|
6
|
+
IMPORT_TYPED_DICT_BACKPORT = Import.from_full_path('typing_extensions.TypedDict')
|
|
7
|
+
IMPORT_NOT_REQUIRED = Import.from_full_path('typing.NotRequired')
|
|
8
|
+
IMPORT_NOT_REQUIRED_BACKPORT = Import.from_full_path('typing_extensions.NotRequired')
|
|
@@ -93,7 +93,7 @@ def type_map_factory(
|
|
|
93
93
|
Types.ipv6_network: data_type.from_import(IMPORT_IPV6NETWORKS),
|
|
94
94
|
Types.boolean: data_type(type='bool'),
|
|
95
95
|
Types.object: data_type.from_import(IMPORT_ANY, is_dict=True),
|
|
96
|
-
Types.null: data_type
|
|
96
|
+
Types.null: data_type(type='None'),
|
|
97
97
|
Types.array: data_type.from_import(IMPORT_ANY, is_list=True),
|
|
98
98
|
Types.any: data_type.from_import(IMPORT_ANY),
|
|
99
99
|
}
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
class {{ class_name }}({{ base_class }}):
|
|
2
|
+
{%- if description %}
|
|
3
|
+
"""
|
|
4
|
+
{{ description | indent(4) }}
|
|
5
|
+
"""
|
|
6
|
+
{%- endif %}
|
|
7
|
+
{%- if not fields and not description %}
|
|
8
|
+
pass
|
|
9
|
+
{%- endif %}
|
|
10
|
+
{%- for field in fields %}
|
|
11
|
+
{{ field.name }}: {{ field.type_hint }}
|
|
12
|
+
{%- if field.docstring %}
|
|
13
|
+
"""
|
|
14
|
+
{{ field.docstring | indent(4) }}
|
|
15
|
+
"""
|
|
16
|
+
{%- endif %}
|
|
17
|
+
{%- endfor -%}
|
datamodel_code_generator-0.20.0/datamodel_code_generator/model/template/TypedDictFunction.jinja2
ADDED
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
{%- if description %}
|
|
2
|
+
"""
|
|
3
|
+
{{ description | indent(4) }}
|
|
4
|
+
"""
|
|
5
|
+
{%- endif %}
|
|
6
|
+
{{ class_name }} = TypedDict('{{ class_name }}', {
|
|
7
|
+
{%- for field in all_fields %}
|
|
8
|
+
'{{ field.key }}': {{ field.type_hint }},
|
|
9
|
+
{%- if field.docstring %}
|
|
10
|
+
"""
|
|
11
|
+
{{ field.docstring | indent(4) }}
|
|
12
|
+
"""
|
|
13
|
+
{%- endif %}
|
|
14
|
+
{%- endfor -%}
|
|
15
|
+
})
|
|
16
|
+
|