♻️ 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 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 fastapi.logger import logger
from pydantic import AnyUrl, BaseModel, Field from pydantic import AnyUrl, BaseModel, Field
from typing_extensions import Literal from typing_extensions import Literal
@ -26,6 +33,26 @@ except ImportError: # pragma: no cover
) )
return str(v) 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): class Contact(BaseModel):
name: Optional[str] = None name: Optional[str] = None

View File

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