3
3
Add async validation to your pydantic models 🥳. This allows you to add validation that actually checks the database
4
4
or makes an API call or just use any code you did write async.
5
5
6
- Note that validation cannot happen during model creation, so you have to call ` await model .model_async_validate() `
6
+ Note that validation cannot happen during model creation, so you have to call ` await obj .model_async_validate() `
7
7
yourself. This is due to the fact that ` __init__() ` will always be a sync method and you cannot sanely call async
8
8
methods from sync methods.
9
9
@@ -95,7 +95,7 @@ class SomethingModel(AsyncValidationModelMixin, pydantic.BaseModel):
95
95
96
96
## When to use field vs. model validators
97
97
98
- As validation happens after the model instance was created, you can access all fields just using ` self ` anyways. So
98
+ As validation happens after the model instance was created, you can access all fields just using ` self ` anyways. So
99
99
field vs. model validation is kind of the same thing. However field validators allow you to get the ` value ` of the
100
100
field as its parameter, so this is perfect when you reuse validators or want to validate multiple fields with the same
101
101
validator. Also field validators will tie the ` ValidationError ` to the field, so it will contain the detail about which
@@ -111,7 +111,7 @@ field to tie it to.
111
111
## Handling validation errors
112
112
113
113
Like with normal pydantic validation, you can catch ` ValidationError ` and access the ` errors() ` method to get a list of
114
- all errors. Like pydantic errors will be collected and be raised as one ` ValidationError ` at the end of validation,
114
+ all errors. Like with pydantic errors will be collected and be raised as one ` ValidationError ` at the end of validation,
115
115
including all errors that occurred.
116
116
117
117
` model_async_validate() ` will also try to validate child model instances, that are also using the
@@ -139,27 +139,28 @@ invalid_instance = ParentModel(child=SomethingModel(name="invalid"))
139
139
await invalid_instance.model_async_validate() # will raise normal pydantic ValidationError
140
140
```
141
141
142
- Note the ` ValidationError ` will not have the location of the error set to ` "child.name" ` .
142
+ Note the ` ValidationError ` will now have the location of the error set to ` "child.name" ` .
143
143
144
144
Recursive validation will happen in those cases:
145
- * Child models as direct instance variables (see example above)
146
- * Child models in list items
147
- * Child models in dict values
145
+ * Child models as direct instance variables (as in example above)
146
+ * Child models in list items (like ` child: List[SomethingModel] ` )
147
+ * Child models in dict values (like ` child: Dict[str, SomethingModel] ` )
148
148
149
149
## FastAPI support
150
150
151
151
When using FastAPI you also can use the ` AsyncValidationModelMixin ` , note however that FastAPI will see any
152
152
` ValidationError ` risen in endpoint methods as unhandled exceptions and thus will return a HTTP 500 error. FastAPI
153
- will only handle the validation errors happening during handling the endpoint parameters in as special way and
153
+ will only handle the validation errors happening during handling the endpoint parameters in a special way and
154
154
convert those to ` RequestValidationError ` - which will then be handled by the default exception handler for
155
155
` RequestValidationError ` FastAPI provides. This will then result in a HTTP 422 return code.
156
156
157
157
When using ` pydantic_async_validation ` this would be a major drawback, as using ` model_async_validate ` for
158
- validating input (/request) data is a totally fine use case. To solve this issue you can use the
159
- ` ensure_request_validation_errors ` context manager provided in ` pydantic_async_validation.fastapi ` . This will
160
- ensure that any ` ValidationError ` risen during the context manager will be converted to a ` RequestValidationError ` .
161
- Those ` RequestValidationError ` s will then be handled by the default exception handler for ` RequestValidationError `
162
- FastAPI provides. This will then again result in a HTTP 422 return code.
158
+ validating input (/request) data is a totally fine use case and you cannot push this into the normal request
159
+ validation step FastAPI does. To solve this issue you can use the ` ensure_request_validation_errors ` context manager
160
+ provided in ` pydantic_async_validation.fastapi ` . This will ensure that any ` ValidationError ` risen inside the context
161
+ manager will be converted to a ` RequestValidationError ` . Those ` RequestValidationError ` s will then be handled by
162
+ the default exception handler for ` RequestValidationError ` which FastAPI provides. This will then again result in a
163
+ HTTP 422 return code.
163
164
164
165
Example for usage with FastAPI:
165
166
0 commit comments