Coverage for faststream / _internal / _compat.py: 60%
66 statements
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-08 01:48 +0000
« prev ^ index » next coverage.py v7.13.5, created at 2026-05-08 01:48 +0000
1import json
2import sys
3import warnings
4from collections import UserString
5from collections.abc import Callable, Iterable, Mapping
6from importlib.util import find_spec
7from typing import (
8 Any,
9 TypeVar,
10)
12from pydantic import BaseModel
13from pydantic.version import VERSION as PYDANTIC_VERSION
15IS_WINDOWS = sys.platform in {"win32", "cygwin", "msys"}
16IS_MACOS = sys.platform == "darwin"
18__all__ = (
19 "HAS_TYPER",
20 "PYDANTIC_V2",
21 "BaseModel",
22 "CoreSchema",
23 "EmailStr",
24 "ExceptionGroup",
25 "GetJsonSchemaHandler",
26 "PydanticUndefined",
27 "json_dumps",
28 "json_loads",
29 "with_info_plain_validator_function",
30)
32try:
33 HAS_TYPER = find_spec("typer") is not None
34except ImportError:
35 HAS_TYPER = False
38json_dumps: Callable[..., bytes]
39orjson: Any
41try:
42 import orjson # type: ignore[no-redef]
43except ImportError:
44 orjson = None
46if orjson: 46 ↛ 47line 46 didn't jump to line 47 because the condition on line 46 was never true
47 json_loads = orjson.loads
48 json_dumps = orjson.dumps
49else:
50 json_loads = json.loads
52 def json_dumps(*a: Any, **kw: Any) -> bytes:
53 return json.dumps(*a, **kw).encode()
56ModelVar = TypeVar("ModelVar", bound=BaseModel)
58JsonSchemaValue = Mapping[str, Any]
59major, minor, *_ = PYDANTIC_VERSION.split(".")
60_PYDANTCI_MAJOR, _PYDANTIC_MINOR = int(major), int(minor)
62PYDANTIC_V2 = _PYDANTCI_MAJOR >= 2
64if PYDANTIC_V2:
65 if _PYDANTIC_MINOR >= 4:
66 from pydantic.annotated_handlers import (
67 GetJsonSchemaHandler,
68 )
69 from pydantic_core.core_schema import (
70 with_info_plain_validator_function,
71 )
72 else:
73 from pydantic._internal._annotated_handlers import ( # type: ignore[no-redef]
74 GetJsonSchemaHandler,
75 )
76 from pydantic_core.core_schema import (
77 general_plain_validator_function as with_info_plain_validator_function,
78 )
80 from pydantic_core import CoreSchema, PydanticUndefined, to_jsonable_python
82 SCHEMA_FIELD = "json_schema_extra"
83 DEF_KEY = "$defs"
85 def model_to_jsonable(
86 model: BaseModel,
87 **kwargs: Any,
88 ) -> Any:
89 return to_jsonable_python(model, **kwargs)
91 def dump_json(data: Any) -> bytes:
92 return json_dumps(model_to_jsonable(data))
94 def get_model_fields(model: type[BaseModel]) -> dict[str, Any]:
95 return model.model_fields
97 def model_to_json(model: BaseModel, **kwargs: Any) -> str:
98 return model.model_dump_json(**kwargs)
100 def model_parse(
101 model: type[ModelVar],
102 data: str | bytes,
103 **kwargs: Any,
104 ) -> ModelVar:
105 return model.model_validate_json(data, **kwargs)
107 def model_schema(model: type[BaseModel], **kwargs: Any) -> dict[str, Any]:
108 return model.model_json_schema(**kwargs)
110else:
111 from pydantic.json import pydantic_encoder
113 GetJsonSchemaHandler = Any # type: ignore[assignment,misc]
114 CoreSchema = Any # type: ignore[assignment,misc]
116 SCHEMA_FIELD = "schema_extra"
117 DEF_KEY = "definitions"
119 PydanticUndefined = Ellipsis # type: ignore[assignment]
121 def dump_json(data: Any) -> bytes:
122 return json_dumps(data, default=pydantic_encoder)
124 def get_model_fields(model: type[BaseModel]) -> dict[str, Any]:
125 return model.__fields__ # type: ignore[return-value]
127 def model_to_json(model: BaseModel, **kwargs: Any) -> str:
128 return model.json(**kwargs)
130 def model_parse(
131 model: type[ModelVar],
132 data: str | bytes,
133 **kwargs: Any,
134 ) -> ModelVar:
135 return model.parse_raw(data, **kwargs)
137 def model_schema(model: type[BaseModel], **kwargs: Any) -> dict[str, Any]:
138 return model.schema(**kwargs)
140 def model_to_jsonable(
141 model: BaseModel,
142 **kwargs: Any,
143 ) -> Any:
144 return json_loads(model.json(**kwargs))
146 # TODO: pydantic types misc
147 def with_info_plain_validator_function( # type: ignore[misc]
148 function: Callable[..., Any],
149 *,
150 ref: str | None = None,
151 metadata: Any = None,
152 serialization: Any = None,
153 ) -> JsonSchemaValue:
154 return {}
157if sys.version_info >= (3, 11):
158 ExceptionGroup = ExceptionGroup # noqa: F821,PLW0127
159else:
160 from exceptiongroup import ExceptionGroup
162try:
163 import email_validator
165 if email_validator is None:
166 raise ImportError
167 from pydantic import EmailStr
168except ImportError: # pragma: no cover
169 # NOTE: EmailStr mock was copied from the FastAPI
170 # https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24
171 class EmailStr(UserString): # type: ignore[no-redef]
172 """EmailStr is a string that should be an email.
174 Note: EmailStr mock was copied from the FastAPI:
175 https://github.com/tiangolo/fastapi/blob/master/fastapi/openapi/models.py#24
176 """
178 @classmethod
179 def __get_validators__(cls) -> Iterable[Callable[..., Any]]:
180 """Returns the validators for the EmailStr class."""
181 yield cls.validate
183 @classmethod
184 def validate(cls, v: Any) -> str:
185 """Validates the EmailStr class."""
186 warnings.warn(
187 "email-validator not installed, email fields will be treated as str.\n"
188 "To install, run: pip install email-validator",
189 category=RuntimeWarning,
190 stacklevel=1,
191 )
192 return str(v)
194 @classmethod
195 def _validate(cls, __input_value: Any, _: Any) -> str:
196 warnings.warn(
197 "email-validator not installed, email fields will be treated as str.\n"
198 "To install, run: pip install email-validator",
199 category=RuntimeWarning,
200 stacklevel=1,
201 )
202 return str(__input_value)
204 @classmethod
205 def __get_pydantic_json_schema__(
206 cls,
207 core_schema: CoreSchema,
208 handler: GetJsonSchemaHandler,
209 ) -> JsonSchemaValue:
210 """Returns the JSON schema for the EmailStr class.
212 Args:
213 core_schema : the core schema
214 handler : the handler
215 """
216 return {"type": "string", "format": "email"}
218 @classmethod
219 def __get_pydantic_core_schema__(
220 cls,
221 source: type[Any],
222 handler: Callable[[Any], CoreSchema],
223 ) -> JsonSchemaValue:
224 """Returns the core schema for the EmailStr class.
226 Args:
227 source : the source
228 handler : the handler
229 """
230 return with_info_plain_validator_function(cls._validate)
233uvicorn: Any
235try:
236 import uvicorn
238 HAS_UVICORN = True
240except ImportError:
241 uvicorn = None
242 HAS_UVICORN = False