-
-
Notifications
You must be signed in to change notification settings - Fork 296
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Feature request: timedelta support #1624
Labels
enhancement
New feature or request
Comments
also having this problem and came across this issue - import typing as ty
import importlib
import json
from pathlib import Path
from tempfile import TemporaryDirectory
from datamodel_code_generator import InputFileType, generate, DataModelType
from pydantic import BaseModel
import sys
def pydantic_model_from_json_schema(json_schema: str) -> ty.Type[BaseModel]:
load = json_schema["title"] if "title" in json_schema else "Model"
with TemporaryDirectory() as temporary_directory_name:
temporary_directory = Path(temporary_directory_name)
file_path = "model.py"
module_name = file_path.split(".")[0]
output = Path(temporary_directory / file_path)
generate(
json.dumps(json_schema),
input_file_type=InputFileType.JsonSchema,
input_filename="example.json",
output=output,
output_model_type=DataModelType.PydanticV2BaseModel,
)
spec = importlib.util.spec_from_file_location(module_name, output)
module = importlib.util.module_from_spec(spec)
sys.modules[module_name] = module
spec.loader.exec_module(module)
return getattr(module, load)
schema = {
"title": "Test",
"type": "object",
"properties": {
"a_int": {
"default": 1,
"title": "A Int",
"type": "integer"
},
"i_duration": {
"default": "PT2H33M3S",
"format": "duration",
"title": "I Duration",
"type": "string"
}
},
}
Model = pydantic_model_from_json_schema(schema)
Model.model_fields
Model = pydantic_model_from_json_schema(schema)
Model.model_fields
#> {'a_int': FieldInfo(annotation=Union[int, NoneType], required=False, default=1, title='A Int'),
#> 'i_duration': FieldInfo(annotation=Union[str, NoneType], required=False, default='PT2H33M3S', title='I Duration')} this is functionality that I require so I made this hack, to modify the generated pydantic model: from datetime import timedelta
from pydantic import create_model
def get_timedelta_fields(schema: dict) -> list[str]:
pr = schema["properties"]
return [k for k, v in pr.items() if "format" in v and v["format"] == "duration"]
def update_timedelta_field(model: BaseModel, timedelta_fields: list[str]) -> BaseModel:
"""returns a new pydantic model where serialization validators have been added to dates,
datetimes and durations for compatibility with excel"""
get_default = lambda obj: obj.default if hasattr(obj, "default") else ...
deltas = {
k: (timedelta, get_default(v))
for k, v in model.model_fields.items()
if k in timedelta_fields
} | {"__base__": model}
return create_model(model.__name__ + "New", **deltas)
li = get_timedelta_fields(schema)
Model1 = update_timedelta_field(Model, li)
Model1.model_fields
#> {'a_int': FieldInfo(annotation=Union[int, NoneType], required=False, default=1, title='A Int'),
#> 'i_duration': FieldInfo(annotation=timedelta, required=False, default='PT2H33M3S')} thanks for this great package! |
can confirm that this is now working with |
jgunstone
added a commit
to maxfordham/xlsxdatagrid
that referenced
this issue
Sep 30, 2024
Thanks, this looks great! Can you also add support for the {
"type": "object",
"properties": {
"granularity": {
"type": "number",
"format": "time-delta"
}
},
"required": ["granularity" ]
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Is your feature request related to a problem? Please describe.
We have a lot of timedelta fields in our schemas and would like to take advantage of Pydantic's native handling of timedelta types. However,
datamodel-code-generator
does not appear to support outputtingtimedelta
objects. Nativetimedelta
support would be a very useful addition.Pydantic handles timedeltas natively. It also appears that
msgspec
addedtimedelta
support recently (see jcrist/msgspec#475) so I don't think there would be anything blocking addingtimedelta
support to alldatamodel-code-generator
output types.Describe the solution you'd like
I've seen two common JSON schema formats to represent timedeltas:
This one is used by Pydantic 1 and serializes the timedeltas as floats of seconds
This one is used by Pydantic 2 and serializes the timedeltas as ISO 8106 duration strings
Ideally,
datamodel-code-generator
would understand and outputtimedelta
fields for both of those schemas.Describe alternatives you've considered
Leaving the current default behavior and having
{"type": "number", "format": "time-delta"}
fall back to just afloat
of seconds.The text was updated successfully, but these errors were encountered: