Skip to content

Commit

Permalink
Use permissive time parser for BaseDTO objects (#498)
Browse files Browse the repository at this point in the history
* Use permissive time parser for BaseDTO objects

* Add support for generic models as well
  • Loading branch information
sergei-encord authored Jan 17, 2024
1 parent 371eb6e commit 9cbbd8e
Show file tree
Hide file tree
Showing 3 changed files with 33 additions and 6 deletions.
7 changes: 2 additions & 5 deletions encord/orm/base_dto/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

pydantic_version = int(pydantic_version_str.split(".")[0])
if pydantic_version < 2:
from encord.orm.base_dto.base_dto_pydantic_v1 import BaseDTO, GenericBaseDTO
from encord.orm.base_dto.base_dto_pydantic_v1 import BaseDTO, Field, GenericBaseDTO
else:
from encord.orm.base_dto.base_dto_pydantic_v2 import ( # type: ignore[assignment]
BaseDTO,
GenericBaseDTO,
)
from encord.orm.base_dto.base_dto_pydantic_v2 import BaseDTO, Field, GenericBaseDTO # type: ignore[assignment]
16 changes: 15 additions & 1 deletion encord/orm/base_dto/base_dto_pydantic_v1.py
Original file line number Diff line number Diff line change
@@ -1,8 +1,10 @@
from datetime import datetime
from typing import Any, Dict, Type, TypeVar

from pydantic import BaseModel, ValidationError
from pydantic import BaseModel, Field, ValidationError, validator
from pydantic.generics import GenericModel

from encord.common.time_parser import parse_datetime
from encord.common.utils import snake_to_camel
from encord.exceptions import EncordException
from encord.orm.base_dto.base_dto_interface import BaseDTOInterface, T
Expand All @@ -14,6 +16,12 @@ class Config:
alias_generator = snake_to_camel
allow_population_by_field_name = True

@validator("*", pre=True)
def parse_datetime(cls, value, field):
if isinstance(value, str) and issubclass(field.type_, datetime):
return parse_datetime(value)
return value

@classmethod
def from_dict(cls: Type[T], d: Dict[str, Any]) -> T:
try:
Expand All @@ -34,6 +42,12 @@ class Config:
alias_generator = snake_to_camel
allow_population_by_field_name = True

@validator("*", pre=True)
def parse_datetime(cls, value, field):
if isinstance(value, str) and issubclass(field.type_, datetime):
return parse_datetime(value)
return value

@classmethod
def from_dict(cls: Type[T], d: Dict[str, Any]) -> T:
try:
Expand Down
16 changes: 16 additions & 0 deletions encord/orm/base_dto/base_dto_pydantic_v2.py
Original file line number Diff line number Diff line change
@@ -1,12 +1,16 @@
from datetime import datetime
from typing import Any, Dict, Type, TypeVar

# TODO: invent some dependency version dependent type checking to get rid of this ignore
from pydantic import ( # type: ignore[attr-defined]
BaseModel,
ConfigDict, # type: ignore[attr-defined]
Field,
ValidationError,
field_validator,
)

from encord.common.time_parser import parse_datetime
from encord.common.utils import snake_to_camel
from encord.exceptions import EncordException
from encord.orm.base_dto.base_dto_interface import BaseDTOInterface, T
Expand All @@ -15,6 +19,12 @@
class BaseDTO(BaseDTOInterface, BaseModel):
model_config = ConfigDict(extra="ignore", populate_by_name=True, alias_generator=snake_to_camel)

@field_validator("*", mode="before")
def parse_datetime(cls, value, info):
if issubclass(cls.model_fields[info.field_name].annotation, datetime) and isinstance(value, str):
return parse_datetime(value)
return value

@classmethod
def from_dict(cls: Type[T], d: Dict[str, Any]) -> T:
try:
Expand All @@ -32,6 +42,12 @@ def to_dict(self, by_alias=True, exclude_none=True) -> Dict[str, Any]:
class GenericBaseDTO(BaseDTOInterface, BaseModel):
model_config = ConfigDict(extra="ignore", populate_by_name=True, alias_generator=snake_to_camel)

@field_validator("*", mode="before")
def parse_datetime(cls, value, info):
if issubclass(cls.model_fields[info.field_name].annotation, datetime) and isinstance(value, str):
return parse_datetime(value)
return value

@classmethod
def from_dict(cls: Type[T], d: Dict[str, Any]) -> T:
try:
Expand Down

0 comments on commit 9cbbd8e

Please sign in to comment.