mirror of
https://github.com/koxudaxi/datamodel-code-generator.git
synced 2024-03-18 14:54:37 +03:00
* Support custom formatters for CodeFormatter * Add custom formatters argument * Add graphql to docs/supported-data-types.md * Add test custom formatter for custom-scalar-types.graphql; * Run poetry run scripts/format.sh * Add simple doc
476 lines
14 KiB
Python
476 lines
14 KiB
Python
from __future__ import annotations
|
|
|
|
import locale
|
|
from argparse import ArgumentParser, FileType, HelpFormatter, Namespace
|
|
from operator import attrgetter
|
|
from typing import TYPE_CHECKING
|
|
|
|
from datamodel_code_generator import DataModelType, InputFileType, OpenAPIScope
|
|
from datamodel_code_generator.format import PythonVersion
|
|
from datamodel_code_generator.parser import LiteralType
|
|
from datamodel_code_generator.types import StrictTypes
|
|
|
|
if TYPE_CHECKING:
|
|
from argparse import Action
|
|
from typing import Iterable, Optional
|
|
|
|
DEFAULT_ENCODING = locale.getpreferredencoding()
|
|
|
|
namespace = Namespace(no_color=False)
|
|
|
|
|
|
class SortingHelpFormatter(HelpFormatter):
|
|
def _bold_cyan(self, text: str) -> str:
|
|
return f'\x1b[36;1m{text}\x1b[0m'
|
|
|
|
def add_arguments(self, actions: Iterable[Action]) -> None:
|
|
actions = sorted(actions, key=attrgetter('option_strings'))
|
|
super().add_arguments(actions)
|
|
|
|
def start_section(self, heading: Optional[str]) -> None:
|
|
return super().start_section(
|
|
heading if namespace.no_color or not heading else self._bold_cyan(heading)
|
|
)
|
|
|
|
|
|
arg_parser = ArgumentParser(
|
|
usage='\n datamodel-codegen [options]',
|
|
description='Generate Python data models from schema definitions or structured data',
|
|
formatter_class=SortingHelpFormatter,
|
|
add_help=False,
|
|
)
|
|
|
|
base_options = arg_parser.add_argument_group('Options')
|
|
typing_options = arg_parser.add_argument_group('Typing customization')
|
|
field_options = arg_parser.add_argument_group('Field customization')
|
|
model_options = arg_parser.add_argument_group('Model customization')
|
|
template_options = arg_parser.add_argument_group('Template customization')
|
|
openapi_options = arg_parser.add_argument_group('OpenAPI-only options')
|
|
general_options = arg_parser.add_argument_group('General options')
|
|
|
|
# ======================================================================================
|
|
# Base options for input/output
|
|
# ======================================================================================
|
|
base_options.add_argument(
|
|
'--http-headers',
|
|
nargs='+',
|
|
metavar='HTTP_HEADER',
|
|
help='Set headers in HTTP requests to the remote host. (example: "Authorization: Basic dXNlcjpwYXNz")',
|
|
)
|
|
base_options.add_argument(
|
|
'--http-ignore-tls',
|
|
help="Disable verification of the remote host's TLS certificate",
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
base_options.add_argument(
|
|
'--input',
|
|
help='Input file/directory (default: stdin)',
|
|
)
|
|
base_options.add_argument(
|
|
'--input-file-type',
|
|
help='Input file type (default: auto)',
|
|
choices=[i.value for i in InputFileType],
|
|
)
|
|
base_options.add_argument(
|
|
'--output',
|
|
help='Output file (default: stdout)',
|
|
)
|
|
base_options.add_argument(
|
|
'--output-model-type',
|
|
help='Output model type (default: pydantic.BaseModel)',
|
|
choices=[i.value for i in DataModelType],
|
|
)
|
|
base_options.add_argument(
|
|
'--url',
|
|
help='Input file URL. `--input` is ignored when `--url` is used',
|
|
)
|
|
|
|
# ======================================================================================
|
|
# Customization options for generated models
|
|
# ======================================================================================
|
|
model_options.add_argument(
|
|
'--allow-extra-fields',
|
|
help='Allow to pass extra fields, if this flag is not passed, extra fields are forbidden.',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--allow-population-by-field-name',
|
|
help='Allow population by field name',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--class-name',
|
|
help='Set class name of root model',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--collapse-root-models',
|
|
action='store_true',
|
|
default=None,
|
|
help='Models generated with a root-type field will be merged'
|
|
'into the models using that root-type model',
|
|
)
|
|
model_options.add_argument(
|
|
'--disable-appending-item-suffix',
|
|
help='Disable appending `Item` suffix to model name in an array',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--disable-timestamp',
|
|
help='Disable timestamp on file headers',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--enable-faux-immutability',
|
|
help='Enable faux immutability',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--enable-version-header',
|
|
help='Enable package version on file headers',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--keep-model-order',
|
|
help="Keep generated models' order",
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--reuse-model',
|
|
help='Re-use models on the field when a module has the model with the same content',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--target-python-version',
|
|
help='target python version (default: 3.7)',
|
|
choices=[v.value for v in PythonVersion],
|
|
)
|
|
model_options.add_argument(
|
|
'--use-schema-description',
|
|
help='Use schema description to populate class docstring',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
model_options.add_argument(
|
|
'--use-title-as-name',
|
|
help='use titles as class names of models',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
|
|
# ======================================================================================
|
|
# Typing options for generated models
|
|
# ======================================================================================
|
|
typing_options.add_argument(
|
|
'--base-class',
|
|
help='Base Class (default: pydantic.BaseModel)',
|
|
type=str,
|
|
)
|
|
typing_options.add_argument(
|
|
'--enum-field-as-literal',
|
|
help='Parse enum field as literal. '
|
|
'all: all enum field type are Literal. '
|
|
'one: field type is Literal when an enum has only one possible value',
|
|
choices=[lt.value for lt in LiteralType],
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--field-constraints',
|
|
help='Use field constraints and not con* annotations',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--set-default-enum-member',
|
|
help='Set enum members as default values for enum field',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--strict-types',
|
|
help='Use strict types',
|
|
choices=[t.value for t in StrictTypes],
|
|
nargs='+',
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-annotated',
|
|
help='Use typing.Annotated for Field(). Also, `--field-constraints` option will be enabled.',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-generic-container-types',
|
|
help='Use generic container types for type hinting (typing.Sequence, typing.Mapping). '
|
|
'If `--use-standard-collections` option is set, then import from collections.abc instead of typing',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-non-positive-negative-number-constrained-types',
|
|
help='Use the Non{Positive,Negative}{FloatInt} types instead of the corresponding con* constrained types.',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-one-literal-as-default',
|
|
help='Use one literal as default value for one literal field',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-standard-collections',
|
|
help='Use standard collections for type hinting (list, dict)',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-subclass-enum',
|
|
help='Define Enum class as subclass with field type when enum has type (int, float, bytes, str)',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-union-operator',
|
|
help='Use | operator for Union type (PEP 604).',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
typing_options.add_argument(
|
|
'--use-unique-items-as-set',
|
|
help='define field type as `set` when the field attribute has `uniqueItems`',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
|
|
# ======================================================================================
|
|
# Customization options for generated model fields
|
|
# ======================================================================================
|
|
field_options.add_argument(
|
|
'--capitalise-enum-members',
|
|
'--capitalize-enum-members',
|
|
help='Capitalize field names on enum',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--empty-enum-field-name',
|
|
help='Set field name when enum value is empty (default: `_`)',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--field-extra-keys',
|
|
help='Add extra keys to field parameters',
|
|
type=str,
|
|
nargs='+',
|
|
)
|
|
field_options.add_argument(
|
|
'--field-extra-keys-without-x-prefix',
|
|
help='Add extra keys with `x-` prefix to field parameters. The extra keys are stripped of the `x-` prefix.',
|
|
type=str,
|
|
nargs='+',
|
|
)
|
|
field_options.add_argument(
|
|
'--field-include-all-keys',
|
|
help='Add all keys to field parameters',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--force-optional',
|
|
help='Force optional for required fields',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--original-field-name-delimiter',
|
|
help='Set delimiter to convert to snake case. This option only can be used with --snake-case-field (default: `_` )',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--remove-special-field-name-prefix',
|
|
help='Remove field name prefix if it has a special meaning e.g. underscores',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--snake-case-field',
|
|
help='Change camel-case field name to snake-case',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--special-field-name-prefix',
|
|
help="Set field name prefix when first character can't be used as Python field name (default: `field`)",
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--strip-default-none',
|
|
help='Strip default None on fields',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--use-default',
|
|
help='Use default value even if a field is required',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--use-default-kwarg',
|
|
action='store_true',
|
|
help='Use `default=` instead of a positional argument for Fields that have default values.',
|
|
default=None,
|
|
)
|
|
field_options.add_argument(
|
|
'--use-field-description',
|
|
help='Use schema description to populate field docstring',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
|
|
# ======================================================================================
|
|
# Options for templating output
|
|
# ======================================================================================
|
|
template_options.add_argument(
|
|
'--aliases',
|
|
help='Alias mapping file',
|
|
type=FileType('rt'),
|
|
)
|
|
template_options.add_argument(
|
|
'--custom-file-header',
|
|
help='Custom file header',
|
|
type=str,
|
|
default=None,
|
|
)
|
|
template_options.add_argument(
|
|
'--custom-file-header-path',
|
|
help='Custom file header file path',
|
|
default=None,
|
|
type=str,
|
|
)
|
|
template_options.add_argument(
|
|
'--custom-template-dir',
|
|
help='Custom template directory',
|
|
type=str,
|
|
)
|
|
template_options.add_argument(
|
|
'--encoding',
|
|
help=f'The encoding of input and output (default: {DEFAULT_ENCODING})',
|
|
default=None,
|
|
)
|
|
template_options.add_argument(
|
|
'--extra-template-data',
|
|
help='Extra template data',
|
|
type=FileType('rt'),
|
|
)
|
|
template_options.add_argument(
|
|
'--use-double-quotes',
|
|
action='store_true',
|
|
default=None,
|
|
help='Model generated with double quotes. Single quotes or '
|
|
'your black config skip_string_normalization value will be used without this option.',
|
|
)
|
|
template_options.add_argument(
|
|
'--wrap-string-literal',
|
|
help='Wrap string literal by using black `experimental-string-processing` option (require black 20.8b0 or later)',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
base_options.add_argument(
|
|
'--additional-imports',
|
|
help='Custom imports for output (delimited list input). For example "datetime.date,datetime.datetime"',
|
|
type=str,
|
|
default=None,
|
|
)
|
|
base_options.add_argument(
|
|
'--custom-formatters',
|
|
help='List of modules with custom formatter (delimited list input).',
|
|
type=str,
|
|
default=None,
|
|
)
|
|
template_options.add_argument(
|
|
'--custom-formatters-kwargs',
|
|
help='A file with kwargs for custom formatters.',
|
|
type=FileType('rt'),
|
|
)
|
|
|
|
# ======================================================================================
|
|
# Options specific to OpenAPI input schemas
|
|
# ======================================================================================
|
|
openapi_options.add_argument(
|
|
'--openapi-scopes',
|
|
help='Scopes of OpenAPI model generation (default: schemas)',
|
|
choices=[o.value for o in OpenAPIScope],
|
|
nargs='+',
|
|
default=None,
|
|
)
|
|
openapi_options.add_argument(
|
|
'--strict-nullable',
|
|
help='Treat default field as a non-nullable field (Only OpenAPI)',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
openapi_options.add_argument(
|
|
'--use-operation-id-as-name',
|
|
help='use operation id of OpenAPI as class names of models',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
openapi_options.add_argument(
|
|
'--validation',
|
|
help='Deprecated: Enable validation (Only OpenAPI). this option is deprecated. it will be removed in future '
|
|
'releases',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
|
|
# ======================================================================================
|
|
# General options
|
|
# ======================================================================================
|
|
general_options.add_argument(
|
|
'--debug',
|
|
help='show debug message (require "debug". `$ pip install \'datamodel-code-generator[debug]\'`)',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
general_options.add_argument(
|
|
'--disable-warnings',
|
|
help='disable warnings',
|
|
action='store_true',
|
|
default=None,
|
|
)
|
|
general_options.add_argument(
|
|
'-h',
|
|
'--help',
|
|
action='help',
|
|
default='==SUPPRESS==',
|
|
help='show this help message and exit',
|
|
)
|
|
general_options.add_argument(
|
|
'--no-color',
|
|
action='store_true',
|
|
default=False,
|
|
help='disable colorized output',
|
|
)
|
|
general_options.add_argument(
|
|
'--version',
|
|
action='store_true',
|
|
help='show version',
|
|
)
|
|
|
|
|
|
__all__ = [
|
|
'arg_parser',
|
|
'DEFAULT_ENCODING',
|
|
'namespace',
|
|
]
|