Skip to content

Instantly share code, notes, and snippets.

@Kludex
Created July 3, 2023 15:06
Show Gist options
  • Save Kludex/f71675dea61302bc0c19f8969098932a to your computer and use it in GitHub Desktop.
Save Kludex/f71675dea61302bc0c19f8969098932a to your computer and use it in GitHub Desktop.
ObjectId with Pydantic protocol
from typing import Type, Callable, Any
from bson.objectid import ObjectId, InvalidId
from pydantic import BaseModel, ValidationError
from pydantic_core import CoreSchema, core_schema
class PydanticObjectId(ObjectId):
@classmethod
def __get_pydantic_core_schema__(
cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
return core_schema.no_info_after_validator_function(
cls._validate, core_schema.any_schema()
)
@classmethod
def _validate(cls, value: Any) -> ObjectId:
try:
return ObjectId(value)
except (InvalidId, TypeError) as e:
raise ValueError("Not a valid ObjectId") from e
class Model(BaseModel):
id: PydanticObjectId
print(Model.model_validate({"id": ObjectId()}))
print(Model.model_validate({"id": str(ObjectId())}))
try:
Model.model_validate({"id": 123})
except ValidationError as e:
print(e.errors())
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment