__init__.py 7.2 KB

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