Skip to content

Commit

Permalink
✨ Add support for Pydantic v2 (#9816)
Browse files Browse the repository at this point in the history
* ✨ Pydantic v2 migration, initial implementation (#9500)

* ✨ Add compat layer, for Pydantic v1 and v2

* ✨ Re-export Pydantic needed internals from compat, to later patch them for v1

* ♻️ Refactor internals to use new compatibility layers and run with Pydantic v2

* 📝 Update examples to run with Pydantic v2

* ✅ Update tests to use Pydantic v2

* 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks

* ✅ Temporarily disable Peewee tests, afterwards I'll enable them only for Pydantic v1

* 🐛 Fix JSON Schema generation and OpenAPI ref template

* 🐛 Fix model field creation with defaults from Pydantic v2

* 🐛 Fix body field creation, with new FieldInfo

* ✨ Use and check new ResponseValidationError for server validation errors

* ✅ Fix test_schema_extra_examples tests with ResponseValidationError

* ✅ Add dirty-equals to tests for compatibility with Pydantic v1 and v2

* ✨ Add util to regenerate errors with custom loc

* ✨ Generate validation errors with loc

* ✅ Update tests for compatibility with Pydantic v1 and v2

* ✅ Update tests for Pydantic v2 in tests/test_filter_pydantic_sub_model.py

* ✅ Refactor tests in tests/test_dependency_overrides.py for Pydantic v2, separate parameterized into independent tests to use insert_assert

* ✅ Refactor OpenAPI test for tests/test_infer_param_optionality.py for consistency, and make it compatible with Pydantic v1 and v2

* ✅ Update tests for tests/test_multi_query_errors.py for Pydantic v1 and v2

* ✅ Update tests for tests/test_multi_body_errors.py for Pydantic v1 and v2

* ✅ Update tests for tests/test_multi_body_errors.py for Pydantic v1 and v2

* 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks

* ♻️ Refactor tests for tests/test_path.py to inline pytest parameters, to make it easier to make them compatible with Pydantic v2

* ✅ Refactor and udpate tests for tests/test_path.py for Pydantic v1 and v2

* ♻️ Refactor and update tests for tests/test_query.py with compatibility for Pydantic v1 and v2

* ✅ Fix test with optional field without default None

* ✅ Update tests for compatibility with Pydantic v2

* ✅ Update tutorial tests for Pydantic v2

* ♻️ Update OAuth2 dependencies for Pydantic v2

* ♻️ Refactor str check when checking for sequence types

* ♻️ Rename regex to pattern to keep in sync with Pydantic v2

* ♻️ Refactor _compat.py, start moving conditional imports and declarations to specifics of Pydantic v1 or v2

* ✅ Update tests for OAuth2 security optional

* ✅ Refactor tests for OAuth2 optional for Pydantic v2

* ✅ Refactor tests for OAuth2 security for compatibility with Pydantic v2

* 🐛 Fix location in compat layer for Pydantic v2 ModelField

* ✅ Refactor tests for Pydantic v2 in tests/test_tutorial/test_bigger_applications/test_main_an_py39.py

* 🐛 Add missing markers in Python 3.9 tests

* ✅ Refactor tests for bigger apps for consistency with annotated ones and with support for Pydantic v2

* 🐛 Fix jsonable_encoder with new Pydantic v2 data types and Url

* 🐛 Fix invalid JSON error for compatibility with Pydantic v2

* ✅ Update tests for behind_a_proxy for Pydantic v2

* ✅ Update tests for tests/test_tutorial/test_body/test_tutorial001_py310.py for Pydantic v2

* ✅ Update tests for tests/test_tutorial/test_body/test_tutorial001.py with Pydantic v2 and consistency with Python 3.10 tests

* ✅ Fix tests for tutorial/body_fields for Pydantic v2

* ✅ Refactor tests for tutorial/body_multiple_params with Pydantic v2

* ✅ Update tests for tutorial/body_nested_models for Pydantic v2

* ✅ Update tests for tutorial/body_updates for Pydantic v2

* ✅ Update test for tutorial/cookie_params for Pydantic v2

* ✅ Fix tests for tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py for Pydantic v2

* ✅ Update tests for tutorial/dataclasses for Pydantic v2

* ✅ Update tests for tutorial/dependencies for Pydantic v2

* ✅ Update tests for tutorial/extra_data_types for Pydantic v2

* ✅ Update tests for tutorial/handling_errors for Pydantic v2

* ✅ Fix test markers for Python 3.9

* ✅ Update tests for tutorial/header_params for Pydantic v2

* ✅ Update tests for Pydantic v2 in tests/test_tutorial/test_openapi_callbacks/test_tutorial001.py

* ✅ Fix extra tests for Pydantic v2

* ✅ Refactor test for parameters, to later fix Pydantic v2

* ✅ Update tests for tutorial/query_params for Pydantic v2

* ♻️ Update examples in docs to use new pattern instead of the old regex

* ✅ Fix several tests for Pydantic v2

* ✅ Update and fix test for ResponseValidationError

* 🐛 Fix check for sequences vs scalars, include bytes as scalar

* 🐛 Fix check for complex data types, include UploadFile

* 🐛 Add list to sequence annotation types

* 🐛 Fix checks for uploads and add utils to find if an annotation is an upload (or bytes)

* ✨ Add UnionType and NoneType to compat layer

* ✅ Update tests for request_files for compatibility with Pydantic v2 and consistency with other tests

* ✅ Fix testsw for request_forms for Pydantic v2

* ✅ Fix tests for request_forms_and_files for Pydantic v2

* ✅ Fix tests in tutorial/security for compatibility with Pydantic v2

* ⬆️ Upgrade required version of email_validator

* ✅ Fix tests for params repr

* ✅ Add Pydantic v2 pytest markers

* Use match_pydantic_error_url

* 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks

* Use field_serializer instead of encoders in some tests

* Show Undefined as ... in repr

* Mark custom encoders test with xfail

* Update test to reflect new serialization of Decimal as str

* Use `model_validate` instead of `from_orm`

* Update JSON schema to reflect required nullable

* Add dirty-equals to pyproject.toml

* Fix locs and error creation for use with pydantic 2.0a4

* Use the type adapter for serialization. This is hacky.

* 🎨 [pre-commit.ci] Auto format from pre-commit.com hooks

* ✅ Refactor test_multi_body_errors for compatibility with Pydantic v1 and v2

* ✅ Refactor test_custom_encoder for Pydantic v1 and v2

* ✅ Set input to None for now, for compatibility with current tests

* 🐛 Fix passing serialization params to model field when handling the response

* ♻️ Refactor exceptions to not depend on Pydantic ValidationError class

* ♻️ Revert/refactor params to simplify repr

* ✅ Tweak tests for custom class encoders for Pydantic v1 and v2

* ✅ Tweak tests for jsonable_encoder for Pydantic v1 and v2

* ✅ Tweak test for compatibility with Pydantic v1 and v2

* 🐛 Fix filtering data with subclasses

* 🐛 Workaround examples in OpenAPI schema

* ✅ Add skip marker for SQL tutorial, needs to be updated either way

* ✅ Update test for broken JSON

* ✅ Fix test for broken JSON

* ✅ Update tests for timedeltas

* ✅ Fix test for plain text validation errors

* ✅ Add markers for Pydantic v1 exclusive tests (for now)

* ✅ Update test for path_params with enums for compatibility with Pydantic v1 and v2

* ✅ Update tests for extra examples in OpenAPI

* ✅ Fix tests for response_model with compatibility with Pydantic v1 and v2

* 🐛 Fix required double serialization for different types of models

* ✅ Fix tests for response model with compatibility with new Pydantic v2

* 🐛 Import Undefined from compat layer

* ✅ Fix tests for response_model for Pydantic v2

* ✅ Fix tests for schema_extra for Pydantic v2

* ✅ Add markers and update tests for Pydantic v2

* 💡 Comment out logic for double encoding that breaks other usecases

* ✅ Update errors for int parsing

* ♻️ Refactor re-enabling compatibility for Pydantic v1

* ♻️ Refactor OpenAPI utils to re-enable support for Pydantic v1

* ♻️ Refactor dependencies/utils and _compat for compatibility with Pydantic v1

* 🐛 Fix and tweak compatibility with Pydantic v1 and v2 in dependencies/utils

* ✅ Tweak tests and examples for Pydantic v1

* ♻️ Tweak call to ModelField.validate for compatibility with Pydantic v1

* ✨ Use new global override TypeAdapter from_attributes

* ✅ Update tests after updating from_attributes

* 🔧 Update pytest config to avoid collecting tests from docs, useful for editor-integrated tests

* ✅ Add test for data filtering, including inheritance and models in fields or lists of models

* ♻️ Make OpenAPI models compatible with both Pydantic v1 and v2

* ♻️ Fix compatibility for Pydantic v1 and v2 in jsonable_encoder

* ♻️ Fix compatibility in params with Pydantic v1 and v2

* ♻️ Fix compatibility when creating a FieldInfo in Pydantic v1 and v2 in utils.py

* ♻️ Fix generation of flat_models and JSON Schema definitions in _compat.py for Pydantic v1 and v2

* ♻️ Update handling of ErrorWrappers for Pydantic v1

* ♻️ Refactor checks and handling of types an sequences

* ♻️ Refactor and cleanup comments with compatibility for Pydantic v1 and v2

* ♻️ Update UploadFile for compatibility with both Pydantic v1 and v2

* 🔥 Remove commented out unneeded code

* 🐛 Fix mock of get_annotation_from_field_info for Pydantic v1 and v2

* 🐛 Fix params with compatibility for Pydantic v1 and v2, with schemas and new pattern vs regex

* 🐛 Fix check if field is sequence for Pydantic v1

* ✅ Fix tests for custom_schema_fields, for compatibility with Pydantic v1 and v2

* ✅ Simplify and fix tests for jsonable_encoder with compatibility for Pydantic v1 and v2

* ✅ Fix tests for orm_mode with Pydantic v1 and compatibility with Pydantic v2

* ♻️ Refactor logic for normalizing Pydantic v1 ErrorWrappers

* ♻️ Workaround for params with examples, before defining what to deprecate in Pydantic v1 and v2 for examples with JSON Schema vs OpenAPI

* ✅ Fix tests for Pydantic v1 and v2 for response_by_alias

* ✅ Fix test for schema_extra with compatibility with Pydantic v1 and v2

* ♻️ Tweak error regeneration with loc

* ♻️ Update error handling and serializationwith compatibility for Pydantic v1 and v2

* ♻️ Re-enable custom encoders for Pydantic v1

* ♻️ Update ErrorWrapper reserialization in Pydantic v1, do it outside of FastAPI ValidationExceptions

* ✅ Update test for filter_submodel, re-structure to simplify testing while keeping division of Pydantic v1 and v2

* ✅ Refactor Pydantic v1 only test that requires modifying environment variables

* 🔥 Update test for plaintext error responses, for Pydantic v1 and v2

* ⏪️ Revert changes in DB tutorial to use Pydantic v1 (the new guide will have SQLModel)

* ✅ Mark current SQL DB tutorial tests as Pydantic only

* ♻️ Update datastructures for compatibility with Pydantic v1, not requiring pydantic-core

* ♻️ Update encoders.py for compatibility with Pydantic v1

* ⏪️ Revert changes to Peewee, the docs for that are gonna live in a new HowTo section, not in the main tutorials

* ♻️ Simplify response body kwargs generation

* 🔥 Clean up comments

* 🔥 Clean some tests and comments

* ✅ Refactor tests to match new Pydantic error string URLs

* ✅ Refactor tests for recursive models for Pydantic v1 and v2

* ✅ Update tests for Peewee, re-enable, Pydantic-v1-only

* ♻️ Update FastAPI params to take regex and pattern arguments

* ⏪️ Revert tutorial examples for pattern, it will be done in a subsequent PR

* ⏪️ Revert changes in schema extra examples, it will be added later in a docs-specific PR

* 💡 Add TODO comment to document str validations with pattern

* 🔥 Remove unneeded comment

* 📌 Upgrade Pydantic pin dependency

* ⬆️ Upgrade email_validator dependency

* 🐛 Tweak type annotations in _compat.py

* 🔇 Tweak mypy errors for compat, for Pydantic v1 re-imports

* 🐛 Tweak and fix type annotations

* ➕ Update requirements-test.txt, re-add dirty-equals

* 🔥 Remove unnecessary config

* 🐛 Tweak type annotations

* 🔥 Remove unnecessary type in dependencies/utils.py

* 💡 Update comment in routing.py

---------

Co-authored-by: David Montague <35119617+dmontagu@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>

* 👷 Add CI for both Pydantic v1 and v2 (#9688)

* 👷 Test and install Pydantic v1 and v2 in CI

* 💚 Tweak CI config for Pydantic v1 and v2

* 💚 Fix Pydantic v2 specification in CI

* 🐛 Fix type annotations for compatibility with Python 3.7

* 💚 Install Pydantic v2 for lints

* 🐛 Fix type annotations for Pydantic v2

* 💚 Re-use test cache for lint

* ♻️ Refactor internals for test coverage and performance (#9691)

* ♻️ Tweak import of Annotated from typing_extensions, they are installed anyway

* ♻️ Refactor _compat to define functions for Pydantic v1 or v2 once instead of checking inside

* ✅ Add test for UploadFile for Pydantic v2

* ♻️ Refactor types and remove logic for impossible cases

* ✅ Add missing tests from test refactor for path params

* ✅ Add tests for new decimal encoder

* 💡 Add TODO comment for decimals in encoders

* 🔥 Remove unneeded dummy function

* 🔥 Remove section of code in field_annotation_is_scalar covered by sub-call to field_annotation_is_complex

* ♻️ Refactor and tweak variables and types in _compat

* ✅ Add tests for corner cases and compat with Pydantic v1 and v2

* ♻️ Refactor type annotations

* 🔖 Release version 0.100.0-beta1

* ♻️ 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

* 🐛 Fix support for Pydantic v2.0, small changes in their final release (#9771)

Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Sebastián Ramírez <tiangolo@gmail.com>

* 🔖 Release version 0.100.0-beta2

* ✨ OpenAPI 3.1.0 with Pydantic v2, merge `master` (#9773)

* ➕ Add dirty-equals as a testing dependency (#9778)

➕ Add dirty-equals as a testing dependency, it seems it got lsot at some point

* 🔀 Merge master, fix valid JSON Schema accepting bools (#9782)

* ⏪️ Revert usage of custom logic for TypeAdapter JSON Schema, solved on the Pydantic side (#9787)

⏪️ Revert usage of custom logic for TypeAdapter JSON Schema, solved on Pydantic side

* ♻️ Deprecate parameter `regex`, use `pattern` instead (#9786)

* 📝 Update docs to deprecate regex, recommend pattern

* ♻️ Update examples to use new pattern instead of regex

* 📝 Add new example with deprecated regex

* ♻️ Add deprecation notes and warnings for regex

* ✅ Add tests for regex deprecation

* ✅ Update tests for compatibility with Pydantic v1

* ✨ Update docs to use Pydantic v2 settings and add note and example about v1 (#9788)

* ➕ Add pydantic-settings to all extras

* 📝 Update docs for Pydantic settings

* 📝 Update Settings source examples to use Pydantic v2, and add a Pydantic v1 version

* ✅ Add tests for settings with Pydantic v1 and v2

* 🔥 Remove solved TODO comment

* ♻️ Update conditional OpenAPI to use new Pydantic v2 settings

* ✅ Update tests to import Annotated from typing_extensions for Python < 3.9 (#9795)

* ➕ Add pydantic-extra-types to fastapi[extra]

* ➕ temp: Install Pydantic from source to test JSON Schema metadata fixes (#9777)

* ➕ Install Pydantic from source, from branch for JSON Schema with metadata

* ➕ Update dependencies, install Pydantic main

* ➕ Fix dependency URL for Pydantic from source

* ➕ Add pydantic-settings for test requirements

* 💡 Add TODO comments to re-enable Pydantic main (not from source) (#9796)

* ✨ Add new Pydantic Field param options to Query, Cookie, Body, etc. (#9797)

* 📝 Add docs for Pydantic v2 for `docs/en/docs/advanced/path-operation-advanced-configuration.md` (#9798)

* 📝 Update docs in examples for settings with Pydantic v2 (#9799)

* 📝 Update JSON Schema `examples` docs with Pydantic v2 (#9800)

* ♻️ Use new Pydantic v2 JSON Schema generator (#9813)

Co-authored-by: David Montague <35119617+dmontagu@users.noreply.github.com>

* ♻️ Tweak type annotations and Pydantic version range (#9801)

* 📌 Re-enable GA Pydantic, for v2, require minimum 2.0.2 (#9814)

* 🔖 Release version 0.100.0-beta3

* 🔥 Remove duplicate type declaration from merge conflicts (#9832)

* 👷‍♂️ Run tests with Pydantic v2 GA (#9830)

👷 Run tests for Pydantic v2 GA

* 📝 Add notes to docs expecting Pydantic v2 and future updates (#9833)

* 📝 Update index with new extras

* 📝 Update release notes

---------

Co-authored-by: David Montague <35119617+dmontagu@users.noreply.github.com>
Co-authored-by: pre-commit-ci[bot] <66853113+pre-commit-ci[bot]@users.noreply.github.com>
Co-authored-by: Pastukhov Nikita <diementros@yandex.ru>
  • Loading branch information
4 people authored Jul 7, 2023
1 parent dd4e78c commit 0976185
Show file tree
Hide file tree
Showing 274 changed files with 16,751 additions and 4,601 deletions.
13 changes: 11 additions & 2 deletions .github/workflows/test.yml
Original file line number Diff line number Diff line change
Expand Up @@ -25,10 +25,12 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-pydantic-v2-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install -r requirements-tests.txt
- name: Install Pydantic v2
run: pip install "pydantic>=2.0.2,<3.0.0"
- name: Lint
run: bash scripts/lint.sh

Expand All @@ -37,6 +39,7 @@ jobs:
strategy:
matrix:
python-version: ["3.7", "3.8", "3.9", "3.10", "3.11"]
pydantic-version: ["pydantic-v1", "pydantic-v2"]
fail-fast: false
steps:
- uses: actions/checkout@v3
Expand All @@ -51,10 +54,16 @@ jobs:
id: cache
with:
path: ${{ env.pythonLocation }}
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
key: ${{ runner.os }}-python-${{ env.pythonLocation }}-${{ matrix.pydantic-version }}-${{ hashFiles('pyproject.toml', 'requirements-tests.txt') }}-test-v03
- name: Install Dependencies
if: steps.cache.outputs.cache-hit != 'true'
run: pip install -r requirements-tests.txt
- name: Install Pydantic v1
if: matrix.pydantic-version == 'pydantic-v1'
run: pip install "pydantic>=1.10.0,<2.0.0"
- name: Install Pydantic v2
if: matrix.pydantic-version == 'pydantic-v2'
run: pip install "pydantic>=2.0.2,<3.0.0"
- run: mkdir coverage
- name: Test
run: bash scripts/test.sh
Expand Down
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -447,6 +447,8 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
Used by Pydantic:

* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.

Used by Starlette:

Expand Down
7 changes: 7 additions & 0 deletions docs/en/docs/advanced/async-sql-databases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Async SQL (Relational) Databases

!!! info
These docs are about to be updated. 🎉

The current version assumes Pydantic v1.

The new docs will include Pydantic v2 and will use <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel</a> once it is updated to use Pydantic v2 as well.

You can also use <a href="https://github.com/encode/databases" class="external-link" target="_blank">`encode/databases`</a> with **FastAPI** to connect to databases using `async` and `await`.

It is compatible with:
Expand Down
7 changes: 7 additions & 0 deletions docs/en/docs/advanced/nosql-databases.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# NoSQL (Distributed / Big Data) Databases

!!! info
These docs are about to be updated. 🎉

The current version assumes Pydantic v1.

The new docs will hopefully use Pydantic v2 and will use <a href="https://art049.github.io/odmantic/" class="external-link" target="_blank">ODMantic</a> with MongoDB.

**FastAPI** can also be integrated with any <abbr title="Distributed database (Big Data), also 'Not Only SQL'">NoSQL</abbr>.

Here we'll see an example using **<a href="https://www.couchbase.com/" class="external-link" target="_blank">Couchbase</a>**, a <abbr title="Document here refers to a JSON object (a dict), with keys and values, and those values can also be other JSON objects, arrays (lists), numbers, strings, booleans, etc.">document</abbr> based NoSQL database.
Expand Down
34 changes: 28 additions & 6 deletions docs/en/docs/advanced/path-operation-advanced-configuration.md
Original file line number Diff line number Diff line change
Expand Up @@ -150,19 +150,41 @@ And you could do this even if the data type in the request is not JSON.

For example, in this application we don't use FastAPI's integrated functionality to extract the JSON Schema from Pydantic models nor the automatic validation for JSON. In fact, we are declaring the request content type as YAML, not JSON:

```Python hl_lines="17-22 24"
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
=== "Pydantic v2"

```Python hl_lines="17-22 24"
{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```

=== "Pydantic v1"

```Python hl_lines="17-22 24"
{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
```

!!! info
In Pydantic version 1 the method to get the JSON Schema for a model was called `Item.schema()`, in Pydantic version 2, the method is called `Item.model_schema_json()`.

Nevertheless, although we are not using the default integrated functionality, we are still using a Pydantic model to manually generate the JSON Schema for the data that we want to receive in YAML.

Then we use the request directly, and extract the body as `bytes`. This means that FastAPI won't even try to parse the request payload as JSON.

And then in our code, we parse that YAML content directly, and then we are again using the same Pydantic model to validate the YAML content:

```Python hl_lines="26-33"
{!../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```
=== "Pydantic v2"

```Python hl_lines="26-33"
{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007.py!}
```

=== "Pydantic v1"

```Python hl_lines="26-33"
{!> ../../../docs_src/path_operation_advanced_configuration/tutorial007_pv1.py!}
```

!!! info
In Pydantic version 1 the method to parse and validate an object was `Item.parse_obj()`, in Pydantic version 2, the method is called `Item.model_validate()`.

!!! tip
Here we re-use the same Pydantic model.
Expand Down
72 changes: 62 additions & 10 deletions docs/en/docs/advanced/settings.md
Original file line number Diff line number Diff line change
Expand Up @@ -125,7 +125,34 @@ That means that any value read in Python from an environment variable will be a

## Pydantic `Settings`

Fortunately, Pydantic provides a great utility to handle these settings coming from environment variables with <a href="https://pydantic-docs.helpmanual.io/usage/settings/" class="external-link" target="_blank">Pydantic: Settings management</a>.
Fortunately, Pydantic provides a great utility to handle these settings coming from environment variables with <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" class="external-link" target="_blank">Pydantic: Settings management</a>.

### Install `pydantic-settings`

First, install the `pydantic-settings` package:

<div class="termy">

```console
$ pip install pydantic-settings
---> 100%
```

</div>

It also comes included when you install the `all` extras with:

<div class="termy">

```console
$ pip install "fastapi[all]"
---> 100%
```

</div>

!!! info
In Pydantic v1 it came included with the main package. Now it is distributed as this independent package so that you can choose to install it or not if you don't need that functionality.

### Create the `Settings` object

Expand All @@ -135,9 +162,20 @@ The same way as with Pydantic models, you declare class attributes with type ann

You can use all the same validation features and tools you use for Pydantic models, like different data types and additional validations with `Field()`.

```Python hl_lines="2 5-8 11"
{!../../../docs_src/settings/tutorial001.py!}
```
=== "Pydantic v2"

```Python hl_lines="2 5-8 11"
{!> ../../../docs_src/settings/tutorial001.py!}
```

=== "Pydantic v1"

!!! info
In Pydantic v1 you would import `BaseSettings` directly from `pydantic` instead of from `pydantic_settings`.

```Python hl_lines="2 5-8 11"
{!> ../../../docs_src/settings/tutorial001_pv1.py!}
```

!!! tip
If you want something quick to copy and paste, don't use this example, use the last one below.
Expand Down Expand Up @@ -306,14 +344,28 @@ APP_NAME="ChimichangApp"

And then update your `config.py` with:

```Python hl_lines="9-10"
{!../../../docs_src/settings/app03/config.py!}
```
=== "Pydantic v2"

```Python hl_lines="9"
{!> ../../../docs_src/settings/app03_an/config.py!}
```

Here we create a class `Config` inside of your Pydantic `Settings` class, and set the `env_file` to the filename with the dotenv file we want to use.
!!! tip
The `model_config` attribute is used just for Pydantic configuration. You can read more at <a href="https://docs.pydantic.dev/latest/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.

!!! tip
The `Config` class is used just for Pydantic configuration. You can read more at <a href="https://pydantic-docs.helpmanual.io/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>
=== "Pydantic v1"

```Python hl_lines="9-10"
{!> ../../../docs_src/settings/app03_an/config_pv1.py!}
```

!!! tip
The `Config` class is used just for Pydantic configuration. You can read more at <a href="https://docs.pydantic.dev/1.10/usage/model_config/" class="external-link" target="_blank">Pydantic Model Config</a>.

!!! info
In Pydantic version 1 the configuration was done in an internal class `Config`, in Pydantic version 2 it's done in an attribute `model_config`. This attribute takes a `dict`, and to get autocompletion and inline errors you can import and use `SettingsConfigDict` to define that `dict`.

Here we define the config `env_file` inside of your Pydantic `Settings` class, and set the value to the filename with the dotenv file we want to use.

### Creating the `Settings` only once with `lru_cache`

Expand Down
7 changes: 7 additions & 0 deletions docs/en/docs/advanced/sql-databases-peewee.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@

Feel free to skip this.

Peewee is not recommended with FastAPI as it doesn't play well with anything async Python. There are several better alternatives.

!!! info
These docs assume Pydantic v1.

Because Pewee doesn't play well with anything async and there are better alternatives, I won't update these docs for Pydantic v2, they are kept for now only for historical purposes.

If you are starting a project from scratch, you are probably better off with SQLAlchemy ORM ([SQL (Relational) Databases](../tutorial/sql-databases.md){.internal-link target=_blank}), or any other async ORM.

If you already have a code base that uses <a href="https://docs.peewee-orm.com/en/latest/" class="external-link" target="_blank">Peewee ORM</a>, you can check here how to use it with **FastAPI**.
Expand Down
7 changes: 7 additions & 0 deletions docs/en/docs/advanced/testing-database.md
Original file line number Diff line number Diff line change
@@ -1,5 +1,12 @@
# Testing a Database

!!! info
These docs are about to be updated. 🎉

The current version assumes Pydantic v1, and SQLAlchemy versions less than 2.0.

The new docs will include Pydantic v2 and will use <a href="https://sqlmodel.tiangolo.com/" class="external-link" target="_blank">SQLModel</a> (which is also based on SQLAlchemy) once it is updated to use Pydantic v2 as well.

You can use the same dependency overrides from [Testing Dependencies with Overrides](testing-dependencies.md){.internal-link target=_blank} to alter a database for testing.

You could want to set up a different database for testing, rollback the data after the tests, pre-fill it with some testing data, etc.
Expand Down
2 changes: 2 additions & 0 deletions docs/en/docs/index.md
Original file line number Diff line number Diff line change
Expand Up @@ -446,6 +446,8 @@ To understand more about it, see the section <a href="https://fastapi.tiangolo.c
Used by Pydantic:

* <a href="https://github.com/JoshData/python-email-validator" target="_blank"><code>email_validator</code></a> - for email validation.
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.

Used by Starlette:

Expand Down
73 changes: 73 additions & 0 deletions docs/en/docs/release-notes.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,79 @@

## Latest Changes

✨ Support for **Pydantic v2**

Pydantic version 2 has the **core** re-written in **Rust** and includes a lot of improvements and features, for example:

* Improved **correctness** in corner cases.
* **Safer** types.
* Better **performance** and **less energy** consumption.
* Better **extensibility**.
* etc.

...all this while keeping the **same Python API**. In most of the cases, for simple models, you can simply upgrade the Pydantic version and get all the benefits. 🚀

In some cases, for pure data validation and processing, you can get performance improvements of **20x** or more. This means 2,000% or more. 🤯

When you use **FastAPI**, there's a lot more going on, processing the request and response, handling dependencies, executing **your own code**, and particularly, **waiting for the network**. But you will probably still get some nice performance improvements just from the upgrade.

The focus of this release is **compatibility** with Pydantic v1 and v2, to make sure your current apps keep working. Later there will be more focus on refactors, correctness, code improvements, and then **performance** improvements. Some third-party early beta testers that ran benchmarks on the beta releases of FastAPI reported improvements of **2x - 3x**. Which is not bad for just doing `pip install --upgrade fastapi pydantic`. This was not an official benchmark and I didn't check it myself, but it's a good sign.

### Migration

Check out the [Pydantic migration guide](https://docs.pydantic.dev/2.0/migration/).

For the things that need changes in your Pydantic models, the Pydantic team built [`bump-pydantic`](https://github.com/pydantic/bump-pydantic).

A command line tool that will **process your code** and update most of the things **automatically** for you. Make sure you have your code in git first, and review each of the changes to make sure everything is correct before committing the changes.

### Pydantic v1

**This version of FastAPI still supports Pydantic v1**. And although Pydantic v1 will be deprecated at some point, ti will still be supported for a while.

This means that you can install the new Pydantic v2, and if something fails, you can install Pydantic v1 while you fix any problems you might have, but having the latest FastAPI.

There are **tests for both Pydantic v1 and v2**, and test **coverage** is kept at **100%**.

### Changes

* There are **new parameter** fields supported by Pydantic `Field()` for:

* `Path()`
* `Query()`
* `Header()`
* `Cookie()`
* `Body()`
* `Form()`
* `File()`

* The new parameter fields are:

* `default_factory`
* `alias_priority`
* `validation_alias`
* `serialization_alias`
* `discriminator`
* `strict`
* `multiple_of`
* `allow_inf_nan`
* `max_digits`
* `decimal_places`
* `json_schema_extra`

...you can read about them in the Pydantic docs.

* The parameter `regex` has been deprecated and replaced by `pattern`.
* You can read more about it in the docs for [Query Parameters and String Validations: Add regular expressions](https://fastapi.tiangolo.com/tutorial/query-params-str-validations/#add-regular-expressions).
* New Pydantic models use an improved and simplified attribute `model_config` that takes a simple dict instead of an internal class `Config` for their configuration.
* You can read more about it in the docs for [Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/).
* The attribute `schema_extra` for the internal class `Config` has been replaced by the key `json_schema_extra` in the new `model_config` dict.
* You can read more about it in the docs for [Declare Request Example Data](https://fastapi.tiangolo.com/tutorial/schema-extra-example/).
* When you install `"fastapi[all]"` it now also includes:
* <a href="https://docs.pydantic.dev/latest/usage/pydantic_settings/" target="_blank"><code>pydantic-settings</code></a> - for settings management.
* <a href="https://docs.pydantic.dev/latest/usage/types/extra_types/extra_types/" target="_blank"><code>pydantic-extra-types</code></a> - for extra types to be used with Pydantic.
* Now Pydantic Settings is an additional optional package (included in `"fastapi[all]"`). To use settings you should now import `from pydantic_settings import BaseSettings` instead of importing from `pydantic` directly.
* You can read more about it in the docs for [Settings and Environment Variables](https://fastapi.tiangolo.com/advanced/settings/).

## 0.99.1

Expand Down
18 changes: 16 additions & 2 deletions docs/en/docs/tutorial/query-params-str-validations.md
Original file line number Diff line number Diff line change
Expand Up @@ -277,7 +277,7 @@ You can also add a parameter `min_length`:

## Add regular expressions

You can define a <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr> that the parameter should match:
You can define a <abbr title="A regular expression, regex or regexp is a sequence of characters that define a search pattern for strings.">regular expression</abbr> `pattern` that the parameter should match:

=== "Python 3.10+"

Expand Down Expand Up @@ -315,7 +315,7 @@ You can define a <abbr title="A regular expression, regex or regexp is a sequenc
{!> ../../../docs_src/query_params_str_validations/tutorial004.py!}
```

This specific regular expression checks that the received parameter value:
This specific regular expression pattern checks that the received parameter value:

* `^`: starts with the following characters, doesn't have characters before.
* `fixedquery`: has the exact value `fixedquery`.
Expand All @@ -325,6 +325,20 @@ If you feel lost with all these **"regular expression"** ideas, don't worry. The

But whenever you need them and go and learn them, know that you can already use them directly in **FastAPI**.

### Pydantic v1 `regex` instead of `pattern`

Before Pydantic version 2 and before FastAPI 0.100.0, the parameter was called `regex` instead of `pattern`, but it's now deprecated.

You could still see some code using it:

=== "Python 3.10+ Pydantic v1"

```Python hl_lines="11"
{!> ../../../docs_src/query_params_str_validations/tutorial004_an_py310_regex.py!}
```

But know that this is deprecated and it should be updated to use the new parameter `pattern`. 🤓

## Default values

You can, of course, use default values other than `None`.
Expand Down
Loading

0 comments on commit 0976185

Please sign in to comment.