1"""!!! abstract "Usage Documentation"
2 [Build a Plugin](../concepts/plugins.md#build-a-plugin)
3
4Plugin interface for Pydantic plugins, and related types.
5"""
6
7from __future__ import annotations
8
9from typing import Any, Callable, Literal, NamedTuple
10
11from pydantic_core import CoreConfig, CoreSchema, ValidationError
12from typing_extensions import Protocol, TypeAlias
13
14from pydantic.config import ExtraValues
15
16__all__ = (
17 'PydanticPluginProtocol',
18 'BaseValidateHandlerProtocol',
19 'ValidatePythonHandlerProtocol',
20 'ValidateJsonHandlerProtocol',
21 'ValidateStringsHandlerProtocol',
22 'NewSchemaReturns',
23 'SchemaTypePath',
24 'SchemaKind',
25)
26
27NewSchemaReturns: TypeAlias = 'tuple[ValidatePythonHandlerProtocol | None, ValidateJsonHandlerProtocol | None, ValidateStringsHandlerProtocol | None]'
28
29
30class SchemaTypePath(NamedTuple):
31 """Path defining where `schema_type` was defined, or where `TypeAdapter` was called."""
32
33 module: str
34 name: str
35
36
37SchemaKind: TypeAlias = Literal['BaseModel', 'TypeAdapter', 'dataclass', 'create_model', 'validate_call']
38
39
40class PydanticPluginProtocol(Protocol):
41 """Protocol defining the interface for Pydantic plugins."""
42
43 def new_schema_validator(
44 self,
45 schema: CoreSchema,
46 schema_type: Any,
47 schema_type_path: SchemaTypePath,
48 schema_kind: SchemaKind,
49 config: CoreConfig | None,
50 plugin_settings: dict[str, object],
51 ) -> tuple[
52 ValidatePythonHandlerProtocol | None, ValidateJsonHandlerProtocol | None, ValidateStringsHandlerProtocol | None
53 ]:
54 """This method is called for each plugin every time a new [`SchemaValidator`][pydantic_core.SchemaValidator]
55 is created.
56
57 It should return an event handler for each of the three validation methods, or `None` if the plugin does not
58 implement that method.
59
60 Args:
61 schema: The schema to validate against.
62 schema_type: The original type which the schema was created from, e.g. the model class.
63 schema_type_path: Path defining where `schema_type` was defined, or where `TypeAdapter` was called.
64 schema_kind: The kind of schema to validate against.
65 config: The config to use for validation.
66 plugin_settings: Any plugin settings.
67
68 Returns:
69 A tuple of optional event handlers for each of the three validation methods -
70 `validate_python`, `validate_json`, `validate_strings`.
71 """
72 raise NotImplementedError('Pydantic plugins should implement `new_schema_validator`.')
73
74
75class BaseValidateHandlerProtocol(Protocol):
76 """Base class for plugin callbacks protocols.
77
78 You shouldn't implement this protocol directly, instead use one of the subclasses with adds the correctly
79 typed `on_error` method.
80 """
81
82 on_enter: Callable[..., None]
83 """`on_enter` is changed to be more specific on all subclasses"""
84
85 def on_success(self, result: Any) -> None:
86 """Callback to be notified of successful validation.
87
88 Args:
89 result: The result of the validation.
90 """
91 return
92
93 def on_error(self, error: ValidationError) -> None:
94 """Callback to be notified of validation errors.
95
96 Args:
97 error: The validation error.
98 """
99 return
100
101 def on_exception(self, exception: Exception) -> None:
102 """Callback to be notified of validation exceptions.
103
104 Args:
105 exception: The exception raised during validation.
106 """
107 return
108
109
110class ValidatePythonHandlerProtocol(BaseValidateHandlerProtocol, Protocol):
111 """Event handler for `SchemaValidator.validate_python`."""
112
113 def on_enter(
114 self,
115 input: Any,
116 *,
117 strict: bool | None = None,
118 extra: ExtraValues | None = None,
119 from_attributes: bool | None = None,
120 context: Any | None = None,
121 self_instance: Any | None = None,
122 by_alias: bool | None = None,
123 by_name: bool | None = None,
124 ) -> None:
125 """Callback to be notified of validation start, and create an instance of the event handler.
126
127 Args:
128 input: The input to be validated.
129 strict: Whether to validate the object in strict mode.
130 extra: Whether to ignore, allow, or forbid extra data during model validation.
131 from_attributes: Whether to validate objects as inputs by extracting attributes.
132 context: The context to use for validation, this is passed to functional validators.
133 self_instance: An instance of a model to set attributes on from validation, this is used when running
134 validation from the `__init__` method of a model.
135 by_alias: Whether to use the field's alias to match the input data to an attribute.
136 by_name: Whether to use the field's name to match the input data to an attribute.
137 """
138
139
140class ValidateJsonHandlerProtocol(BaseValidateHandlerProtocol, Protocol):
141 """Event handler for `SchemaValidator.validate_json`."""
142
143 def on_enter(
144 self,
145 input: str | bytes | bytearray,
146 *,
147 strict: bool | None = None,
148 extra: ExtraValues | None = None,
149 context: Any | None = None,
150 self_instance: Any | None = None,
151 by_alias: bool | None = None,
152 by_name: bool | None = None,
153 ) -> None:
154 """Callback to be notified of validation start, and create an instance of the event handler.
155
156 Args:
157 input: The JSON data to be validated.
158 strict: Whether to validate the object in strict mode.
159 extra: Whether to ignore, allow, or forbid extra data during model validation.
160 context: The context to use for validation, this is passed to functional validators.
161 self_instance: An instance of a model to set attributes on from validation, this is used when running
162 validation from the `__init__` method of a model.
163 by_alias: Whether to use the field's alias to match the input data to an attribute.
164 by_name: Whether to use the field's name to match the input data to an attribute.
165 """
166
167
168StringInput: TypeAlias = 'dict[str, StringInput]'
169
170
171class ValidateStringsHandlerProtocol(BaseValidateHandlerProtocol, Protocol):
172 """Event handler for `SchemaValidator.validate_strings`."""
173
174 def on_enter(
175 self,
176 input: StringInput,
177 *,
178 strict: bool | None = None,
179 extra: ExtraValues | None = None,
180 context: Any | None = None,
181 by_alias: bool | None = None,
182 by_name: bool | None = None,
183 ) -> None:
184 """Callback to be notified of validation start, and create an instance of the event handler.
185
186 Args:
187 input: The string data to be validated.
188 strict: Whether to validate the object in strict mode.
189 extra: Whether to ignore, allow, or forbid extra data during model validation.
190 context: The context to use for validation, this is passed to functional validators.
191 by_alias: Whether to use the field's alias to match the input data to an attribute.
192 by_name: Whether to use the field's name to match the input data to an attribute.
193 """