Replies: 2 comments
-
Linked discussion about custom formatters from #1733 |
Beta Was this translation helpful? Give feedback.
-
My ideas about features for version 1 (in addition to those listed above)Custom formattersa) Creating an abstract class for Formatter and creating a runner for default formatters and custom formatters. For example from datamodel_code_generator.formatter.base import BaseCodeFormatter
class CustomHeaderCodeFormatter(BaseCodeFormatter):
formatter_name: ClassVar[str] = "custom"
def __init__(self, formatter_kwargs: Dict[str, Any]) -> None:
super().__init__(formatter_kwargs=formatter_kwargs)
default_header = "my header"
self.header: str = self.formatter_kwargs.get("header", default_header)
def apply(self, code: str) -> str:
return f'# {self.header}\\n{code}'
formatter_kwargs = {"header": "formatted with CustomHeaderCodeFormatter"}
formatter = CustomHeaderCodeFormatter(formatter_kwargs)
code = '''x = 1\ny = 2'''
print(formatter.apply(code))
"""
# formatted with CustomHeaderCodeFormatter
x = 1
y = 2
""" Example for a runner runner = CodeFormattersRunner(
default_formatter=['black', 'isort'],
disable_default_formatter=False,
custom_formatters=["my_package.my_sub_package.CustomHeaderCodeFormatter"],
custom_formatters_kwargs={
'custom': {
'header': 'formatted with CustomHeaderCodeFormatter',
}
}
)
runner.format_code("...")
# running black
# running isort
# running custom This point realization in the PR 1746. b) Running custom formatters in different step of generate lifecycle like this https://the-guild.dev/graphql/codegen/docs/config-reference/lifecycle-hooks. First of all, these are For example, a formatter for adding a license header (after adding a Custom DataTypeCreating a simple abstract data type. class _BaseDataType(ABC):
"""An abstract base data type."""
description: Optional[str]
def __init__(self, description: Optional[str] = None, *args: Any, **kwargs: Any) -> None:
self.description = description
class _BaseRenderingDataType(_BaseDataType):
TEMPLATE_FILE_PATH: ClassVar[str] = ''
DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = ()
custom_template_dir: Optional[Path]
extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]]
# like your `datamodel_code_generator.model.base.TemplateBase`
# and this class has imports methods. reflections: class ScalarDataType(_BaseRenderingDataType):
TEMPLATE_FILE_PATH: ClassVar[str] = 'Scalar.jinja2'
DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = (IMPORT_TYPE_ALIAS,)
def __init__(
self,
*,
reference: Reference,
custom_template_dir: Optional[Path] = None,
extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
description: Optional[str] = None,
...
):
# not needs for `fields` field
class DataModel(_BaseRenderingDataType):
# classic base `datamodel_code_generator` data model
class PythonModule(_BaseRenderingDataType):
TEMPLATE_FILE_PATH: ClassVar[str] = 'PythonModule.jinja2'
DEFAULT_IMPORTS: ClassVar[Tuple[Import, ...]] = ()
def __init__(
self,
*,
reference: Reference,
fields: List[DataModelFieldBase],
custom_template_dir: Optional[Path] = None,
extra_template_data: Optional[DefaultDict[str, Dict[str, Any]]] = None,
description: Optional[str] = None,
models: List[DataModel] = None,
functions: List[PythonFunctionDataType] = None,
...
): And need creating a guide for creating custom data type with examples. For example, we can create class for rendering of python classes for FastAPI client (like your Developer will can create custom data types and custom templates for his problems. Custom parsersNeed creating api for creating custom parsers outside datamodel_code_generator. The process of adding a new parser to the package can take a significant amount of time. Main idea: using parsed modules as result of method. Implementation details later |
Beta Was this translation helpful? Give feedback.
-
We have an issue for the blocker of the V1 Release.
We can talk about the details and any opinions here.
Beta Was this translation helpful? Give feedback.
All reactions