Browse Source

♻️ 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
pull/9747/head 0.100.0-beta1
Sebastián Ramírez 2 years ago
committed by GitHub
parent
commit
6dc975da9d
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
  1. 33
      fastapi/openapi/models.py
  2. 5
      fastapi/utils.py

33
fastapi/openapi/models.py

@ -1,7 +1,14 @@
from enum import Enum
from typing import Any, Callable, Dict, Iterable, List, Optional, Union
from fastapi._compat import PYDANTIC_V2, _model_rebuild
from typing import Any, Callable, Dict, Iterable, List, Optional, Type, Union
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

5
fastapi/utils.py

@ -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}")

Loading…
Cancel
Save