♻️ Refactor parts that use optional requirements to make them compatible with installations without them (#9707)

* ♻️ Refactor parts that use optional requirements to make them compatible with installations without them

* ♻️ Update JSON Schema for email field without email-validator installed
This commit is contained in:
Sebastián Ramírez 2023-06-20 18:22:03 +02:00 committed by GitHub
parent e7b3d47af3
commit 6dc975da9d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 32 additions and 4 deletions

View File

@ -1,7 +1,14 @@
from enum import Enum
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
from typing import Any, Callable, Dict, Iterable, List, Optional, Type, Union
from fastapi._compat import PYDANTIC_V2, _model_rebuild
from fastapi._compat import (
PYDANTIC_V2,
CoreSchema,
GetJsonSchemaHandler,
JsonSchemaValue,
_model_rebuild,
general_plain_validator_function,
)
from fastapi.logger import logger
from pydantic import AnyUrl, BaseModel, Field
from typing_extensions import Literal
@ -26,6 +33,26 @@ except ImportError: # pragma: no cover
)
return str(v)
@classmethod
def _validate(cls, __input_value: Any, _: Any) -> str:
logger.warning(
"email-validator not installed, email fields will be treated as str.\n"
"To install, run: pip install email-validator"
)
return str(__input_value)
@classmethod
def __get_pydantic_json_schema__(
cls, core_schema: CoreSchema, handler: GetJsonSchemaHandler
) -> JsonSchemaValue:
return {"type": "string", "format": "email"}
@classmethod
def __get_pydantic_core_schema__(
cls, source: Type[Any], handler: Callable[[Any], CoreSchema]
) -> CoreSchema:
return general_plain_validator_function(cls._validate)
class Contact(BaseModel):
name: Optional[str] = None

View File

@ -15,7 +15,6 @@ from typing import (
from weakref import WeakKeyDictionary
import fastapi
from dirty_equals import IsStr
from fastapi._compat import (
PYDANTIC_V2,
BaseConfig,
@ -219,5 +218,7 @@ def get_value_or_default(
return first_item
def match_pydantic_error_url(error_type: str) -> IsStr:
def match_pydantic_error_url(error_type: str) -> Any:
from dirty_equals import IsStr
return IsStr(regex=rf"^https://errors\.pydantic\.dev/.*/v/{error_type}")