]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
📝 Update source examples and docs from Python 3.9 to 3.10 (#14900)
authorSebastián Ramírez <tiangolo@gmail.com>
Thu, 12 Feb 2026 13:19:43 +0000 (05:19 -0800)
committerGitHub <noreply@github.com>
Thu, 12 Feb 2026 13:19:43 +0000 (14:19 +0100)
655 files changed:
docs/en/docs/advanced/additional-responses.md
docs/en/docs/advanced/advanced-dependencies.md
docs/en/docs/advanced/async-tests.md
docs/en/docs/advanced/behind-a-proxy.md
docs/en/docs/advanced/custom-response.md
docs/en/docs/advanced/events.md
docs/en/docs/advanced/generate-clients.md
docs/en/docs/advanced/middleware.md
docs/en/docs/advanced/openapi-webhooks.md
docs/en/docs/advanced/path-operation-advanced-configuration.md
docs/en/docs/advanced/response-change-status-code.md
docs/en/docs/advanced/response-cookies.md
docs/en/docs/advanced/response-directly.md
docs/en/docs/advanced/response-headers.md
docs/en/docs/advanced/security/http-basic-auth.md
docs/en/docs/advanced/settings.md
docs/en/docs/advanced/sub-applications.md
docs/en/docs/advanced/templates.md
docs/en/docs/advanced/testing-events.md
docs/en/docs/advanced/testing-websockets.md
docs/en/docs/advanced/using-request-directly.md
docs/en/docs/advanced/websockets.md
docs/en/docs/advanced/wsgi.md
docs/en/docs/how-to/authentication-error-status-code.md
docs/en/docs/how-to/conditional-openapi.md
docs/en/docs/how-to/configure-swagger-ui.md
docs/en/docs/how-to/custom-docs-ui-assets.md
docs/en/docs/how-to/extending-openapi.md
docs/en/docs/how-to/graphql.md
docs/en/docs/python-types.md
docs/en/docs/tutorial/background-tasks.md
docs/en/docs/tutorial/bigger-applications.md
docs/en/docs/tutorial/body-nested-models.md
docs/en/docs/tutorial/cors.md
docs/en/docs/tutorial/debugging.md
docs/en/docs/tutorial/dependencies/dependencies-in-path-operation-decorators.md
docs/en/docs/tutorial/dependencies/dependencies-with-yield.md
docs/en/docs/tutorial/dependencies/global-dependencies.md
docs/en/docs/tutorial/extra-models.md
docs/en/docs/tutorial/first-steps.md
docs/en/docs/tutorial/handling-errors.md
docs/en/docs/tutorial/metadata.md
docs/en/docs/tutorial/middleware.md
docs/en/docs/tutorial/path-operation-configuration.md
docs/en/docs/tutorial/path-params-numeric-validations.md
docs/en/docs/tutorial/path-params.md
docs/en/docs/tutorial/query-params-str-validations.md
docs/en/docs/tutorial/query-params.md
docs/en/docs/tutorial/request-files.md
docs/en/docs/tutorial/request-form-models.md
docs/en/docs/tutorial/request-forms-and-files.md
docs/en/docs/tutorial/request-forms.md
docs/en/docs/tutorial/response-model.md
docs/en/docs/tutorial/response-status-code.md
docs/en/docs/tutorial/security/first-steps.md
docs/en/docs/tutorial/security/get-current-user.md
docs/en/docs/tutorial/static-files.md
docs/en/docs/tutorial/testing.md
docs_src/additional_responses/tutorial001_py310.py [new file with mode: 0644]
docs_src/additional_responses/tutorial002_py39.py [deleted file]
docs_src/additional_responses/tutorial003_py310.py [new file with mode: 0644]
docs_src/additional_responses/tutorial004_py39.py [deleted file]
docs_src/additional_status_codes/tutorial001_an_py39.py [deleted file]
docs_src/additional_status_codes/tutorial001_py39.py [deleted file]
docs_src/advanced_middleware/tutorial001_py310.py [new file with mode: 0644]
docs_src/advanced_middleware/tutorial002_py310.py [new file with mode: 0644]
docs_src/advanced_middleware/tutorial003_py310.py [new file with mode: 0644]
docs_src/app_testing/app_a_py310/__init__.py [moved from docs_src/app_testing/app_b_an_py39/__init__.py with 100% similarity]
docs_src/app_testing/app_a_py310/main.py [new file with mode: 0644]
docs_src/app_testing/app_a_py310/test_main.py [new file with mode: 0644]
docs_src/app_testing/app_b_an_py39/main.py [deleted file]
docs_src/app_testing/app_b_an_py39/test_main.py [deleted file]
docs_src/app_testing/app_b_py39/main.py [deleted file]
docs_src/app_testing/app_b_py39/test_main.py [deleted file]
docs_src/app_testing/tutorial001_py310.py [new file with mode: 0644]
docs_src/app_testing/tutorial002_py310.py [new file with mode: 0644]
docs_src/app_testing/tutorial003_py310.py [new file with mode: 0644]
docs_src/app_testing/tutorial004_py310.py [new file with mode: 0644]
docs_src/async_tests/app_a_py310/__init__.py [moved from docs_src/app_testing/app_b_py39/__init__.py with 100% similarity]
docs_src/async_tests/app_a_py310/main.py [new file with mode: 0644]
docs_src/async_tests/app_a_py310/test_main.py [new file with mode: 0644]
docs_src/authentication_error_status_code/tutorial001_an_py310.py [new file with mode: 0644]
docs_src/background_tasks/tutorial001_py310.py [new file with mode: 0644]
docs_src/background_tasks/tutorial002_an_py39.py [deleted file]
docs_src/background_tasks/tutorial002_py39.py [deleted file]
docs_src/behind_a_proxy/tutorial001_01_py310.py [new file with mode: 0644]
docs_src/behind_a_proxy/tutorial001_py310.py [new file with mode: 0644]
docs_src/behind_a_proxy/tutorial002_py310.py [new file with mode: 0644]
docs_src/behind_a_proxy/tutorial003_py310.py [new file with mode: 0644]
docs_src/behind_a_proxy/tutorial004_py310.py [new file with mode: 0644]
docs_src/bigger_applications/app_an_py310/__init__.py [moved from docs_src/bigger_applications/app_py39/internal/__init__.py with 100% similarity]
docs_src/bigger_applications/app_an_py310/dependencies.py [new file with mode: 0644]
docs_src/bigger_applications/app_an_py310/internal/__init__.py [moved from docs_src/bigger_applications/app_py39/routers/__init__.py with 100% similarity]
docs_src/bigger_applications/app_an_py310/internal/admin.py [moved from docs_src/bigger_applications/app_py39/internal/admin.py with 100% similarity]
docs_src/bigger_applications/app_an_py310/main.py [new file with mode: 0644]
docs_src/bigger_applications/app_an_py310/routers/__init__.py [new file with mode: 0644]
docs_src/bigger_applications/app_an_py310/routers/items.py [moved from docs_src/bigger_applications/app_py39/routers/items.py with 100% similarity]
docs_src/bigger_applications/app_an_py310/routers/users.py [moved from docs_src/bigger_applications/app_py39/routers/users.py with 100% similarity]
docs_src/body/tutorial001_py39.py [deleted file]
docs_src/body/tutorial002_py39.py [deleted file]
docs_src/body/tutorial003_py39.py [deleted file]
docs_src/body/tutorial004_py39.py [deleted file]
docs_src/body_fields/tutorial001_an_py39.py [deleted file]
docs_src/body_fields/tutorial001_py39.py [deleted file]
docs_src/body_multiple_params/tutorial001_an_py39.py [deleted file]
docs_src/body_multiple_params/tutorial001_py39.py [deleted file]
docs_src/body_multiple_params/tutorial002_py39.py [deleted file]
docs_src/body_multiple_params/tutorial003_an_py39.py [deleted file]
docs_src/body_multiple_params/tutorial003_py39.py [deleted file]
docs_src/body_multiple_params/tutorial004_an_py39.py [deleted file]
docs_src/body_multiple_params/tutorial004_py39.py [deleted file]
docs_src/body_multiple_params/tutorial005_an_py39.py [deleted file]
docs_src/body_multiple_params/tutorial005_py39.py [deleted file]
docs_src/body_nested_models/tutorial001_py39.py [deleted file]
docs_src/body_nested_models/tutorial002_py39.py [deleted file]
docs_src/body_nested_models/tutorial003_py39.py [deleted file]
docs_src/body_nested_models/tutorial004_py39.py [deleted file]
docs_src/body_nested_models/tutorial005_py39.py [deleted file]
docs_src/body_nested_models/tutorial006_py39.py [deleted file]
docs_src/body_nested_models/tutorial007_py39.py [deleted file]
docs_src/body_nested_models/tutorial008_py310.py [new file with mode: 0644]
docs_src/body_nested_models/tutorial009_py310.py [new file with mode: 0644]
docs_src/body_updates/tutorial001_py39.py [deleted file]
docs_src/body_updates/tutorial002_py39.py [deleted file]
docs_src/conditional_openapi/tutorial001_py310.py [new file with mode: 0644]
docs_src/configure_swagger_ui/tutorial001_py310.py [new file with mode: 0644]
docs_src/configure_swagger_ui/tutorial002_py310.py [new file with mode: 0644]
docs_src/configure_swagger_ui/tutorial003_py310.py [new file with mode: 0644]
docs_src/cookie_param_models/tutorial001_an_py39.py [deleted file]
docs_src/cookie_param_models/tutorial001_py39.py [deleted file]
docs_src/cookie_param_models/tutorial002_an_py39.py [deleted file]
docs_src/cookie_param_models/tutorial002_py39.py [deleted file]
docs_src/cookie_params/tutorial001_an_py39.py [deleted file]
docs_src/cookie_params/tutorial001_py39.py [deleted file]
docs_src/cors/tutorial001_py310.py [new file with mode: 0644]
docs_src/custom_docs_ui/tutorial001_py310.py [new file with mode: 0644]
docs_src/custom_docs_ui/tutorial002_py310.py [new file with mode: 0644]
docs_src/custom_request_and_route/tutorial001_an_py39.py [deleted file]
docs_src/custom_request_and_route/tutorial001_py39.py [deleted file]
docs_src/custom_request_and_route/tutorial002_an_py39.py [deleted file]
docs_src/custom_request_and_route/tutorial002_py39.py [deleted file]
docs_src/custom_request_and_route/tutorial003_py39.py [deleted file]
docs_src/custom_response/tutorial001_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial001b_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial002_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial003_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial004_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial005_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial006_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial006b_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial006c_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial007_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial008_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial009_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial009b_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial009c_py310.py [new file with mode: 0644]
docs_src/custom_response/tutorial010_py310.py [new file with mode: 0644]
docs_src/dataclasses_/tutorial001_py39.py [deleted file]
docs_src/dataclasses_/tutorial002_py39.py [deleted file]
docs_src/dataclasses_/tutorial003_py39.py [deleted file]
docs_src/debugging/tutorial001_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial001_02_an_py39.py [deleted file]
docs_src/dependencies/tutorial001_an_py39.py [deleted file]
docs_src/dependencies/tutorial001_py39.py [deleted file]
docs_src/dependencies/tutorial002_an_py39.py [deleted file]
docs_src/dependencies/tutorial002_py39.py [deleted file]
docs_src/dependencies/tutorial003_an_py39.py [deleted file]
docs_src/dependencies/tutorial003_py39.py [deleted file]
docs_src/dependencies/tutorial004_an_py39.py [deleted file]
docs_src/dependencies/tutorial004_py39.py [deleted file]
docs_src/dependencies/tutorial005_an_py39.py [deleted file]
docs_src/dependencies/tutorial005_py39.py [deleted file]
docs_src/dependencies/tutorial006_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial006_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial007_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008b_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008b_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008c_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008c_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008d_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008d_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008e_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial008e_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial010_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial011_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial011_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial012_an_py310.py [new file with mode: 0644]
docs_src/dependencies/tutorial012_py310.py [new file with mode: 0644]
docs_src/dependency_testing/tutorial001_an_py39.py [deleted file]
docs_src/dependency_testing/tutorial001_py39.py [deleted file]
docs_src/encoder/tutorial001_py39.py [deleted file]
docs_src/events/tutorial001_py310.py [new file with mode: 0644]
docs_src/events/tutorial002_py310.py [new file with mode: 0644]
docs_src/events/tutorial003_py310.py [new file with mode: 0644]
docs_src/extending_openapi/tutorial001_py310.py [new file with mode: 0644]
docs_src/extra_data_types/tutorial001_an_py39.py [deleted file]
docs_src/extra_data_types/tutorial001_py39.py [deleted file]
docs_src/extra_models/tutorial001_py39.py [deleted file]
docs_src/extra_models/tutorial002_py39.py [deleted file]
docs_src/extra_models/tutorial003_py39.py [deleted file]
docs_src/extra_models/tutorial004_py310.py [new file with mode: 0644]
docs_src/extra_models/tutorial005_py310.py [new file with mode: 0644]
docs_src/first_steps/tutorial001_py310.py [new file with mode: 0644]
docs_src/first_steps/tutorial003_py310.py [new file with mode: 0644]
docs_src/generate_clients/tutorial001_py310.py [new file with mode: 0644]
docs_src/generate_clients/tutorial002_py310.py [new file with mode: 0644]
docs_src/generate_clients/tutorial003_py310.py [new file with mode: 0644]
docs_src/generate_clients/tutorial004_py310.py [new file with mode: 0644]
docs_src/graphql_/tutorial001_py310.py [new file with mode: 0644]
docs_src/handling_errors/tutorial001_py310.py [new file with mode: 0644]
docs_src/handling_errors/tutorial002_py310.py [new file with mode: 0644]
docs_src/handling_errors/tutorial003_py310.py [new file with mode: 0644]
docs_src/handling_errors/tutorial004_py310.py [new file with mode: 0644]
docs_src/handling_errors/tutorial005_py310.py [new file with mode: 0644]
docs_src/handling_errors/tutorial006_py310.py [new file with mode: 0644]
docs_src/header_param_models/tutorial001_an_py39.py [deleted file]
docs_src/header_param_models/tutorial001_py39.py [deleted file]
docs_src/header_param_models/tutorial002_an_py39.py [deleted file]
docs_src/header_param_models/tutorial002_py39.py [deleted file]
docs_src/header_param_models/tutorial003_an_py39.py [deleted file]
docs_src/header_param_models/tutorial003_py39.py [deleted file]
docs_src/header_params/tutorial001_an_py39.py [deleted file]
docs_src/header_params/tutorial001_py39.py [deleted file]
docs_src/header_params/tutorial002_an_py39.py [deleted file]
docs_src/header_params/tutorial002_py39.py [deleted file]
docs_src/header_params/tutorial003_an_py39.py [deleted file]
docs_src/header_params/tutorial003_py39.py [deleted file]
docs_src/metadata/tutorial001_1_py310.py [new file with mode: 0644]
docs_src/metadata/tutorial001_py310.py [new file with mode: 0644]
docs_src/metadata/tutorial002_py310.py [new file with mode: 0644]
docs_src/metadata/tutorial003_py310.py [new file with mode: 0644]
docs_src/metadata/tutorial004_py310.py [new file with mode: 0644]
docs_src/middleware/tutorial001_py310.py [new file with mode: 0644]
docs_src/openapi_callbacks/tutorial001_py39.py [deleted file]
docs_src/openapi_webhooks/tutorial001_py310.py [new file with mode: 0644]
docs_src/path_operation_advanced_configuration/tutorial001_py310.py [new file with mode: 0644]
docs_src/path_operation_advanced_configuration/tutorial002_py310.py [new file with mode: 0644]
docs_src/path_operation_advanced_configuration/tutorial003_py310.py [new file with mode: 0644]
docs_src/path_operation_advanced_configuration/tutorial004_py39.py [deleted file]
docs_src/path_operation_advanced_configuration/tutorial005_py310.py [new file with mode: 0644]
docs_src/path_operation_advanced_configuration/tutorial006_py310.py [new file with mode: 0644]
docs_src/path_operation_advanced_configuration/tutorial007_py310.py [moved from docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py with 68% similarity]
docs_src/path_operation_configuration/tutorial001_py39.py [deleted file]
docs_src/path_operation_configuration/tutorial002_py39.py [deleted file]
docs_src/path_operation_configuration/tutorial002b_py310.py [new file with mode: 0644]
docs_src/path_operation_configuration/tutorial003_py39.py [deleted file]
docs_src/path_operation_configuration/tutorial004_py39.py [deleted file]
docs_src/path_operation_configuration/tutorial005_py39.py [deleted file]
docs_src/path_operation_configuration/tutorial006_py310.py [new file with mode: 0644]
docs_src/path_params/tutorial001_py310.py [new file with mode: 0644]
docs_src/path_params/tutorial002_py310.py [new file with mode: 0644]
docs_src/path_params/tutorial003_py310.py [new file with mode: 0644]
docs_src/path_params/tutorial003b_py310.py [new file with mode: 0644]
docs_src/path_params/tutorial004_py310.py [new file with mode: 0644]
docs_src/path_params/tutorial005_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial002_an_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial002_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial003_an_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial003_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial004_an_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial004_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial005_an_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial005_py310.py [new file with mode: 0644]
docs_src/path_params_numeric_validations/tutorial006_an_py310.py [moved from docs_src/path_params_numeric_validations/tutorial001_an_py39.py with 61% similarity]
docs_src/path_params_numeric_validations/tutorial006_py310.py [moved from docs_src/path_params_numeric_validations/tutorial001_py39.py with 53% similarity]
docs_src/pydantic_v1_in_v2/tutorial001_an_py39.py [deleted file]
docs_src/pydantic_v1_in_v2/tutorial002_an_py39.py [deleted file]
docs_src/pydantic_v1_in_v2/tutorial003_an_py39.py [deleted file]
docs_src/pydantic_v1_in_v2/tutorial004_an_py39.py [deleted file]
docs_src/python_types/tutorial001_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial002_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial003_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial004_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial005_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial006_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial007_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial008_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial010_py310.py [new file with mode: 0644]
docs_src/python_types/tutorial011_py39.py [deleted file]
docs_src/python_types/tutorial012_py39.py [deleted file]
docs_src/python_types/tutorial013_py310.py [new file with mode: 0644]
docs_src/query_param_models/tutorial001_an_py39.py [deleted file]
docs_src/query_param_models/tutorial001_py39.py [deleted file]
docs_src/query_param_models/tutorial002_an_py39.py [deleted file]
docs_src/query_param_models/tutorial002_py39.py [deleted file]
docs_src/query_params/tutorial001_py310.py [new file with mode: 0644]
docs_src/query_params/tutorial002_py39.py [deleted file]
docs_src/query_params/tutorial003_py39.py [deleted file]
docs_src/query_params/tutorial004_py39.py [deleted file]
docs_src/query_params/tutorial005_py310.py [new file with mode: 0644]
docs_src/query_params/tutorial006_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial001_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial002_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial003_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial003_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial004_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial004_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial004_regex_an_py310.py [deleted file]
docs_src/query_params_str_validations/tutorial005_an_py310.py [moved from docs_src/query_params_str_validations/tutorial002_py39.py with 65% similarity]
docs_src/query_params_str_validations/tutorial005_py310.py [moved from docs_src/query_params_str_validations/tutorial009_py39.py with 64% similarity]
docs_src/query_params_str_validations/tutorial006_an_py310.py [moved from docs_src/query_params_str_validations/tutorial006c_py39.py with 69% similarity]
docs_src/query_params_str_validations/tutorial006_py310.py [moved from docs_src/query_params_str_validations/tutorial006c_an_py39.py with 64% similarity]
docs_src/query_params_str_validations/tutorial007_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial007_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial008_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial008_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial009_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial010_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial010_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial012_an_py310.py [moved from docs_src/query_params_str_validations/tutorial011_an_py39.py with 52% similarity]
docs_src/query_params_str_validations/tutorial012_py310.py [new file with mode: 0644]
docs_src/query_params_str_validations/tutorial013_an_py310.py [moved from docs_src/query_params_str_validations/tutorial011_py39.py with 56% similarity]
docs_src/query_params_str_validations/tutorial013_py310.py [new file with mode: 0644]
docs_src/query_params_str_validations/tutorial014_an_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial014_py39.py [deleted file]
docs_src/query_params_str_validations/tutorial015_an_py39.py [deleted file]
docs_src/request_files/tutorial001_02_an_py39.py [deleted file]
docs_src/request_files/tutorial001_02_py39.py [deleted file]
docs_src/request_files/tutorial001_03_an_py310.py [new file with mode: 0644]
docs_src/request_files/tutorial001_03_py310.py [new file with mode: 0644]
docs_src/request_files/tutorial001_an_py310.py [new file with mode: 0644]
docs_src/request_files/tutorial001_py310.py [new file with mode: 0644]
docs_src/request_files/tutorial002_an_py310.py [new file with mode: 0644]
docs_src/request_files/tutorial002_py310.py [new file with mode: 0644]
docs_src/request_files/tutorial003_an_py310.py [new file with mode: 0644]
docs_src/request_files/tutorial003_py310.py [new file with mode: 0644]
docs_src/request_form_models/tutorial001_an_py310.py [new file with mode: 0644]
docs_src/request_form_models/tutorial001_py310.py [new file with mode: 0644]
docs_src/request_form_models/tutorial002_an_py310.py [new file with mode: 0644]
docs_src/request_form_models/tutorial002_py310.py [new file with mode: 0644]
docs_src/request_forms/tutorial001_an_py310.py [new file with mode: 0644]
docs_src/request_forms/tutorial001_py310.py [new file with mode: 0644]
docs_src/request_forms_and_files/tutorial001_an_py310.py [new file with mode: 0644]
docs_src/request_forms_and_files/tutorial001_py310.py [new file with mode: 0644]
docs_src/response_change_status_code/tutorial001_py310.py [new file with mode: 0644]
docs_src/response_cookies/tutorial001_py310.py [new file with mode: 0644]
docs_src/response_cookies/tutorial002_py310.py [new file with mode: 0644]
docs_src/response_directly/tutorial001_py39.py [deleted file]
docs_src/response_directly/tutorial002_py310.py [new file with mode: 0644]
docs_src/response_headers/tutorial001_py310.py [new file with mode: 0644]
docs_src/response_headers/tutorial002_py310.py [new file with mode: 0644]
docs_src/response_model/tutorial001_01_py39.py [deleted file]
docs_src/response_model/tutorial001_py39.py [deleted file]
docs_src/response_model/tutorial002_py39.py [deleted file]
docs_src/response_model/tutorial003_01_py39.py [deleted file]
docs_src/response_model/tutorial003_02_py310.py [new file with mode: 0644]
docs_src/response_model/tutorial003_03_py310.py [new file with mode: 0644]
docs_src/response_model/tutorial003_04_py39.py [deleted file]
docs_src/response_model/tutorial003_05_py39.py [deleted file]
docs_src/response_model/tutorial003_py39.py [deleted file]
docs_src/response_model/tutorial004_py39.py [deleted file]
docs_src/response_model/tutorial005_py39.py [deleted file]
docs_src/response_model/tutorial006_py39.py [deleted file]
docs_src/response_status_code/tutorial001_py310.py [new file with mode: 0644]
docs_src/response_status_code/tutorial002_py310.py [new file with mode: 0644]
docs_src/schema_extra_example/tutorial001_pv1_py310.py [deleted file]
docs_src/schema_extra_example/tutorial001_pv1_py39.py [deleted file]
docs_src/schema_extra_example/tutorial001_py39.py [deleted file]
docs_src/schema_extra_example/tutorial002_py39.py [deleted file]
docs_src/schema_extra_example/tutorial003_an_py39.py [deleted file]
docs_src/schema_extra_example/tutorial003_py39.py [deleted file]
docs_src/schema_extra_example/tutorial004_an_py39.py [deleted file]
docs_src/schema_extra_example/tutorial004_py39.py [deleted file]
docs_src/schema_extra_example/tutorial005_an_py39.py [deleted file]
docs_src/schema_extra_example/tutorial005_py39.py [deleted file]
docs_src/security/tutorial001_an_py310.py [new file with mode: 0644]
docs_src/security/tutorial001_py310.py [new file with mode: 0644]
docs_src/security/tutorial002_an_py39.py [deleted file]
docs_src/security/tutorial002_py39.py [deleted file]
docs_src/security/tutorial003_an_py39.py [deleted file]
docs_src/security/tutorial003_py39.py [deleted file]
docs_src/security/tutorial004_an_py39.py [deleted file]
docs_src/security/tutorial004_py39.py [deleted file]
docs_src/security/tutorial005_an_py39.py [deleted file]
docs_src/security/tutorial005_py39.py [deleted file]
docs_src/security/tutorial006_an_py310.py [new file with mode: 0644]
docs_src/security/tutorial006_py310.py [new file with mode: 0644]
docs_src/security/tutorial007_an_py310.py [new file with mode: 0644]
docs_src/security/tutorial007_py310.py [new file with mode: 0644]
docs_src/separate_openapi_schemas/tutorial001_py39.py [deleted file]
docs_src/separate_openapi_schemas/tutorial002_py39.py [deleted file]
docs_src/settings/app01_py310/__init__.py [new file with mode: 0644]
docs_src/settings/app01_py310/config.py [moved from docs_src/settings/app03_an_py39/config_pv1.py with 59% similarity]
docs_src/settings/app01_py310/main.py [new file with mode: 0644]
docs_src/settings/app02_an_py310/__init__.py [new file with mode: 0644]
docs_src/settings/app02_an_py310/config.py [moved from docs_src/settings/app03_py39/config_pv1.py with 58% similarity]
docs_src/settings/app02_an_py310/main.py [new file with mode: 0644]
docs_src/settings/app02_an_py310/test_main.py [new file with mode: 0644]
docs_src/settings/app02_py310/__init__.py [new file with mode: 0644]
docs_src/settings/app02_py310/config.py [new file with mode: 0644]
docs_src/settings/app02_py310/main.py [new file with mode: 0644]
docs_src/settings/app02_py310/test_main.py [new file with mode: 0644]
docs_src/settings/app03_an_py310/__init__.py [new file with mode: 0644]
docs_src/settings/app03_an_py310/config.py [new file with mode: 0644]
docs_src/settings/app03_an_py310/main.py [new file with mode: 0644]
docs_src/settings/app03_py310/__init__.py [new file with mode: 0644]
docs_src/settings/app03_py310/config.py [new file with mode: 0644]
docs_src/settings/app03_py310/main.py [new file with mode: 0644]
docs_src/settings/tutorial001_py310.py [moved from docs_src/settings/tutorial001_pv1_py39.py with 89% similarity]
docs_src/sql_databases/tutorial001_an_py39.py [deleted file]
docs_src/sql_databases/tutorial001_py39.py [deleted file]
docs_src/sql_databases/tutorial002_an_py39.py [deleted file]
docs_src/sql_databases/tutorial002_py39.py [deleted file]
docs_src/static_files/tutorial001_py310.py [new file with mode: 0644]
docs_src/sub_applications/tutorial001_py310.py [new file with mode: 0644]
docs_src/templates/tutorial001_py310.py [new file with mode: 0644]
docs_src/using_request_directly/tutorial001_py310.py [new file with mode: 0644]
docs_src/websockets/tutorial001_py310.py [new file with mode: 0644]
docs_src/websockets/tutorial002_an_py39.py [deleted file]
docs_src/websockets/tutorial002_py39.py [deleted file]
docs_src/websockets/tutorial003_py310.py [new file with mode: 0644]
docs_src/wsgi/tutorial001_py310.py [new file with mode: 0644]
pyproject.toml
tests/test_tutorial/test_additional_responses/test_tutorial001.py
tests/test_tutorial/test_additional_responses/test_tutorial002.py
tests/test_tutorial/test_additional_responses/test_tutorial003.py
tests/test_tutorial/test_additional_responses/test_tutorial004.py
tests/test_tutorial/test_additional_status_codes/test_tutorial001.py
tests/test_tutorial/test_advanced_middleware/test_tutorial001.py
tests/test_tutorial/test_advanced_middleware/test_tutorial002.py
tests/test_tutorial/test_advanced_middleware/test_tutorial003.py
tests/test_tutorial/test_async_tests/test_main_a.py
tests/test_tutorial/test_authentication_error_status_code/test_tutorial001.py
tests/test_tutorial/test_background_tasks/test_tutorial001.py
tests/test_tutorial/test_background_tasks/test_tutorial002.py
tests/test_tutorial/test_behind_a_proxy/test_tutorial001.py
tests/test_tutorial/test_behind_a_proxy/test_tutorial001_01.py
tests/test_tutorial/test_behind_a_proxy/test_tutorial002.py
tests/test_tutorial/test_behind_a_proxy/test_tutorial003.py
tests/test_tutorial/test_behind_a_proxy/test_tutorial004.py
tests/test_tutorial/test_bigger_applications/test_main.py
tests/test_tutorial/test_body/test_tutorial001.py
tests/test_tutorial/test_body/test_tutorial002.py
tests/test_tutorial/test_body/test_tutorial003.py
tests/test_tutorial/test_body/test_tutorial004.py
tests/test_tutorial/test_body_fields/test_tutorial001.py
tests/test_tutorial/test_body_multiple_params/test_tutorial001.py
tests/test_tutorial/test_body_multiple_params/test_tutorial002.py
tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
tests/test_tutorial/test_body_multiple_params/test_tutorial004.py
tests/test_tutorial/test_body_multiple_params/test_tutorial005.py
tests/test_tutorial/test_body_nested_models/test_tutorial001_tutorial002_tutorial003.py
tests/test_tutorial/test_body_nested_models/test_tutorial004.py
tests/test_tutorial/test_body_nested_models/test_tutorial005.py
tests/test_tutorial/test_body_nested_models/test_tutorial006.py
tests/test_tutorial/test_body_nested_models/test_tutorial007.py
tests/test_tutorial/test_body_nested_models/test_tutorial008.py
tests/test_tutorial/test_body_nested_models/test_tutorial009.py
tests/test_tutorial/test_body_updates/test_tutorial001.py
tests/test_tutorial/test_body_updates/test_tutorial002.py
tests/test_tutorial/test_conditional_openapi/test_tutorial001.py
tests/test_tutorial/test_configure_swagger_ui/test_tutorial001.py
tests/test_tutorial/test_configure_swagger_ui/test_tutorial002.py
tests/test_tutorial/test_configure_swagger_ui/test_tutorial003.py
tests/test_tutorial/test_cookie_param_models/test_tutorial001.py
tests/test_tutorial/test_cookie_param_models/test_tutorial002.py
tests/test_tutorial/test_cookie_params/test_tutorial001.py
tests/test_tutorial/test_cors/test_tutorial001.py
tests/test_tutorial/test_custom_docs_ui/test_tutorial001.py
tests/test_tutorial/test_custom_docs_ui/test_tutorial002.py
tests/test_tutorial/test_custom_request_and_route/test_tutorial001.py
tests/test_tutorial/test_custom_request_and_route/test_tutorial002.py
tests/test_tutorial/test_custom_request_and_route/test_tutorial003.py
tests/test_tutorial/test_custom_response/test_tutorial001.py
tests/test_tutorial/test_custom_response/test_tutorial001b.py
tests/test_tutorial/test_custom_response/test_tutorial002_tutorial003_tutorial004.py
tests/test_tutorial/test_custom_response/test_tutorial005.py
tests/test_tutorial/test_custom_response/test_tutorial006.py
tests/test_tutorial/test_custom_response/test_tutorial006b.py
tests/test_tutorial/test_custom_response/test_tutorial006c.py
tests/test_tutorial/test_custom_response/test_tutorial007.py
tests/test_tutorial/test_custom_response/test_tutorial008.py
tests/test_tutorial/test_custom_response/test_tutorial009.py
tests/test_tutorial/test_custom_response/test_tutorial009b.py
tests/test_tutorial/test_custom_response/test_tutorial009c.py
tests/test_tutorial/test_dataclasses/test_tutorial001.py
tests/test_tutorial/test_dataclasses/test_tutorial002.py
tests/test_tutorial/test_dataclasses/test_tutorial003.py
tests/test_tutorial/test_debugging/test_tutorial001.py
tests/test_tutorial/test_dependencies/test_tutorial001_tutorial001_02.py
tests/test_tutorial/test_dependencies/test_tutorial002_tutorial003_tutorial004.py
tests/test_tutorial/test_dependencies/test_tutorial005.py
tests/test_tutorial/test_dependencies/test_tutorial006.py
tests/test_tutorial/test_dependencies/test_tutorial007.py
tests/test_tutorial/test_dependencies/test_tutorial008.py
tests/test_tutorial/test_dependencies/test_tutorial008b.py
tests/test_tutorial/test_dependencies/test_tutorial008c.py
tests/test_tutorial/test_dependencies/test_tutorial008d.py
tests/test_tutorial/test_dependencies/test_tutorial008e.py
tests/test_tutorial/test_dependencies/test_tutorial010.py
tests/test_tutorial/test_dependencies/test_tutorial011.py
tests/test_tutorial/test_dependencies/test_tutorial012.py
tests/test_tutorial/test_encoder/test_tutorial001.py
tests/test_tutorial/test_events/test_tutorial001.py
tests/test_tutorial/test_events/test_tutorial002.py
tests/test_tutorial/test_events/test_tutorial003.py
tests/test_tutorial/test_extending_openapi/test_tutorial001.py
tests/test_tutorial/test_extra_data_types/test_tutorial001.py
tests/test_tutorial/test_extra_models/test_tutorial001_tutorial002.py
tests/test_tutorial/test_extra_models/test_tutorial003.py
tests/test_tutorial/test_extra_models/test_tutorial004.py
tests/test_tutorial/test_extra_models/test_tutorial005.py
tests/test_tutorial/test_first_steps/test_tutorial001_tutorial002_tutorial003.py
tests/test_tutorial/test_generate_clients/test_tutorial001.py
tests/test_tutorial/test_generate_clients/test_tutorial002.py
tests/test_tutorial/test_generate_clients/test_tutorial003.py
tests/test_tutorial/test_generate_clients/test_tutorial004.py
tests/test_tutorial/test_graphql/test_tutorial001.py
tests/test_tutorial/test_handling_errors/test_tutorial001.py
tests/test_tutorial/test_handling_errors/test_tutorial002.py
tests/test_tutorial/test_handling_errors/test_tutorial003.py
tests/test_tutorial/test_handling_errors/test_tutorial004.py
tests/test_tutorial/test_handling_errors/test_tutorial005.py
tests/test_tutorial/test_handling_errors/test_tutorial006.py
tests/test_tutorial/test_header_param_models/test_tutorial001.py
tests/test_tutorial/test_header_param_models/test_tutorial002.py
tests/test_tutorial/test_header_param_models/test_tutorial003.py
tests/test_tutorial/test_header_params/test_tutorial001.py
tests/test_tutorial/test_header_params/test_tutorial002.py
tests/test_tutorial/test_header_params/test_tutorial003.py
tests/test_tutorial/test_metadata/test_tutorial001.py
tests/test_tutorial/test_metadata/test_tutorial001_1.py
tests/test_tutorial/test_metadata/test_tutorial002.py
tests/test_tutorial/test_metadata/test_tutorial003.py
tests/test_tutorial/test_metadata/test_tutorial004.py
tests/test_tutorial/test_middleware/test_tutorial001.py
tests/test_tutorial/test_openapi_callbacks/test_tutorial001.py
tests/test_tutorial/test_openapi_webhooks/test_tutorial001.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial001.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial002.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial003.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial004.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial005.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial006.py
tests/test_tutorial/test_path_operation_advanced_configurations/test_tutorial007.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial001.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial002.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial002b.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial003_tutorial004.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial005.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial006.py
tests/test_tutorial/test_path_params/test_tutorial001.py
tests/test_tutorial/test_path_params/test_tutorial002.py
tests/test_tutorial/test_path_params/test_tutorial003.py
tests/test_tutorial/test_path_params/test_tutorial003b.py
tests/test_tutorial/test_path_params/test_tutorial004.py
tests/test_tutorial/test_path_params/test_tutorial005.py
tests/test_tutorial/test_path_params_numeric_validations/test_tutorial001.py
tests/test_tutorial/test_path_params_numeric_validations/test_tutorial002_tutorial003.py
tests/test_tutorial/test_path_params_numeric_validations/test_tutorial004.py
tests/test_tutorial/test_path_params_numeric_validations/test_tutorial005.py
tests/test_tutorial/test_path_params_numeric_validations/test_tutorial006.py
tests/test_tutorial/test_python_types/test_tutorial001_tutorial002.py
tests/test_tutorial/test_python_types/test_tutorial003.py
tests/test_tutorial/test_python_types/test_tutorial004.py
tests/test_tutorial/test_python_types/test_tutorial005.py
tests/test_tutorial/test_python_types/test_tutorial006.py
tests/test_tutorial/test_python_types/test_tutorial007.py
tests/test_tutorial/test_python_types/test_tutorial008.py
tests/test_tutorial/test_python_types/test_tutorial008b.py
tests/test_tutorial/test_python_types/test_tutorial009_tutorial009b.py
tests/test_tutorial/test_python_types/test_tutorial009c.py
tests/test_tutorial/test_python_types/test_tutorial010.py
tests/test_tutorial/test_python_types/test_tutorial011.py
tests/test_tutorial/test_python_types/test_tutorial012.py [deleted file]
tests/test_tutorial/test_python_types/test_tutorial013.py
tests/test_tutorial/test_query_param_models/test_tutorial001.py
tests/test_tutorial/test_query_param_models/test_tutorial002.py
tests/test_tutorial/test_query_params/test_tutorial001.py
tests/test_tutorial/test_query_params/test_tutorial002.py
tests/test_tutorial/test_query_params/test_tutorial003.py
tests/test_tutorial/test_query_params/test_tutorial004.py
tests/test_tutorial/test_query_params/test_tutorial005.py
tests/test_tutorial/test_query_params/test_tutorial006.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial001.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial002.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial003.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial004.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial005.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial006.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial006c.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial007.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial008.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial009.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial010.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial011.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial012.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial013.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial014.py
tests/test_tutorial/test_query_params_str_validations/test_tutorial015.py
tests/test_tutorial/test_request_files/test_tutorial001.py
tests/test_tutorial/test_request_files/test_tutorial001_02.py
tests/test_tutorial/test_request_files/test_tutorial001_03.py
tests/test_tutorial/test_request_files/test_tutorial002.py
tests/test_tutorial/test_request_files/test_tutorial003.py
tests/test_tutorial/test_request_form_models/test_tutorial001.py
tests/test_tutorial/test_request_form_models/test_tutorial002.py
tests/test_tutorial/test_request_forms/test_tutorial001.py
tests/test_tutorial/test_request_forms_and_files/test_tutorial001.py
tests/test_tutorial/test_response_change_status_code/test_tutorial001.py
tests/test_tutorial/test_response_cookies/test_tutorial001.py
tests/test_tutorial/test_response_cookies/test_tutorial002.py
tests/test_tutorial/test_response_directly/test_tutorial001.py
tests/test_tutorial/test_response_directly/test_tutorial002.py
tests/test_tutorial/test_response_headers/test_tutorial001.py
tests/test_tutorial/test_response_headers/test_tutorial002.py
tests/test_tutorial/test_response_model/test_tutorial001_tutorial001_01.py
tests/test_tutorial/test_response_model/test_tutorial002.py
tests/test_tutorial/test_response_model/test_tutorial003.py
tests/test_tutorial/test_response_model/test_tutorial003_01.py
tests/test_tutorial/test_response_model/test_tutorial003_02.py
tests/test_tutorial/test_response_model/test_tutorial003_03.py
tests/test_tutorial/test_response_model/test_tutorial003_04.py
tests/test_tutorial/test_response_model/test_tutorial003_05.py
tests/test_tutorial/test_response_model/test_tutorial004.py
tests/test_tutorial/test_response_model/test_tutorial005.py
tests/test_tutorial/test_response_model/test_tutorial006.py
tests/test_tutorial/test_response_status_code/test_tutorial001_tutorial002.py
tests/test_tutorial/test_schema_extra_example/test_tutorial001.py
tests/test_tutorial/test_schema_extra_example/test_tutorial002.py
tests/test_tutorial/test_schema_extra_example/test_tutorial003.py
tests/test_tutorial/test_schema_extra_example/test_tutorial004.py
tests/test_tutorial/test_schema_extra_example/test_tutorial005.py
tests/test_tutorial/test_security/test_tutorial001.py
tests/test_tutorial/test_security/test_tutorial002.py
tests/test_tutorial/test_security/test_tutorial003.py
tests/test_tutorial/test_security/test_tutorial004.py
tests/test_tutorial/test_security/test_tutorial005.py
tests/test_tutorial/test_security/test_tutorial006.py
tests/test_tutorial/test_security/test_tutorial007.py
tests/test_tutorial/test_separate_openapi_schemas/test_tutorial001.py
tests/test_tutorial/test_separate_openapi_schemas/test_tutorial002.py
tests/test_tutorial/test_settings/test_app01.py
tests/test_tutorial/test_settings/test_app02.py
tests/test_tutorial/test_settings/test_app03.py
tests/test_tutorial/test_settings/test_tutorial001.py
tests/test_tutorial/test_sql_databases/test_tutorial001.py
tests/test_tutorial/test_sql_databases/test_tutorial002.py
tests/test_tutorial/test_static_files/test_tutorial001.py
tests/test_tutorial/test_sub_applications/test_tutorial001.py
tests/test_tutorial/test_templates/test_tutorial001.py
tests/test_tutorial/test_testing/test_main_a.py
tests/test_tutorial/test_testing/test_main_b.py
tests/test_tutorial/test_testing/test_tutorial001.py
tests/test_tutorial/test_testing/test_tutorial002.py
tests/test_tutorial/test_testing/test_tutorial003.py
tests/test_tutorial/test_testing/test_tutorial004.py
tests/test_tutorial/test_testing_dependencies/test_tutorial001.py
tests/test_tutorial/test_using_request_directly/test_tutorial001.py
tests/test_tutorial/test_websockets/test_tutorial001.py
tests/test_tutorial/test_websockets/test_tutorial002.py
tests/test_tutorial/test_websockets/test_tutorial003.py
tests/test_tutorial/test_wsgi/test_tutorial001.py

index bb70753edd185e3e250622fd567b517230f39318..6306bd1f9a9eb2594ccbadf51321a8a2d6886e3d 100644 (file)
@@ -26,7 +26,7 @@ Each of those response `dict`s can have a key `model`, containing a Pydantic mod
 
 For example, to declare another response with a status code `404` and a Pydantic model `Message`, you can write:
 
-{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py310.py hl[18,22] *}
 
 /// note
 
@@ -203,7 +203,7 @@ For example, you can declare a response with a status code `404` that uses a Pyd
 
 And a response with a status code `200` that uses your `response_model`, but includes a custom `example`:
 
-{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py310.py hl[20:31] *}
 
 It will all be combined and included in your OpenAPI, and shown in the API docs:
 
index 0d03507b7eee160d9e9a4ed4f12e3db9321b0ca3..3a23a6d1ad530abc74816467ac29159aeaf2a5bc 100644 (file)
@@ -18,7 +18,7 @@ Not the class itself (which is already a callable), but an instance of that clas
 
 To do that, we declare a method `__call__`:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[12] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[12] *}
 
 In this case, this `__call__` is what **FastAPI** will use to check for additional parameters and sub-dependencies, and this is what will be called to pass a value to the parameter in your *path operation function* later.
 
@@ -26,7 +26,7 @@ In this case, this `__call__` is what **FastAPI** will use to check for addition
 
 And now, we can use `__init__` to declare the parameters of the instance that we can use to "parameterize" the dependency:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[9] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[9] *}
 
 In this case, **FastAPI** won't ever touch or care about `__init__`, we will use it directly in our code.
 
@@ -34,7 +34,7 @@ In this case, **FastAPI** won't ever touch or care about `__init__`, we will use
 
 We could create an instance of this class with:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[18] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[18] *}
 
 And that way we are able to "parameterize" our dependency, that now has `"bar"` inside of it, as the attribute `checker.fixed_content`.
 
@@ -50,7 +50,7 @@ checker(q="somequery")
 
 ...and pass whatever that returns as the value of the dependency in our *path operation function* as the parameter `fixed_content_included`:
 
-{* ../../docs_src/dependencies/tutorial011_an_py39.py hl[22] *}
+{* ../../docs_src/dependencies/tutorial011_an_py310.py hl[22] *}
 
 /// tip
 
index 65ddc60b2d93a289698f0f31b7ac62b014ce17f0..cefb1d1841e290e8319e0ff3f4ca4cc47138f945 100644 (file)
@@ -32,11 +32,11 @@ For a simple example, let's consider a file structure similar to the one describ
 
 The file `main.py` would have:
 
-{* ../../docs_src/async_tests/app_a_py39/main.py *}
+{* ../../docs_src/async_tests/app_a_py310/main.py *}
 
 The file `test_main.py` would have the tests for `main.py`, it could look like this now:
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py *}
 
 ## Run it { #run-it }
 
@@ -56,7 +56,7 @@ $ pytest
 
 The marker `@pytest.mark.anyio` tells pytest that this test function should be called asynchronously:
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[7] *}
 
 /// tip
 
@@ -66,7 +66,7 @@ Note that the test function is now `async def` instead of just `def` as before w
 
 Then we can create an `AsyncClient` with the app, and send async requests to it, using `await`.
 
-{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py310/test_main.py hl[9:12] *}
 
 This is the equivalent to:
 
index 4fef02bd1c4c6ff31e684789caf0bcb78ea11829..770e9cd3cafd9c19d6ac1d09f4458fc0acf0eef2 100644 (file)
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
 
 For example, let's say you define a *path operation* `/items/`:
 
-{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py310.py hl[6] *}
 
 If the client tries to go to `/items`, by default, it would be redirected to `/items/`.
 
@@ -115,7 +115,7 @@ In this case, the original path `/app` would actually be served at `/api/v1/app`
 
 Even though all your code is written assuming there's just `/app`.
 
-{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[6] *}
 
 And the proxy would be **"stripping"** the **path prefix** on the fly before transmitting the request to the app server (probably Uvicorn via FastAPI CLI), keeping your application convinced that it is being served at `/app`, so that you don't have to update all your code to include the prefix `/api/v1`.
 
@@ -193,7 +193,7 @@ You can get the current `root_path` used by your application for each request, i
 
 Here we are including it in the message just for demonstration purposes.
 
-{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py310.py hl[8] *}
 
 Then, if you start Uvicorn with:
 
@@ -220,7 +220,7 @@ The response would be something like:
 
 Alternatively, if you don't have a way to provide a command line option like `--root-path` or equivalent, you can set the `root_path` parameter when creating your FastAPI app:
 
-{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py310.py hl[3] *}
 
 Passing the `root_path` to `FastAPI` would be the equivalent of passing the `--root-path` command line option to Uvicorn or Hypercorn.
 
@@ -400,7 +400,7 @@ If you pass a custom list of `servers` and there's a `root_path` (because your A
 
 For example:
 
-{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py310.py hl[4:7] *}
 
 Will generate an OpenAPI schema like:
 
@@ -455,7 +455,7 @@ If you don't specify the `servers` parameter and `root_path` is equal to `/`, th
 
 If you don't want **FastAPI** to include an automatic server using the `root_path`, you can use the parameter `root_path_in_servers=False`:
 
-{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py310.py hl[9] *}
 
 and then it won't include it in the OpenAPI schema.
 
index e53409c39dfba8786bf5c9b5ccd0d87c4fd43cf2..8b4b3da339e7cfad2c3ad12ebc8dc641307da9b0 100644 (file)
@@ -30,7 +30,7 @@ This is because by default, FastAPI will inspect every item inside and make sure
 
 But if you are certain that the content that you are returning is **serializable with JSON**, you can pass it directly to the response class and avoid the extra overhead that FastAPI would have by passing your return content through the `jsonable_encoder` before passing it to the response class.
 
-{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py310.py hl[2,7] *}
 
 /// info
 
@@ -55,7 +55,7 @@ To return a response with HTML directly from **FastAPI**, use `HTMLResponse`.
 * Import `HTMLResponse`.
 * Pass `HTMLResponse` as the parameter `response_class` of your *path operation decorator*.
 
-{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py310.py hl[2,7] *}
 
 /// info
 
@@ -73,7 +73,7 @@ As seen in [Return a Response directly](response-directly.md){.internal-link tar
 
 The same example from above, returning an `HTMLResponse`, could look like:
 
-{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py310.py hl[2,7,19] *}
 
 /// warning
 
@@ -97,7 +97,7 @@ The `response_class` will then be used only to document the OpenAPI *path operat
 
 For example, it could be something like:
 
-{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py310.py hl[7,21,23] *}
 
 In this example, the function `generate_html_response()` already generates and returns a `Response` instead of returning the HTML in a `str`.
 
@@ -136,7 +136,7 @@ It accepts the following parameters:
 
 FastAPI (actually Starlette) will automatically include a Content-Length header. It will also include a Content-Type header, based on the `media_type` and appending a charset for text types.
 
-{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
 
 ### `HTMLResponse` { #htmlresponse }
 
@@ -146,7 +146,7 @@ Takes some text or bytes and returns an HTML response, as you read above.
 
 Takes some text or bytes and returns a plain text response.
 
-{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py310.py hl[2,7,9] *}
 
 ### `JSONResponse` { #jsonresponse }
 
@@ -180,7 +180,7 @@ This requires installing `ujson` for example with `pip install ujson`.
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py310.py hl[2,7] *}
 
 /// tip
 
@@ -194,14 +194,14 @@ Returns an HTTP redirect. Uses a 307 status code (Temporary Redirect) by default
 
 You can return a `RedirectResponse` directly:
 
-{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py310.py hl[2,9] *}
 
 ---
 
 Or you can use it in the `response_class` parameter:
 
 
-{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py310.py hl[2,7,9] *}
 
 If you do that, then you can return the URL directly from your *path operation* function.
 
@@ -211,13 +211,13 @@ In this case, the `status_code` used will be the default one for the `RedirectRe
 
 You can also use the `status_code` parameter combined with the `response_class` parameter:
 
-{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py310.py hl[2,7,9] *}
 
 ### `StreamingResponse` { #streamingresponse }
 
 Takes an async generator or a normal generator/iterator and streams the response body.
 
-{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py310.py hl[2,14] *}
 
 #### Using `StreamingResponse` with file-like objects { #using-streamingresponse-with-file-like-objects }
 
@@ -227,7 +227,7 @@ That way, you don't have to read it all first in memory, and you can pass that g
 
 This includes many libraries to interact with cloud storage, video processing, and others.
 
-{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py310.py hl[2,10:12,14] *}
 
 1. This is the generator function. It's a "generator function" because it contains `yield` statements inside.
 2. By using a `with` block, we make sure that the file-like object is closed after the generator function is done. So, after it finishes sending the response.
@@ -256,11 +256,11 @@ Takes a different set of arguments to instantiate than the other response types:
 
 File responses will include appropriate `Content-Length`, `Last-Modified` and `ETag` headers.
 
-{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py310.py hl[2,10] *}
 
 You can also use the `response_class` parameter:
 
-{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py310.py hl[2,8,10] *}
 
 In this case, you can return the file path directly from your *path operation* function.
 
@@ -274,7 +274,7 @@ Let's say you want it to return indented and formatted JSON, so you want to use
 
 You could create a `CustomORJSONResponse`. The main thing you have to do is create a `Response.render(content)` method that returns the content as `bytes`:
 
-{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py310.py hl[9:14,17] *}
 
 Now instead of returning:
 
@@ -300,7 +300,7 @@ The parameter that defines this is `default_response_class`.
 
 In the example below, **FastAPI** will use `ORJSONResponse` by default, in all *path operations*, instead of `JSONResponse`.
 
-{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py310.py hl[2,4] *}
 
 /// tip
 
index 9414b7a3f0a77debf64d36511133fdab66c7d527..302e96325185aff00d4e2bba55fd4e94aaf0afd5 100644 (file)
@@ -30,7 +30,7 @@ Let's start with an example and then see it in detail.
 
 We create an async function `lifespan()` with `yield` like this:
 
-{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[16,19] *}
 
 Here we are simulating the expensive *startup* operation of loading the model by putting the (fake) model function in the dictionary with machine learning models before the `yield`. This code will be executed **before** the application **starts taking requests**, during the *startup*.
 
@@ -48,7 +48,7 @@ Maybe you need to start a new version, or you just got tired of running it. 🤷
 
 The first thing to notice, is that we are defining an async function with `yield`. This is very similar to Dependencies with `yield`.
 
-{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[14:19] *}
 
 The first part of the function, before the `yield`, will be executed **before** the application starts.
 
@@ -60,7 +60,7 @@ If you check, the function is decorated with an `@asynccontextmanager`.
 
 That converts the function into something called an "**async context manager**".
 
-{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[1,13] *}
 
 A **context manager** in Python is something that you can use in a `with` statement, for example, `open()` can be used as a context manager:
 
@@ -82,7 +82,7 @@ In our code example above, we don't use it directly, but we pass it to FastAPI f
 
 The `lifespan` parameter of the `FastAPI` app takes an **async context manager**, so we can pass our new `lifespan` async context manager to it.
 
-{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py310.py hl[22] *}
 
 ## Alternative Events (deprecated) { #alternative-events-deprecated }
 
@@ -104,7 +104,7 @@ These functions can be declared with `async def` or normal `def`.
 
 To add a function that should be run before the application starts, declare it with the event `"startup"`:
 
-{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py310.py hl[8] *}
 
 In this case, the `startup` event handler function will initialize the items "database" (just a `dict`) with some values.
 
@@ -116,7 +116,7 @@ And your application won't start receiving requests until all the `startup` even
 
 To add a function that should be run when the application is shutting down, declare it with the event `"shutdown"`:
 
-{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py310.py hl[6] *}
 
 Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.
 
index 2d0c2aa0c919adbf8047c84fd564cf8121c3085e..1e6173c9ae39ad62396ac80ff9a3d64addd39b92 100644 (file)
@@ -40,7 +40,7 @@ Some of these solutions may also be open source or offer free tiers, so you can
 
 Let's start with a simple FastAPI application:
 
-{* ../../docs_src/generate_clients/tutorial001_py39.py hl[7:9,12:13,16:17,21] *}
+{* ../../docs_src/generate_clients/tutorial001_py310.py hl[7:9,12:13,16:17,21] *}
 
 Notice that the *path operations* define the models they use for request payload and response payload, using the models `Item` and `ResponseMessage`.
 
@@ -98,7 +98,7 @@ In many cases, your FastAPI app will be bigger, and you will probably use tags t
 
 For example, you could have a section for **items** and another section for **users**, and they could be separated by tags:
 
-{* ../../docs_src/generate_clients/tutorial002_py39.py hl[21,26,34] *}
+{* ../../docs_src/generate_clients/tutorial002_py310.py hl[21,26,34] *}
 
 ### Generate a TypeScript Client with Tags { #generate-a-typescript-client-with-tags }
 
@@ -145,7 +145,7 @@ For example, here it is using the first tag (you will probably have only one tag
 
 You can then pass that custom function to **FastAPI** as the `generate_unique_id_function` parameter:
 
-{* ../../docs_src/generate_clients/tutorial003_py39.py hl[6:7,10] *}
+{* ../../docs_src/generate_clients/tutorial003_py310.py hl[6:7,10] *}
 
 ### Generate a TypeScript Client with Custom Operation IDs { #generate-a-typescript-client-with-custom-operation-ids }
 
@@ -167,7 +167,7 @@ But for the generated client, we could **modify** the OpenAPI operation IDs righ
 
 We could download the OpenAPI JSON to a file `openapi.json` and then we could **remove that prefixed tag** with a script like this:
 
-{* ../../docs_src/generate_clients/tutorial004_py39.py *}
+{* ../../docs_src/generate_clients/tutorial004_py310.py *}
 
 //// tab | Node.js
 
index 765b389329a2368ab91f9235c8b0e254ecf0b102..b448f5c520bb5edac506e798740ea1105a7d093d 100644 (file)
@@ -57,13 +57,13 @@ Enforces that all incoming requests must either be `https` or `wss`.
 
 Any incoming request to `http` or `ws` will be redirected to the secure scheme instead.
 
-{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py310.py hl[2,6] *}
 
 ## `TrustedHostMiddleware` { #trustedhostmiddleware }
 
 Enforces that all incoming requests have a correctly set `Host` header, in order to guard against HTTP Host Header attacks.
 
-{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py310.py hl[2,6:8] *}
 
 The following arguments are supported:
 
@@ -78,7 +78,7 @@ Handles GZip responses for any request that includes `"gzip"` in the `Accept-Enc
 
 The middleware will handle both standard and streaming responses.
 
-{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py310.py hl[2,6] *}
 
 The following arguments are supported:
 
index 59f060c032e1a5c4b39e0cb23ee95573108ffada..f4f586f84ce70c0368c6b2830533c3525a6b983c 100644 (file)
@@ -32,7 +32,7 @@ Webhooks are available in OpenAPI 3.1.0 and above, supported by FastAPI `0.99.0`
 
 When you create a **FastAPI** application, there is a `webhooks` attribute that you can use to define *webhooks*, the same way you would define *path operations*, for example with `@app.webhooks.post()`.
 
-{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py310.py hl[9:13,36:53] *}
 
 The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**.
 
index 3d7bfdee59999c621073dade91d6837dceb7adbf..fdc77c8a25a7ecfbd8b0836681e4d16d968d5b4b 100644 (file)
@@ -12,7 +12,7 @@ You can set the OpenAPI `operationId` to be used in your *path operation* with t
 
 You would have to make sure that it is unique for each operation.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py310.py hl[6] *}
 
 ### Using the *path operation function* name as the operationId { #using-the-path-operation-function-name-as-the-operationid }
 
@@ -20,7 +20,7 @@ If you want to use your APIs' function names as `operationId`s, you can iterate
 
 You should do it after adding all your *path operations*.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py310.py hl[2, 12:21, 24] *}
 
 /// tip
 
@@ -40,7 +40,7 @@ Even if they are in different modules (Python files).
 
 To exclude a *path operation* from the generated OpenAPI schema (and thus, from the automatic documentation systems), use the parameter `include_in_schema` and set it to `False`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py310.py hl[6] *}
 
 ## Advanced description from docstring { #advanced-description-from-docstring }
 
@@ -92,7 +92,7 @@ You can extend the OpenAPI schema for a *path operation* using the parameter `op
 
 This `openapi_extra` can be helpful, for example, to declare [OpenAPI Extensions](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py310.py hl[6] *}
 
 If you open the automatic API docs, your extension will show up at the bottom of the specific *path operation*.
 
@@ -139,7 +139,7 @@ For example, you could decide to read and validate the request with your own cod
 
 You could do that with `openapi_extra`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py310.py hl[19:36, 39:40] *}
 
 In this example, we didn't declare any Pydantic model. In fact, the request body is not even <dfn title="converted from some plain format, like bytes, into Python objects">parsed</dfn> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
 
@@ -153,7 +153,7 @@ 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:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[15:20, 22] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[15:20, 22] *}
 
 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.
 
@@ -161,7 +161,7 @@ Then we use the request directly, and extract the body as `bytes`. This means th
 
 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:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py39.py hl[24:31] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial007_py310.py hl[24:31] *}
 
 /// tip
 
index d9708aa627fd63d551bb5c4080feaa8d293bf4bb..8aa601e7bd506a58f8868eb81fe2cc6831e0b433 100644 (file)
@@ -20,7 +20,7 @@ You can declare a parameter of type `Response` in your *path operation function*
 
 And then you can set the `status_code` in that *temporal* response object.
 
-{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py310.py hl[1,9,12] *}
 
 And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
 
index 5b6fab112b418338ad0d2d77f772179716c7e05c..cfc615d7e45ab4beed1b4e3b2e633d962f7a37e8 100644 (file)
@@ -6,7 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function*
 
 And then you can set cookies in that *temporal* response object.
 
-{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py310.py hl[1, 8:9] *}
 
 And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
 
@@ -24,7 +24,7 @@ To do that, you can create a response as described in [Return a Response Directl
 
 Then set Cookies in it, and then return it:
 
-{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py310.py hl[10:12] *}
 
 /// tip
 
index 4374cb963743a5ca300cd774f05b406b0f2bdd53..76cc50d03c6add858e3f9aa239db7f77a512aa1b 100644 (file)
@@ -54,7 +54,7 @@ Let's say that you want to return an <a href="https://en.wikipedia.org/wiki/XML"
 
 You could put your XML content in a string, put that in a `Response`, and return it:
 
-{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py310.py hl[1,18] *}
 
 ## Notes { #notes }
 
index 5e9338fbe2c6caa20e83d0ab077ba6455581b9f1..ebc96d5dd0acebfd6a7c45678d1191a581ba5f1c 100644 (file)
@@ -6,7 +6,7 @@ You can declare a parameter of type `Response` in your *path operation function*
 
 And then you can set headers in that *temporal* response object.
 
-{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py310.py hl[1, 7:8] *}
 
 And then you can return any object you need, as you normally would (a `dict`, a database model, etc).
 
@@ -22,7 +22,7 @@ You can also add headers when you return a `Response` directly.
 
 Create a response as described in [Return a Response Directly](response-directly.md){.internal-link target=_blank} and pass the headers as an additional parameter:
 
-{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py310.py hl[10:12] *}
 
 /// note | Technical Details
 
index 01b98eeff3d0abdce3ecbe90cbf8bb85a1f38714..c066cc63a45eac862bf837efd016b3e053edfb61 100644 (file)
@@ -20,7 +20,7 @@ Then, when you type that username and password, the browser sends them in the he
 * It returns an object of type `HTTPBasicCredentials`:
     * It contains the `username` and `password` sent.
 
-{* ../../docs_src/security/tutorial006_an_py39.py hl[4,8,12] *}
+{* ../../docs_src/security/tutorial006_an_py310.py hl[4,8,12] *}
 
 When you try to open the URL for the first time (or click the "Execute" button in the docs) the browser will ask you for your username and password:
 
@@ -40,7 +40,7 @@ To handle that, we first convert the `username` and `password` to `bytes` encodi
 
 Then we can use `secrets.compare_digest()` to ensure that `credentials.username` is `"stanleyjobson"`, and that `credentials.password` is `"swordfish"`.
 
-{* ../../docs_src/security/tutorial007_an_py39.py hl[1,12:24] *}
+{* ../../docs_src/security/tutorial007_an_py310.py hl[1,12:24] *}
 
 This would be similar to:
 
@@ -104,4 +104,4 @@ That way, using `secrets.compare_digest()` in your application code, it will be
 
 After detecting that the credentials are incorrect, return an `HTTPException` with a status code 401 (the same returned when no credentials are provided) and add the header `WWW-Authenticate` to make the browser show the login prompt again:
 
-{* ../../docs_src/security/tutorial007_an_py39.py hl[26:30] *}
+{* ../../docs_src/security/tutorial007_an_py310.py hl[26:30] *}
index cded9b80b8e4e630bb3481f3a8c68ae0d4272658..61a6ac8bc199c6bc6174e8bda2a0d6bd0078770a 100644 (file)
@@ -54,7 +54,7 @@ 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()`.
 
-{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py310.py hl[2,5:8,11] *}
 
 /// tip
 
@@ -70,7 +70,7 @@ Next it will convert and validate the data. So, when you use that `settings` obj
 
 Then you can use the new `settings` object in your application:
 
-{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py310.py hl[18:20] *}
 
 ### Run the server { #run-the-server }
 
@@ -104,11 +104,11 @@ You could put those settings in another module file as you saw in [Bigger Applic
 
 For example, you could have a file `config.py` with:
 
-{* ../../docs_src/settings/app01_py39/config.py *}
+{* ../../docs_src/settings/app01_py310/config.py *}
 
 And then use it in a file `main.py`:
 
-{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py310/main.py hl[3,11:13] *}
 
 /// tip
 
@@ -126,7 +126,7 @@ This could be especially useful during testing, as it's very easy to override a
 
 Coming from the previous example, your `config.py` file could look like:
 
-{* ../../docs_src/settings/app02_an_py39/config.py hl[10] *}
+{* ../../docs_src/settings/app02_an_py310/config.py hl[10] *}
 
 Notice that now we don't create a default instance `settings = Settings()`.
 
@@ -134,7 +134,7 @@ Notice that now we don't create a default instance `settings = Settings()`.
 
 Now we create a dependency that returns a new `config.Settings()`.
 
-{* ../../docs_src/settings/app02_an_py39/main.py hl[6,12:13] *}
+{* ../../docs_src/settings/app02_an_py310/main.py hl[6,12:13] *}
 
 /// tip
 
@@ -146,13 +146,13 @@ For now you can assume `get_settings()` is a normal function.
 
 And then we can require it from the *path operation function* as a dependency and use it anywhere we need it.
 
-{* ../../docs_src/settings/app02_an_py39/main.py hl[17,19:21] *}
+{* ../../docs_src/settings/app02_an_py310/main.py hl[17,19:21] *}
 
 ### Settings and testing { #settings-and-testing }
 
 Then it would be very easy to provide a different settings object during testing by creating a dependency override for `get_settings`:
 
-{* ../../docs_src/settings/app02_an_py39/test_main.py hl[9:10,13,21] *}
+{* ../../docs_src/settings/app02_an_py310/test_main.py hl[9:10,13,21] *}
 
 In the dependency override we set a new value for the `admin_email` when creating the new `Settings` object, and then we return that new object.
 
@@ -193,7 +193,7 @@ APP_NAME="ChimichangApp"
 
 And then update your `config.py` with:
 
-{* ../../docs_src/settings/app03_an_py39/config.py hl[9] *}
+{* ../../docs_src/settings/app03_an_py310/config.py hl[9] *}
 
 /// tip
 
@@ -226,7 +226,7 @@ we would create that object for each request, and we would be reading the `.env`
 
 But as we are using the `@lru_cache` decorator on top, the `Settings` object will be created only once, the first time it's called. ✔️
 
-{* ../../docs_src/settings/app03_an_py39/main.py hl[1,11] *}
+{* ../../docs_src/settings/app03_an_py310/main.py hl[1,11] *}
 
 Then for any subsequent call of `get_settings()` in the dependencies for the next requests, instead of executing the internal code of `get_settings()` and creating a new `Settings` object, it will return the same object that was returned on the first call, again and again.
 
index 60bb15c0292c7776f6d55669b802cd8611b375b5..0f7053669cf0ad865021ae738f3e56c181827a39 100644 (file)
@@ -10,7 +10,7 @@ If you need to have two independent FastAPI applications, with their own indepen
 
 First, create the main, top-level, **FastAPI** application, and its *path operations*:
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[3, 6:8] *}
 
 ### Sub-application { #sub-application }
 
@@ -18,7 +18,7 @@ Then, create your sub-application, and its *path operations*.
 
 This sub-application is just another standard FastAPI application, but this is the one that will be "mounted":
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 14:16] *}
 
 ### Mount the sub-application { #mount-the-sub-application }
 
@@ -26,7 +26,7 @@ In your top-level application, `app`, mount the sub-application, `subapi`.
 
 In this case, it will be mounted at the path `/subapi`:
 
-{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py310.py hl[11, 19] *}
 
 ### Check the automatic API docs { #check-the-automatic-api-docs }
 
index c843d60f73e25fdabd916e04bac0c56d89c40750..71c8f73c035f2ae2c135866adfb9ed841e796bef 100644 (file)
@@ -27,7 +27,7 @@ $ pip install jinja2
 * Declare a `Request` parameter in the *path operation* that will return a template.
 * Use the `templates` you created to render and return a `TemplateResponse`, pass the name of the template, the request object, and a "context" dictionary with key-value pairs to be used inside of the Jinja2 template.
 
-{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py310.py hl[4,11,15:18] *}
 
 /// note
 
index 13c6e2a259ca9d17edfc928374a39859f55ff555..ba42e716952c0be84f55ef8aff2f86385163d07b 100644 (file)
@@ -2,11 +2,11 @@
 
 When you need `lifespan` to run in your tests, you can use the `TestClient` with a `with` statement:
 
-{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../docs_src/app_testing/tutorial004_py310.py hl[9:15,18,27:28,30:32,41:43] *}
 
 
 You can read more details about the ["Running lifespan in tests in the official Starlette documentation site."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
 
 For the deprecated `startup` and `shutdown` events, you can use the `TestClient` as follows:
 
-{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py310.py hl[9:12,20:24] *}
index a3cc381a33869f18084511a0092a7e1111c9ebca..44509570e58c6e21cbaf9a1d1455d1016b19d8f4 100644 (file)
@@ -4,7 +4,7 @@ You can use the same `TestClient` to test WebSockets.
 
 For this, you use the `TestClient` in a `with` statement, connecting to the WebSocket:
 
-{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py310.py hl[27:31] *}
 
 /// note
 
index bc23f2df9058d8aceab0a9bc8db9e4e55d28358c..5dc944ab1985bd3c8758c06252f820f36c9637b4 100644 (file)
@@ -29,7 +29,7 @@ Let's imagine you want to get the client's IP address/host inside of your *path
 
 For that you need to access the request directly.
 
-{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py310.py hl[1,7:8] *}
 
 By declaring a *path operation function* parameter with the type being the `Request` **FastAPI** will know to pass the `Request` in that parameter.
 
index 286df6943225b4a90867a13b747c1cc7208da196..ae17742bb5e7d30bcbab3c22a4ec642c3bd122dc 100644 (file)
@@ -38,13 +38,13 @@ In production you would have one of the options above.
 
 But it's the simplest way to focus on the server-side of WebSockets and have a working example:
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[2,6:38,41:43] *}
 
 ## Create a `websocket` { #create-a-websocket }
 
 In your **FastAPI** application, create a `websocket`:
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[1,46:47] *}
 
 /// note | Technical Details
 
@@ -58,7 +58,7 @@ You could also use `from starlette.websockets import WebSocket`.
 
 In your WebSocket route you can `await` for messages and send messages.
 
-{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py310.py hl[48:52] *}
 
 You can receive and send binary, text, and JSON data.
 
@@ -154,7 +154,7 @@ With that you can connect the WebSocket and then send and receive messages:
 
 When a WebSocket connection is closed, the `await websocket.receive_text()` will raise a `WebSocketDisconnect` exception, which you can then catch and handle like in this example.
 
-{* ../../docs_src/websockets/tutorial003_py39.py hl[79:81] *}
+{* ../../docs_src/websockets/tutorial003_py310.py hl[79:81] *}
 
 To try it out:
 
index aa68617cf423e92fd3de7b6aac2e494655d978d5..4944dc5ace3090ba5d29c7ef1a2e0580ddae11f8 100644 (file)
@@ -18,7 +18,7 @@ Then wrap the WSGI (e.g. Flask) app with the middleware.
 
 And then mount that under a path.
 
-{* ../../docs_src/wsgi/tutorial001_py39.py hl[1,3,23] *}
+{* ../../docs_src/wsgi/tutorial001_py310.py hl[1,3,23] *}
 
 /// note
 
index f9433e5dd31ac4023aaea483657b9b6cb3b3228d..b15298e73652e3bdfc6aab18474e5b819d55d5cc 100644 (file)
@@ -8,7 +8,7 @@ But if for some reason your clients depend on the old behavior, you can revert t
 
 For example, you can create a subclass of `HTTPBearer` that returns a `403 Forbidden` error instead of the default `401 Unauthorized` error:
 
-{* ../../docs_src/authentication_error_status_code/tutorial001_an_py39.py hl[9:13] *}
+{* ../../docs_src/authentication_error_status_code/tutorial001_an_py310.py hl[9:13] *}
 
 /// tip
 
index ecb45b4a5b5f265860accd202dfeb346b9d43a03..b2a7f812f780bc5787fb3636e7b1a0dab4fcda8e 100644 (file)
@@ -29,7 +29,7 @@ You can easily use the same Pydantic settings to configure your generated OpenAP
 
 For example:
 
-{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py310.py hl[6,11] *}
 
 Here we declare the setting `openapi_url` with the same default of `"/openapi.json"`.
 
index ff46dc5b1b434e0d4fc11d00faae3f229adae6b3..ad9c01556d874a7976f9621bbe3d625a11a3d66e 100644 (file)
@@ -18,7 +18,7 @@ Without changing the settings, syntax highlighting is enabled by default:
 
 But you can disable it by setting `syntaxHighlight` to `False`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py310.py hl[3] *}
 
 ...and then Swagger UI won't show the syntax highlighting anymore:
 
@@ -28,7 +28,7 @@ But you can disable it by setting `syntaxHighlight` to `False`:
 
 The same way you could set the syntax highlighting theme with the key `"syntaxHighlight.theme"` (notice that it has a dot in the middle):
 
-{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py310.py hl[3] *}
 
 That configuration would change the syntax highlighting color theme:
 
@@ -46,7 +46,7 @@ You can override any of them by setting a different value in the argument `swagg
 
 For example, to disable `deepLinking` you could pass these settings to `swagger_ui_parameters`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py310.py hl[3] *}
 
 ## Other Swagger UI Parameters { #other-swagger-ui-parameters }
 
index 61a97dca2b54fe374720f9d2b7447211c00bb6e0..d3e505040ad6a124991ed76c6427a10634174b3a 100644 (file)
@@ -18,7 +18,7 @@ The first step is to disable the automatic docs, as by default, those use the de
 
 To disable them, set their URLs to `None` when creating your `FastAPI` app:
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[8] *}
 
 ### Include the custom docs { #include-the-custom-docs }
 
@@ -34,7 +34,7 @@ You can reuse FastAPI's internal functions to create the HTML pages for the docs
 
 And similarly for ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[2:6,11:19,22:24,27:33] *}
 
 /// tip
 
@@ -50,7 +50,7 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
 
 Now, to be able to test that everything works, create a *path operation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py310.py hl[36:38] *}
 
 ### Test it { #test-it }
 
@@ -118,7 +118,7 @@ After that, your file structure could look like:
 * Import `StaticFiles`.
 * "Mount" a `StaticFiles()` instance in a specific path.
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[7,11] *}
 
 ### Test the static files { #test-the-static-files }
 
@@ -144,7 +144,7 @@ The same as when using a custom CDN, the first step is to disable the automatic
 
 To disable them, set their URLs to `None` when creating your `FastAPI` app:
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[9] *}
 
 ### Include the custom docs for static files { #include-the-custom-docs-for-static-files }
 
@@ -160,7 +160,7 @@ Again, you can reuse FastAPI's internal functions to create the HTML pages for t
 
 And similarly for ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[2:6,14:22,25:27,30:36] *}
 
 /// tip
 
@@ -176,7 +176,7 @@ Swagger UI will handle it behind the scenes for you, but it needs this "redirect
 
 Now, to be able to test that everything works, create a *path operation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py310.py hl[39:41] *}
 
 ### Test Static Files UI { #test-static-files-ui }
 
index 2dc262cbad14c2f53f731f8ec815d01c857a1385..b480223bf098713fea083445d381cdc45ae85f19 100644 (file)
@@ -43,19 +43,19 @@ For example, let's add <a href="https://github.com/Rebilly/ReDoc/blob/master/doc
 
 First, write all your **FastAPI** application as normally:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[1,4,7:9] *}
 
 ### Generate the OpenAPI schema { #generate-the-openapi-schema }
 
 Then, use the same utility function to generate the OpenAPI schema, inside a `custom_openapi()` function:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[2,15:21] *}
 
 ### Modify the OpenAPI schema { #modify-the-openapi-schema }
 
 Now you can add the ReDoc extension, adding a custom `x-logo` to the `info` "object" in the OpenAPI schema:
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[22:24] *}
 
 ### Cache the OpenAPI schema { #cache-the-openapi-schema }
 
@@ -65,13 +65,13 @@ That way, your application won't have to generate the schema every time a user o
 
 It will be generated only once, and then the same cached schema will be used for the next requests.
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[13:14,25:26] *}
 
 ### Override the method { #override-the-method }
 
 Now you can replace the `.openapi()` method with your new function.
 
-{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py310.py hl[29] *}
 
 ### Check it { #check-it }
 
index 666f819b0f0e364cfa6eb16f1a677b4a6fb1b1c8..426b2e9821873aafc07eb8176f47d066167b6868 100644 (file)
@@ -35,7 +35,7 @@ Depending on your use case, you might prefer to use a different library, but if
 
 Here's a small preview of how you could integrate Strawberry with FastAPI:
 
-{* ../../docs_src/graphql_/tutorial001_py39.py hl[3,22,25] *}
+{* ../../docs_src/graphql_/tutorial001_py310.py hl[3,22,25] *}
 
 You can learn more about Strawberry in the <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry documentation</a>.
 
index f2ad35d710b425bd55ec388521b3aa850fa8859a..90c32cec8c899d4d2614f0dd1d852ab6c8a95007 100644 (file)
@@ -22,7 +22,7 @@ If you are a Python expert, and you already know everything about type hints, sk
 
 Let's start with a simple example:
 
-{* ../../docs_src/python_types/tutorial001_py39.py *}
+{* ../../docs_src/python_types/tutorial001_py310.py *}
 
 Calling this program outputs:
 
@@ -36,7 +36,7 @@ The function does the following:
 * Converts the first letter of each one to upper case with `title()`.
 * <dfn title="Puts them together, as one. With the contents of one after the other.">Concatenates</dfn> them with a space in the middle.
 
-{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py310.py hl[2] *}
 
 ### Edit it { #edit-it }
 
@@ -78,7 +78,7 @@ That's it.
 
 Those are the "type hints":
 
-{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py310.py hl[1] *}
 
 That is not the same as declaring default values like would be with:
 
@@ -106,7 +106,7 @@ With that, you can scroll, seeing the options, until you find the one that "ring
 
 Check this function, it already has type hints:
 
-{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py310.py hl[1] *}
 
 Because the editor knows the types of the variables, you don't only get completion, you also get error checks:
 
@@ -114,7 +114,7 @@ Because the editor knows the types of the variables, you don't only get completi
 
 Now you know that you have to fix it, convert `age` to a string with `str(age)`:
 
-{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py310.py hl[2] *}
 
 ## Declaring types { #declaring-types }
 
@@ -133,7 +133,7 @@ You can use, for example:
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py310.py hl[1] *}
 
 ### `typing` module { #typing-module }
 
@@ -170,7 +170,7 @@ As the type, put `list`.
 
 As the list is a type that contains some internal types, you put them in square brackets:
 
-{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial006_py310.py hl[1] *}
 
 /// info
 
@@ -196,7 +196,7 @@ And still, the editor knows it is a `str`, and provides support for that.
 
 You would do the same to declare `tuple`s and `set`s:
 
-{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial007_py310.py hl[1] *}
 
 This means:
 
@@ -211,7 +211,7 @@ The first type parameter is for the keys of the `dict`.
 
 The second type parameter is for the values of the `dict`:
 
-{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
+{* ../../docs_src/python_types/tutorial008_py310.py hl[1] *}
 
 This means:
 
@@ -253,11 +253,11 @@ You can also declare a class as the type of a variable.
 
 Let's say you have a class `Person`, with a name:
 
-{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[1:3] *}
 
 Then you can declare a variable to be of type `Person`:
 
-{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py310.py hl[6] *}
 
 And then, again, you get all the editor support:
 
@@ -299,7 +299,7 @@ Python also has a feature that allows putting **additional <dfn title="Data abou
 
 You can import `Annotated` from `typing`.
 
-{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial013_py310.py hl[1,4] *}
 
 Python itself doesn't do anything with this `Annotated`. And for editors and other tools, the type is still `str`.
 
index be7ecd58715cbc0c05829ae5f769ec2164b6f686..163070d3d3c1cdb31820c765b457bcad7be41bba 100644 (file)
@@ -15,7 +15,7 @@ This includes, for example:
 
 First, import `BackgroundTasks` and define a parameter in your *path operation function* with a type declaration of `BackgroundTasks`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[1,13] *}
 
 **FastAPI** will create the object of type `BackgroundTasks` for you and pass it as that parameter.
 
@@ -31,13 +31,13 @@ In this case, the task function will write to a file (simulating sending an emai
 
 And as the write operation doesn't use `async` and `await`, we define the function with normal `def`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[6:9] *}
 
 ## Add the background task { #add-the-background-task }
 
 Inside of your *path operation function*, pass your task function to the *background tasks* object with the method `.add_task()`:
 
-{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py310.py hl[14] *}
 
 `.add_task()` receives as arguments:
 
index f6cee8036b44a7ea9d307c8263e44a4bde4da305..7fe83c06359a8f5da487b312bb86875707434ced 100644 (file)
@@ -85,7 +85,7 @@ You can create the *path operations* for that module using `APIRouter`.
 
 You import it and create an "instance" the same way you would with the class `FastAPI`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[1,3] title["app/routers/users.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[1,3] title["app/routers/users.py"] *}
 
 ### *Path operations* with `APIRouter` { #path-operations-with-apirouter }
 
@@ -93,7 +93,7 @@ And then you use it to declare your *path operations*.
 
 Use it the same way you would use the `FastAPI` class:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/users.py hl[6,11,16] title["app/routers/users.py"] *}
 
 You can think of `APIRouter` as a "mini `FastAPI`" class.
 
@@ -117,7 +117,7 @@ So we put them in their own `dependencies` module (`app/dependencies.py`).
 
 We will now use a simple dependency to read a custom `X-Token` header:
 
-{* ../../docs_src/bigger_applications/app_an_py39/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/dependencies.py hl[3,6:8] title["app/dependencies.py"] *}
 
 /// tip
 
@@ -149,7 +149,7 @@ We know all the *path operations* in this module have the same:
 
 So, instead of adding all that to each *path operation*, we can add it to the `APIRouter`.
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[5:10,16,21] title["app/routers/items.py"] *}
 
 As the path of each *path operation* has to start with `/`, like in:
 
@@ -208,7 +208,7 @@ And we need to get the dependency function from the module `app.dependencies`, t
 
 So we use a relative import with `..` for the dependencies:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[3] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[3] title["app/routers/items.py"] *}
 
 #### How relative imports work { #how-relative-imports-work }
 
@@ -279,7 +279,7 @@ We are not adding the prefix `/items` nor the `tags=["items"]` to each *path ope
 
 But we can still add _more_ `tags` that will be applied to a specific *path operation*, and also some extra `responses` specific to that *path operation*:
 
-{* ../../docs_src/bigger_applications/app_an_py39/routers/items.py hl[30:31] title["app/routers/items.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/routers/items.py hl[30:31] title["app/routers/items.py"] *}
 
 /// tip
 
@@ -305,13 +305,13 @@ You import and create a `FastAPI` class as normally.
 
 And we can even declare [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank} that will be combined with the dependencies for each `APIRouter`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[1,3,7] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[1,3,7] title["app/main.py"] *}
 
 ### Import the `APIRouter` { #import-the-apirouter }
 
 Now we import the other submodules that have `APIRouter`s:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[4:5] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[4:5] title["app/main.py"] *}
 
 As the files `app/routers/users.py` and `app/routers/items.py` are submodules that are part of the same Python package `app`, we can use a single dot `.` to import them using "relative imports".
 
@@ -374,13 +374,13 @@ the `router` from `users` would overwrite the one from `items` and we wouldn't b
 
 So, to be able to use both of them in the same file, we import the submodules directly:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[5] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[5] title["app/main.py"] *}
 
 ### Include the `APIRouter`s for `users` and `items` { #include-the-apirouters-for-users-and-items }
 
 Now, let's include the `router`s from the submodules `users` and `items`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[10:11] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[10:11] title["app/main.py"] *}
 
 /// info
 
@@ -420,13 +420,13 @@ It contains an `APIRouter` with some admin *path operations* that your organizat
 
 For this example it will be super simple. But let's say that because it is shared with other projects in the organization, we cannot modify it and add a `prefix`, `dependencies`, `tags`, etc. directly to the `APIRouter`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/internal/admin.py hl[3] title["app/internal/admin.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/internal/admin.py hl[3] title["app/internal/admin.py"] *}
 
 But we still want to set a custom `prefix` when including the `APIRouter` so that all its *path operations* start with `/admin`, we want to secure it with the `dependencies` we already have for this project, and we want to include `tags` and `responses`.
 
 We can declare all that without having to modify the original `APIRouter` by passing those parameters to `app.include_router()`:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[14:17] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[14:17] title["app/main.py"] *}
 
 That way, the original `APIRouter` will stay unmodified, so we can still share that same `app/internal/admin.py` file with other projects in the organization.
 
@@ -447,7 +447,7 @@ We can also add *path operations* directly to the `FastAPI` app.
 
 Here we do it... just to show that we can 🤷:
 
-{* ../../docs_src/bigger_applications/app_an_py39/main.py hl[21:23] title["app/main.py"] *}
+{* ../../docs_src/bigger_applications/app_an_py310/main.py hl[21:23] title["app/main.py"] *}
 
 and it will work correctly, together with all the other *path operations* added with `app.include_router()`.
 
index 5fd83a8f3c78744f549d5849b752afd598b09d88..b84c9242e908299975fe46483ed396104b9ce5c3 100644 (file)
@@ -164,7 +164,7 @@ images: list[Image]
 
 as in:
 
-{* ../../docs_src/body_nested_models/tutorial008_py39.py hl[13] *}
+{* ../../docs_src/body_nested_models/tutorial008_py310.py hl[13] *}
 
 ## Editor support everywhere { #editor-support-everywhere }
 
@@ -194,7 +194,7 @@ That's what we are going to see here.
 
 In this case, you would accept any `dict` as long as it has `int` keys with `float` values:
 
-{* ../../docs_src/body_nested_models/tutorial009_py39.py hl[7] *}
+{* ../../docs_src/body_nested_models/tutorial009_py310.py hl[7] *}
 
 /// tip
 
index 8a3a8eb0a8b56cc1f57df4cbc3a234cd6dbab26b..61aaa563600026cc41864ccad91167f96d29b44e 100644 (file)
@@ -46,7 +46,7 @@ You can also specify whether your backend allows:
 * Specific HTTP methods (`POST`, `PUT`) or all of them with the wildcard `"*"`.
 * Specific HTTP headers or all of them with the wildcard `"*"`.
 
-{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py310.py hl[2,6:11,13:19] *}
 
 
 The default parameters used by the `CORSMiddleware` implementation are restrictive by default, so you'll need to explicitly enable particular origins, methods, or headers, in order for browsers to be permitted to use them in a Cross-Domain context.
index a2edfe7203902bcbb61f3e273046f5399f578c6d..89bfb702a69d4756f5cd7a18c7c953f64a8ac461 100644 (file)
@@ -6,7 +6,7 @@ You can connect the debugger in your editor, for example with Visual Studio Code
 
 In your FastAPI application, import and run `uvicorn` directly:
 
-{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py310.py hl[1,15] *}
 
 ### About `__name__ == "__main__"` { #about-name-main }
 
index 2e3f04dff089a3a661236b1769789be8636570e7..c57c608d2b827104c5b671e5d7bc64970f64476c 100644 (file)
@@ -14,7 +14,7 @@ The *path operation decorator* receives an optional argument `dependencies`.
 
 It should be a `list` of `Depends()`:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[19] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[19] *}
 
 These dependencies will be executed/solved the same way as normal dependencies. But their value (if they return any) won't be passed to your *path operation function*.
 
@@ -44,13 +44,13 @@ You can use the same dependency *functions* you use normally.
 
 They can declare request requirements (like headers) or other sub-dependencies:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[8,13] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[8,13] *}
 
 ### Raise exceptions { #raise-exceptions }
 
 These dependencies can `raise` exceptions, the same as normal dependencies:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[10,15] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[10,15] *}
 
 ### Return values { #return-values }
 
@@ -58,7 +58,7 @@ And they can return values or not, the values won't be used.
 
 So, you can reuse a normal dependency (that returns a value) you already use somewhere else, and even though the value won't be used, the dependency will be executed:
 
-{* ../../docs_src/dependencies/tutorial006_an_py39.py hl[11,16] *}
+{* ../../docs_src/dependencies/tutorial006_an_py310.py hl[11,16] *}
 
 ## Dependencies for a group of *path operations* { #dependencies-for-a-group-of-path-operations }
 
index cfcd961baa472b536e53cdff4f29402b8dc334db..24a20764312c550e74e2886cd25794f061e9c538 100644 (file)
@@ -29,15 +29,15 @@ For example, you could use this to create a database session and close it after
 
 Only the code prior to and including the `yield` statement is executed before creating a response:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[2:4] *}
 
 The yielded value is what is injected into *path operations* and other dependencies:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[4] *}
 
 The code following the `yield` statement is executed after the response:
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[5:6] *}
 
 /// tip
 
@@ -57,7 +57,7 @@ So, you can look for that specific exception inside the dependency with `except
 
 In the same way, you can use `finally` to make sure the exit steps are executed, no matter if there was an exception or not.
 
-{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py310.py hl[3,5] *}
 
 ## Sub-dependencies with `yield` { #sub-dependencies-with-yield }
 
@@ -67,7 +67,7 @@ You can have sub-dependencies and "trees" of sub-dependencies of any size and sh
 
 For example, `dependency_c` can have a dependency on `dependency_b`, and `dependency_b` on `dependency_a`:
 
-{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[6,14,22] *}
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[6,14,22] *}
 
 And all of them can use `yield`.
 
@@ -75,7 +75,7 @@ In this case `dependency_c`, to execute its exit code, needs the value from `dep
 
 And, in turn, `dependency_b` needs the value from `dependency_a` (here named `dep_a`) to be available for its exit code.
 
-{* ../../docs_src/dependencies/tutorial008_an_py39.py hl[18:19,26:27] *}
+{* ../../docs_src/dependencies/tutorial008_an_py310.py hl[18:19,26:27] *}
 
 The same way, you could have some dependencies with `yield` and some other dependencies with `return`, and have some of those depend on some of the others.
 
@@ -109,7 +109,7 @@ But it's there for you if you need it. 🤓
 
 ///
 
-{* ../../docs_src/dependencies/tutorial008b_an_py39.py hl[18:22,31] *}
+{* ../../docs_src/dependencies/tutorial008b_an_py310.py hl[18:22,31] *}
 
 If you want to catch exceptions and create a custom response based on that, create a [Custom Exception Handler](../handling-errors.md#install-custom-exception-handlers){.internal-link target=_blank}.
 
@@ -117,7 +117,7 @@ If you want to catch exceptions and create a custom response based on that, crea
 
 If you catch an exception using `except` in a dependency with `yield` and you don't raise it again (or raise a new exception), FastAPI won't be able to notice there was an exception, the same way that would happen with regular Python:
 
-{* ../../docs_src/dependencies/tutorial008c_an_py39.py hl[15:16] *}
+{* ../../docs_src/dependencies/tutorial008c_an_py310.py hl[15:16] *}
 
 In this case, the client will see an *HTTP 500 Internal Server Error* response as it should, given that we are not raising an `HTTPException` or similar, but the server will **not have any logs** or any other indication of what was the error. 😱
 
@@ -127,7 +127,7 @@ If you catch an exception in a dependency with `yield`, unless you are raising a
 
 You can re-raise the same exception using `raise`:
 
-{* ../../docs_src/dependencies/tutorial008d_an_py39.py hl[17] *}
+{* ../../docs_src/dependencies/tutorial008d_an_py310.py hl[17] *}
 
 Now the client will get the same *HTTP 500 Internal Server Error* response, but the server will have our custom `InternalError` in the logs. 😎
 
@@ -190,7 +190,7 @@ Normally the exit code of dependencies with `yield` is executed **after the resp
 
 But if you know that you won't need to use the dependency after returning from the *path operation function*, you can use `Depends(scope="function")` to tell FastAPI that it should close the dependency after the *path operation function* returns, but **before** the **response is sent**.
 
-{* ../../docs_src/dependencies/tutorial008e_an_py39.py hl[12,16] *}
+{* ../../docs_src/dependencies/tutorial008e_an_py310.py hl[12,16] *}
 
 `Depends()` receives a `scope` parameter that can be:
 
@@ -269,7 +269,7 @@ In Python, you can create Context Managers by <a href="https://docs.python.org/3
 You can also use them inside of **FastAPI** dependencies with `yield` by using
 `with` or `async with` statements inside of the dependency function:
 
-{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py310.py hl[1:9,13] *}
 
 /// tip
 
index df5af2dff2863ea5bdb2fc46de8453e122d55212..6feda0bc8269958611d78348f9105ee9c45e3692 100644 (file)
@@ -6,7 +6,7 @@ Similar to the way you can [add `dependencies` to the *path operation decorators
 
 In that case, they will be applied to all the *path operations* in the application:
 
-{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
+{* ../../docs_src/dependencies/tutorial012_an_py310.py hl[17] *}
 
 
 And all the ideas in the section about [adding `dependencies` to the *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} still apply, but in this case, to all of the *path operations* in the app.
index 7e7fa146d0d10414ff1611217b81e21959c48419..da4f8f2bda05d6bb3b76e836616db2fe5fe2a988 100644 (file)
@@ -192,7 +192,7 @@ The same way, you can declare responses of lists of objects.
 
 For that, use the standard Python `list`:
 
-{* ../../docs_src/extra_models/tutorial004_py39.py hl[18] *}
+{* ../../docs_src/extra_models/tutorial004_py310.py hl[18] *}
 
 ## Response with arbitrary `dict` { #response-with-arbitrary-dict }
 
@@ -202,7 +202,7 @@ This is useful if you don't know the valid field/attribute names (that would be
 
 In this case, you can use `dict`:
 
-{* ../../docs_src/extra_models/tutorial005_py39.py hl[6] *}
+{* ../../docs_src/extra_models/tutorial005_py310.py hl[6] *}
 
 ## Recap { #recap }
 
index ceae6c475e974103c43ab01aa976dbbfb6dd7763..84751d9d827c2d654bc2d217e89fbe0b3c263a7c 100644 (file)
@@ -2,7 +2,7 @@
 
 The simplest FastAPI file could look like this:
 
-{* ../../docs_src/first_steps/tutorial001_py39.py *}
+{* ../../docs_src/first_steps/tutorial001_py310.py *}
 
 Copy that to a file `main.py`.
 
@@ -183,7 +183,7 @@ That's it! Now you can access your app at that URL. ✨
 
 ### Step 1: import `FastAPI` { #step-1-import-fastapi }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[1] *}
 
 `FastAPI` is a Python class that provides all the functionality for your API.
 
@@ -197,7 +197,7 @@ You can use all the <a href="https://www.starlette.dev/" class="external-link" t
 
 ### Step 2: create a `FastAPI` "instance" { #step-2-create-a-fastapi-instance }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[3] *}
 
 Here the `app` variable will be an "instance" of the class `FastAPI`.
 
@@ -266,7 +266,7 @@ We are going to call them "**operations**" too.
 
 #### Define a *path operation decorator* { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[6] *}
 
 The `@app.get("/")` tells **FastAPI** that the function right below is in charge of handling requests that go to:
 
@@ -320,7 +320,7 @@ This is our "**path operation function**":
 * **operation**: is `get`.
 * **function**: is the function below the "decorator" (below `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[7] *}
 
 This is a Python function.
 
@@ -332,7 +332,7 @@ In this case, it is an `async` function.
 
 You could also define it as a normal function instead of `async def`:
 
-{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py310.py hl[7] *}
 
 /// note
 
@@ -342,7 +342,7 @@ If you don't know the difference, check the [Async: *"In a hurry?"*](../async.md
 
 ### Step 5: return the content { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py310.py hl[8] *}
 
 You can return a `dict`, `list`, singular values as `str`, `int`, etc.
 
index 0e43d7f6f173fba18994072a2a4c8fd1af4d32ed..f1db17bb2ebd0006764ddf41bcfdd89c22a529ca 100644 (file)
@@ -25,7 +25,7 @@ To return HTTP responses with errors to the client you use `HTTPException`.
 
 ### Import `HTTPException` { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[1] *}
 
 ### Raise an `HTTPException` in your code { #raise-an-httpexception-in-your-code }
 
@@ -39,7 +39,7 @@ The benefit of raising an exception over returning a value will be more evident
 
 In this example, when the client requests an item by an ID that doesn't exist, raise an exception with a status code of `404`:
 
-{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py310.py hl[11] *}
 
 ### The resulting response { #the-resulting-response }
 
@@ -77,7 +77,7 @@ You probably won't need to use it directly in your code.
 
 But in case you needed it for an advanced scenario, you can add custom headers:
 
-{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py310.py hl[14] *}
 
 ## Install custom exception handlers { #install-custom-exception-handlers }
 
@@ -89,7 +89,7 @@ And you want to handle this exception globally with FastAPI.
 
 You could add a custom exception handler with `@app.exception_handler()`:
 
-{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py310.py hl[5:7,13:18,24] *}
 
 Here, if you request `/unicorns/yolo`, the *path operation* will `raise` a `UnicornException`.
 
@@ -127,7 +127,7 @@ To override it, import the `RequestValidationError` and use it with `@app.except
 
 The exception handler will receive a `Request` and the exception.
 
-{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[2,14:19] *}
 
 Now, if you go to `/items/foo`, instead of getting the default JSON error with:
 
@@ -159,7 +159,7 @@ The same way, you can override the `HTTPException` handler.
 
 For example, you could want to return a plain text response instead of JSON for these errors:
 
-{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py310.py hl[3:4,9:11,25] *}
 
 /// note | Technical Details
 
@@ -183,7 +183,7 @@ The `RequestValidationError` contains the `body` it received with invalid data.
 
 You could use it while developing your app to log the body and debug it, return it to the user, etc.
 
-{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py310.py hl[14] *}
 
 Now try sending an invalid item like:
 
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
 
 If you want to use the exception along with the same default exception handlers from  **FastAPI**, you can import and reuse the default exception handlers from `fastapi.exception_handlers`:
 
-{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py310.py hl[2:5,15,21] *}
 
 In this example you are just printing the error with a very expressive message, but you get the idea. You can use the exception and then just reuse the default exception handlers.
index 941359a15426322a93a9e25f8963c3fe72c69233..5cf0dfca0193a36d053538b0bcb9162eedfb1e0a 100644 (file)
@@ -18,7 +18,7 @@ You can set the following fields that are used in the OpenAPI specification and
 
 You can set them as follows:
 
-{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
+{* ../../docs_src/metadata/tutorial001_py310.py hl[3:16, 19:32] *}
 
 /// tip
 
@@ -36,7 +36,7 @@ Since OpenAPI 3.1.0 and FastAPI 0.99.0, you can also set the `license_info` with
 
 For example:
 
-{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py310.py hl[31] *}
 
 ## Metadata for tags { #metadata-for-tags }
 
@@ -58,7 +58,7 @@ Let's try that in an example with tags for `users` and `items`.
 
 Create metadata for your tags and pass it to the `openapi_tags` parameter:
 
-{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py310.py hl[3:16,18] *}
 
 Notice that you can use Markdown inside of the descriptions, for example "login" will be shown in bold (**login**) and "fancy" will be shown in italics (_fancy_).
 
@@ -72,7 +72,7 @@ You don't have to add metadata for all the tags that you use.
 
 Use the `tags` parameter with your *path operations* (and `APIRouter`s) to assign them to different tags:
 
-{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py310.py hl[21,26] *}
 
 /// info
 
@@ -100,7 +100,7 @@ But you can configure it with the parameter `openapi_url`.
 
 For example, to set it to be served at `/api/v1/openapi.json`:
 
-{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py310.py hl[3] *}
 
 If you want to disable the OpenAPI schema completely you can set `openapi_url=None`, that will also disable the documentation user interfaces that use it.
 
@@ -117,4 +117,4 @@ You can configure the two documentation user interfaces included:
 
 For example, to set Swagger UI to be served at `/documentation` and disable ReDoc:
 
-{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py310.py hl[3] *}
index 1e77251c587b595ca829bd7e8b8211059b28e0c2..123ce3a683f8cdd2086970a2475e97433b4e3a3c 100644 (file)
@@ -31,7 +31,7 @@ The middleware function receives:
     * Then it returns the `response` generated by the corresponding *path operation*.
 * You can then further modify the `response` before returning it.
 
-{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py310.py hl[8:9,11,14] *}
 
 /// tip
 
@@ -57,7 +57,7 @@ And also after the `response` is generated, before returning it.
 
 For example, you could add a custom header `X-Process-Time` containing the time in seconds that it took to process the request and generate a response:
 
-{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py310.py hl[10,12:13] *}
 
 /// tip
 
index f5c603880aa473c1df3b702626b5f03f167fe3c3..2c545dc1a98a055966bd9d230b46c13ae3f55cdb 100644 (file)
@@ -46,7 +46,7 @@ In these cases, it could make sense to store the tags in an `Enum`.
 
 **FastAPI** supports that the same way as with plain strings:
 
-{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py310.py hl[1,8:10,13,18] *}
 
 ## Summary and description { #summary-and-description }
 
@@ -92,7 +92,7 @@ So, if you don't provide one, **FastAPI** will automatically generate one of "Su
 
 If you need to mark a *path operation* as <dfn title="obsolete, recommended not to use it">deprecated</dfn>, but without removing it, pass the parameter `deprecated`:
 
-{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py310.py hl[16] *}
 
 It will be clearly marked as deprecated in the interactive docs:
 
index 8b1b8a83929dda007edcf1784fea8fae8ef88396..de63a51f593a205927d4fb4eeb567e5e2a84ba23 100644 (file)
@@ -54,11 +54,11 @@ It doesn't matter for **FastAPI**. It will detect the parameters by their names,
 
 So, you can declare your function as:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py310.py hl[7] *}
 
 But keep in mind that if you use `Annotated`, you won't have this problem, it won't matter as you're not using the function parameter default values for `Query()` or `Path()`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py39.py *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_an_py310.py *}
 
 ## Order the parameters as you need, tricks { #order-the-parameters-as-you-need-tricks }
 
@@ -83,13 +83,13 @@ Pass `*`, as the first parameter of the function.
 
 Python won't do anything with that `*`, but it will know that all the following parameters should be called as keyword arguments (key-value pairs), also known as <abbr title="From: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Even if they don't have a default value.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py310.py hl[7] *}
 
 ### Better with `Annotated` { #better-with-annotated }
 
 Keep in mind that if you use `Annotated`, as you are not using function parameter default values, you won't have this problem, and you probably won't need to use `*`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_an_py310.py hl[10] *}
 
 ## Number validations: greater than or equal { #number-validations-greater-than-or-equal }
 
@@ -97,7 +97,7 @@ With `Query` and `Path` (and others you'll see later) you can declare number con
 
 Here, with `ge=1`, `item_id` will need to be an integer number "`g`reater than or `e`qual" to `1`.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial004_an_py310.py hl[10] *}
 
 ## Number validations: greater than and less than or equal { #number-validations-greater-than-and-less-than-or-equal }
 
@@ -106,7 +106,7 @@ The same applies for:
 * `gt`: `g`reater `t`han
 * `le`: `l`ess than or `e`qual
 
-{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py39.py hl[10] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial005_an_py310.py hl[10] *}
 
 ## Number validations: floats, greater than and less than { #number-validations-floats-greater-than-and-less-than }
 
@@ -118,7 +118,7 @@ So, `0.5` would be a valid value. But `0.0` or `0` would not.
 
 And the same for <abbr title="less than"><code>lt</code></abbr>.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py39.py hl[13] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial006_an_py310.py hl[13] *}
 
 ## Recap { #recap }
 
index cf312f1fef3a3465773a95ec00310bb5477c2f15..8adbbcfa1bb4b8870c9307e34407f3ee77e95207 100644 (file)
@@ -2,7 +2,7 @@
 
 You can declare path "parameters" or "variables" with the same syntax used by Python format strings:
 
-{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py310.py hl[6:7] *}
 
 The value of the path parameter `item_id` will be passed to your function as the argument `item_id`.
 
@@ -16,7 +16,7 @@ So, if you run this example and go to <a href="http://127.0.0.1:8000/items/foo"
 
 You can declare the type of a path parameter in the function, using standard Python type annotations:
 
-{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py310.py hl[7] *}
 
 In this case, `item_id` is declared to be an `int`.
 
@@ -118,13 +118,13 @@ And then you can also have a path `/users/{user_id}` to get data about a specifi
 
 Because *path operations* are evaluated in order, you need to make sure that the path for `/users/me` is declared before the one for `/users/{user_id}`:
 
-{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py310.py hl[6,11] *}
 
 Otherwise, the path for `/users/{user_id}` would match also for `/users/me`, "thinking" that it's receiving a parameter `user_id` with a value of `"me"`.
 
 Similarly, you cannot redefine a path operation:
 
-{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py310.py hl[6,11] *}
 
 The first one will always be used since the path matches first.
 
@@ -140,7 +140,7 @@ By inheriting from `str` the API docs will be able to know that the values must
 
 Then create class attributes with fixed values, which will be the available valid values:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[1,6:9] *}
 
 /// tip
 
@@ -152,7 +152,7 @@ If you are wondering, "AlexNet", "ResNet", and "LeNet" are just names of Machine
 
 Then create a *path parameter* with a type annotation using the enum class you created (`ModelName`):
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[16] *}
 
 ### Check the docs { #check-the-docs }
 
@@ -168,13 +168,13 @@ The value of the *path parameter* will be an *enumeration member*.
 
 You can compare it with the *enumeration member* in your created enum `ModelName`:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[17] *}
 
 #### Get the *enumeration value* { #get-the-enumeration-value }
 
 You can get the actual value (a `str` in this case) using `model_name.value`, or in general, `your_enum_member.value`:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[20] *}
 
 /// tip
 
@@ -188,7 +188,7 @@ You can return *enum members* from your *path operation*, even nested in a JSON
 
 They will be converted to their corresponding values (strings in this case) before returning them to the client:
 
-{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py310.py hl[18,21,23] *}
 
 In your client you will get a JSON response like:
 
@@ -227,7 +227,7 @@ In this case, the name of the parameter is `file_path`, and the last part, `:pat
 
 So, you can use it with:
 
-{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py310.py hl[6] *}
 
 /// tip
 
index b8396027007dc3bd8334078e57a1b0e1ecbe6463..7ae94fb0a8caf45e61d92d3fda958f62be541370 100644 (file)
@@ -188,7 +188,7 @@ You can, of course, use default values other than `None`.
 
 Let's say that you want to declare the `q` query parameter to have a `min_length` of `3`, and to have a default value of `"fixedquery"`:
 
-{* ../../docs_src/query_params_str_validations/tutorial005_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial005_an_py310.py hl[9] *}
 
 /// note
 
@@ -218,7 +218,7 @@ q: Annotated[str | None, Query(min_length=3)] = None
 
 So, when you need to declare a value as required while using `Query`, you can simply not declare a default value:
 
-{* ../../docs_src/query_params_str_validations/tutorial006_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial006_an_py310.py hl[9] *}
 
 ### Required, can be `None` { #required-can-be-none }
 
@@ -269,7 +269,7 @@ The interactive API docs will update accordingly, to allow multiple values:
 
 You can also define a default `list` of values if none are provided:
 
-{* ../../docs_src/query_params_str_validations/tutorial012_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial012_an_py310.py hl[9] *}
 
 If you go to:
 
@@ -292,7 +292,7 @@ the default of `q` will be: `["foo", "bar"]` and your response will be:
 
 You can also use `list` directly instead of `list[str]`:
 
-{* ../../docs_src/query_params_str_validations/tutorial013_an_py39.py hl[9] *}
+{* ../../docs_src/query_params_str_validations/tutorial013_an_py310.py hl[9] *}
 
 /// note
 
index eeb59f92581604f1bf8d3182f39b9147cd2fb9f8..9408168cf10a5418245298a9c6c33912e9ca885c 100644 (file)
@@ -2,7 +2,7 @@
 
 When you declare other function parameters that are not part of the path parameters, they are automatically interpreted as "query" parameters.
 
-{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py310.py hl[9] *}
 
 The query is the set of key-value pairs that go after the `?` in a URL, separated by `&` characters.
 
@@ -128,7 +128,7 @@ If you don't want to add a specific value but just make it optional, set the def
 
 But when you want to make a query parameter required, you can just not declare any default value:
 
-{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py310.py hl[6:7] *}
 
 Here the query parameter `needy` is a required query parameter of type `str`.
 
index 3d6e9c18a043da424298cf156179a40a26952067..93c27df3fe5f1a6a7432d1cd4564c440309e8ef8 100644 (file)
@@ -20,13 +20,13 @@ This is because uploaded files are sent as "form data".
 
 Import `File` and `UploadFile` from `fastapi`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[3] *}
 
 ## Define `File` Parameters { #define-file-parameters }
 
 Create file parameters the same way you would for `Body` or `Form`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[9] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[9] *}
 
 /// info
 
@@ -54,7 +54,7 @@ But there are several cases in which you might benefit from using `UploadFile`.
 
 Define a file parameter with a type of `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial001_an_py39.py hl[14] *}
+{* ../../docs_src/request_files/tutorial001_an_py310.py hl[14] *}
 
 Using `UploadFile` has several advantages over `bytes`:
 
@@ -143,7 +143,7 @@ You can make a file optional by using standard type annotations and setting a de
 
 You can also use `File()` with `UploadFile`, for example, to set additional metadata:
 
-{* ../../docs_src/request_files/tutorial001_03_an_py39.py hl[9,15] *}
+{* ../../docs_src/request_files/tutorial001_03_an_py310.py hl[9,15] *}
 
 ## Multiple File Uploads { #multiple-file-uploads }
 
@@ -153,7 +153,7 @@ They would be associated to the same "form field" sent using "form data".
 
 To use that, declare a list of `bytes` or `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial002_an_py39.py hl[10,15] *}
+{* ../../docs_src/request_files/tutorial002_an_py310.py hl[10,15] *}
 
 You will receive, as declared, a `list` of `bytes` or `UploadFile`s.
 
@@ -169,7 +169,7 @@ You could also use `from starlette.responses import HTMLResponse`.
 
 And the same way as before, you can use `File()` to set additional parameters, even for `UploadFile`:
 
-{* ../../docs_src/request_files/tutorial003_an_py39.py hl[11,18:20] *}
+{* ../../docs_src/request_files/tutorial003_an_py310.py hl[11,18:20] *}
 
 ## Recap { #recap }
 
index 68bdf198e76e0fbe3532c1a7290c4fea814fcc22..37e764c136f64be93ba6c7fc55b7822bb913e230 100644 (file)
@@ -24,7 +24,7 @@ This is supported since FastAPI version `0.113.0`. 🤓
 
 You just need to declare a **Pydantic model** with the fields you want to receive as **form fields**, and then declare the parameter as `Form`:
 
-{* ../../docs_src/request_form_models/tutorial001_an_py39.py hl[9:11,15] *}
+{* ../../docs_src/request_form_models/tutorial001_an_py310.py hl[9:11,15] *}
 
 **FastAPI** will **extract** the data for **each field** from the **form data** in the request and give you the Pydantic model you defined.
 
@@ -48,7 +48,7 @@ This is supported since FastAPI version `0.114.0`. 🤓
 
 You can use Pydantic's model configuration to `forbid` any `extra` fields:
 
-{* ../../docs_src/request_form_models/tutorial002_an_py39.py hl[12] *}
+{* ../../docs_src/request_form_models/tutorial002_an_py310.py hl[12] *}
 
 If a client tries to send some extra data, they will receive an **error** response.
 
index a9d905a51d0c3c02579b1ae39212446548638a6a..75f30bd2a944df7f2abaadc488de34b02abb877d 100644 (file)
@@ -16,13 +16,13 @@ $ pip install python-multipart
 
 ## Import `File` and `Form` { #import-file-and-form }
 
-{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[3] *}
 
 ## Define `File` and `Form` parameters { #define-file-and-form-parameters }
 
 Create file and form parameters the same way you would for `Body` or `Query`:
 
-{* ../../docs_src/request_forms_and_files/tutorial001_an_py39.py hl[10:12] *}
+{* ../../docs_src/request_forms_and_files/tutorial001_an_py310.py hl[10:12] *}
 
 The files and form fields will be uploaded as form data and you will receive the files and form fields.
 
index d63ffd56558f008cf595af217862c57e48e0276a..3f160504f673c13d7732215a0cb960ec8167f7ad 100644 (file)
@@ -18,13 +18,13 @@ $ pip install python-multipart
 
 Import `Form` from `fastapi`:
 
-{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[3] *}
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[3] *}
 
 ## Define `Form` parameters { #define-form-parameters }
 
 Create form parameters the same way you would for `Body` or `Query`:
 
-{* ../../docs_src/request_forms/tutorial001_an_py39.py hl[9] *}
+{* ../../docs_src/request_forms/tutorial001_an_py310.py hl[9] *}
 
 For example, in one of the ways the OAuth2 specification can be used (called "password flow") it is required to send a `username` and `password` as form fields.
 
index ac35390fadc6d55c4299a5f46f0a17314d61a4d3..51492722ae2f6d54ddcb0261cc786336d60c4883 100644 (file)
@@ -183,7 +183,7 @@ There might be cases where you return something that is not a valid Pydantic fie
 
 The most common case would be [returning a Response directly as explained later in the advanced docs](../advanced/response-directly.md){.internal-link target=_blank}.
 
-{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py310.py hl[8,10:11] *}
 
 This simple case is handled automatically by FastAPI because the return type annotation is the class (or a subclass of) `Response`.
 
@@ -193,7 +193,7 @@ And tools will also be happy because both `RedirectResponse` and `JSONResponse`
 
 You can also use a subclass of `Response` in the type annotation:
 
-{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py310.py hl[8:9] *}
 
 This will also work because `RedirectResponse` is a subclass of `Response`, and FastAPI will automatically handle this simple case.
 
index 63895924863c53de4e37e586336809e759e85462..dcb35dff54ccc8f3c0781a48e1f65ffe6186ec49 100644 (file)
@@ -8,7 +8,7 @@ The same way you can specify a response model, you can also declare the HTTP sta
 * `@app.delete()`
 * etc.
 
-{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
 
 /// note
 
@@ -74,7 +74,7 @@ To know more about each status code and which code is for what, check the <a hre
 
 Let's see the previous example again:
 
-{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py310.py hl[6] *}
 
 `201` is the status code for "Created".
 
@@ -82,7 +82,7 @@ But you don't have to memorize what each of these codes mean.
 
 You can use the convenience variables from `fastapi.status`.
 
-{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py310.py hl[1,6] *}
 
 They are just a convenience, they hold the same number, but that way you can use the editor's autocomplete to find them:
 
index fd8a44f7688e87f7a2c5d2b997684b44ee62408d..4fbb5e0903eb485e220800ff084b7581a468631f 100644 (file)
@@ -20,7 +20,7 @@ Let's first just use the code and see how it works, and then we'll come back to
 
 Copy the example in a file `main.py`:
 
-{* ../../docs_src/security/tutorial001_an_py39.py *}
+{* ../../docs_src/security/tutorial001_an_py310.py *}
 
 ## Run it { #run-it }
 
@@ -132,7 +132,7 @@ In that case, **FastAPI** also provides you with the tools to build it.
 
 When we create an instance of the `OAuth2PasswordBearer` class we pass in the `tokenUrl` parameter. This parameter contains the URL that the client (the frontend running in the user's browser) will use to send the `username` and `password` in order to get a token.
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[8] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[8] *}
 
 /// tip
 
@@ -170,7 +170,7 @@ So, it can be used with `Depends`.
 
 Now you can pass that `oauth2_scheme` in a dependency with `Depends`.
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
 
 This dependency will provide a `str` that is assigned to the parameter `token` of the *path operation function*.
 
index d9fc8119ba00ac8cfd6be29588c3770173cf08ef..2eb80341f97591f109c0966503a0bcae96143309 100644 (file)
@@ -2,7 +2,7 @@
 
 In the previous chapter the security system (which is based on the dependency injection system) was giving the *path operation function* a `token` as a `str`:
 
-{* ../../docs_src/security/tutorial001_an_py39.py hl[12] *}
+{* ../../docs_src/security/tutorial001_an_py310.py hl[12] *}
 
 But that is still not that useful.
 
index 8cf5a5a8aef2680842d0c345f591402fc467fb72..8fd65a0d7fe33ea37da9f5c6560796cfbbcf0b3f 100644 (file)
@@ -7,7 +7,7 @@ You can serve static files automatically from a directory using `StaticFiles`.
 * Import `StaticFiles`.
 * "Mount" a `StaticFiles()` instance in a specific path.
 
-{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py310.py hl[2,6] *}
 
 /// note | Technical Details
 
index f61e62ac549d3b73faf2ea036fc8d5e764bb19d6..14c1b35668d11420084b35a0e8c95d7fc23f1c7e 100644 (file)
@@ -30,7 +30,7 @@ Use the `TestClient` object the same way as you do with `httpx`.
 
 Write simple `assert` statements with the standard Python expressions that you need to check (again, standard `pytest`).
 
-{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py310.py hl[2,12,15:18] *}
 
 /// tip
 
@@ -76,7 +76,7 @@ Let's say you have a file structure as described in [Bigger Applications](bigger
 In the file `main.py` you have your **FastAPI** app:
 
 
-{* ../../docs_src/app_testing/app_a_py39/main.py *}
+{* ../../docs_src/app_testing/app_a_py310/main.py *}
 
 ### Testing file { #testing-file }
 
@@ -92,7 +92,7 @@ Then you could have a file `test_main.py` with your tests. It could live on the
 
 Because this file is in the same package, you can use relative imports to import the object `app` from the `main` module (`main.py`):
 
-{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py310/test_main.py hl[3] *}
 
 
 ...and have the code for the tests just like before.
diff --git a/docs_src/additional_responses/tutorial001_py310.py b/docs_src/additional_responses/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..ffa821b
--- /dev/null
@@ -0,0 +1,22 @@
+from fastapi import FastAPI
+from fastapi.responses import JSONResponse
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+    id: str
+    value: str
+
+
+class Message(BaseModel):
+    message: str
+
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}", response_model=Item, responses={404: {"model": Message}})
+async def read_item(item_id: str):
+    if item_id == "foo":
+        return {"id": "foo", "value": "there goes my hero"}
+    return JSONResponse(status_code=404, content={"message": "Item not found"})
diff --git a/docs_src/additional_responses/tutorial002_py39.py b/docs_src/additional_responses/tutorial002_py39.py
deleted file mode 100644 (file)
index bd0c957..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from fastapi.responses import FileResponse
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    id: str
-    value: str
-
-
-app = FastAPI()
-
-
-@app.get(
-    "/items/{item_id}",
-    response_model=Item,
-    responses={
-        200: {
-            "content": {"image/png": {}},
-            "description": "Return the JSON item or an image.",
-        }
-    },
-)
-async def read_item(item_id: str, img: Union[bool, None] = None):
-    if img:
-        return FileResponse("image.png", media_type="image/png")
-    else:
-        return {"id": "foo", "value": "there goes my hero"}
diff --git a/docs_src/additional_responses/tutorial003_py310.py b/docs_src/additional_responses/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..f3e41e8
--- /dev/null
@@ -0,0 +1,37 @@
+from fastapi import FastAPI
+from fastapi.responses import JSONResponse
+from pydantic import BaseModel
+
+
+class Item(BaseModel):
+    id: str
+    value: str
+
+
+class Message(BaseModel):
+    message: str
+
+
+app = FastAPI()
+
+
+@app.get(
+    "/items/{item_id}",
+    response_model=Item,
+    responses={
+        404: {"model": Message, "description": "The item was not found"},
+        200: {
+            "description": "Item requested by ID",
+            "content": {
+                "application/json": {
+                    "example": {"id": "bar", "value": "The bar tenders"}
+                }
+            },
+        },
+    },
+)
+async def read_item(item_id: str):
+    if item_id == "foo":
+        return {"id": "foo", "value": "there goes my hero"}
+    else:
+        return JSONResponse(status_code=404, content={"message": "Item not found"})
diff --git a/docs_src/additional_responses/tutorial004_py39.py b/docs_src/additional_responses/tutorial004_py39.py
deleted file mode 100644 (file)
index 978bc18..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from fastapi.responses import FileResponse
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    id: str
-    value: str
-
-
-responses = {
-    404: {"description": "Item not found"},
-    302: {"description": "The item was moved"},
-    403: {"description": "Not enough privileges"},
-}
-
-
-app = FastAPI()
-
-
-@app.get(
-    "/items/{item_id}",
-    response_model=Item,
-    responses={**responses, 200: {"content": {"image/png": {}}}},
-)
-async def read_item(item_id: str, img: Union[bool, None] = None):
-    if img:
-        return FileResponse("image.png", media_type="image/png")
-    else:
-        return {"id": "foo", "value": "there goes my hero"}
diff --git a/docs_src/additional_status_codes/tutorial001_an_py39.py b/docs_src/additional_status_codes/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 89653dd..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI, status
-from fastapi.responses import JSONResponse
-
-app = FastAPI()
-
-items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
-
-
-@app.put("/items/{item_id}")
-async def upsert_item(
-    item_id: str,
-    name: Annotated[Union[str, None], Body()] = None,
-    size: Annotated[Union[int, None], Body()] = None,
-):
-    if item_id in items:
-        item = items[item_id]
-        item["name"] = name
-        item["size"] = size
-        return item
-    else:
-        item = {"name": name, "size": size}
-        items[item_id] = item
-        return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
diff --git a/docs_src/additional_status_codes/tutorial001_py39.py b/docs_src/additional_status_codes/tutorial001_py39.py
deleted file mode 100644 (file)
index 74a986a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI, status
-from fastapi.responses import JSONResponse
-
-app = FastAPI()
-
-items = {"foo": {"name": "Fighters", "size": 6}, "bar": {"name": "Tenders", "size": 3}}
-
-
-@app.put("/items/{item_id}")
-async def upsert_item(
-    item_id: str,
-    name: Union[str, None] = Body(default=None),
-    size: Union[int, None] = Body(default=None),
-):
-    if item_id in items:
-        item = items[item_id]
-        item["name"] = name
-        item["size"] = size
-        return item
-    else:
-        item = {"name": name, "size": size}
-        items[item_id] = item
-        return JSONResponse(status_code=status.HTTP_201_CREATED, content=item)
diff --git a/docs_src/advanced_middleware/tutorial001_py310.py b/docs_src/advanced_middleware/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..35dbd30
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI
+from fastapi.middleware.httpsredirect import HTTPSRedirectMiddleware
+
+app = FastAPI()
+
+app.add_middleware(HTTPSRedirectMiddleware)
+
+
+@app.get("/")
+async def main():
+    return {"message": "Hello World"}
diff --git a/docs_src/advanced_middleware/tutorial002_py310.py b/docs_src/advanced_middleware/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..405235a
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI
+from fastapi.middleware.trustedhost import TrustedHostMiddleware
+
+app = FastAPI()
+
+app.add_middleware(
+    TrustedHostMiddleware, allowed_hosts=["example.com", "*.example.com"]
+)
+
+
+@app.get("/")
+async def main():
+    return {"message": "Hello World"}
diff --git a/docs_src/advanced_middleware/tutorial003_py310.py b/docs_src/advanced_middleware/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..e2c87e6
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI
+from fastapi.middleware.gzip import GZipMiddleware
+
+app = FastAPI()
+
+app.add_middleware(GZipMiddleware, minimum_size=1000, compresslevel=5)
+
+
+@app.get("/")
+async def main():
+    return "somebigcontent"
diff --git a/docs_src/app_testing/app_a_py310/main.py b/docs_src/app_testing/app_a_py310/main.py
new file mode 100644 (file)
index 0000000..4679aec
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+async def read_main():
+    return {"msg": "Hello World"}
diff --git a/docs_src/app_testing/app_a_py310/test_main.py b/docs_src/app_testing/app_a_py310/test_main.py
new file mode 100644 (file)
index 0000000..ddc013f
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi.testclient import TestClient
+
+from .main import app
+
+client = TestClient(app)
+
+
+def test_read_main():
+    response = client.get("/")
+    assert response.status_code == 200
+    assert response.json() == {"msg": "Hello World"}
diff --git a/docs_src/app_testing/app_b_an_py39/main.py b/docs_src/app_testing/app_b_an_py39/main.py
deleted file mode 100644 (file)
index 42026a8..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header, HTTPException
-from pydantic import BaseModel
-
-fake_secret_token = "coneofsilence"
-
-fake_db = {
-    "foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"},
-    "bar": {"id": "bar", "title": "Bar", "description": "The bartenders"},
-}
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    id: str
-    title: str
-    description: Union[str, None] = None
-
-
-@app.get("/items/{item_id}", response_model=Item)
-async def read_main(item_id: str, x_token: Annotated[str, Header()]):
-    if x_token != fake_secret_token:
-        raise HTTPException(status_code=400, detail="Invalid X-Token header")
-    if item_id not in fake_db:
-        raise HTTPException(status_code=404, detail="Item not found")
-    return fake_db[item_id]
-
-
-@app.post("/items/")
-async def create_item(item: Item, x_token: Annotated[str, Header()]) -> Item:
-    if x_token != fake_secret_token:
-        raise HTTPException(status_code=400, detail="Invalid X-Token header")
-    if item.id in fake_db:
-        raise HTTPException(status_code=409, detail="Item already exists")
-    fake_db[item.id] = item.model_dump()
-    return item
diff --git a/docs_src/app_testing/app_b_an_py39/test_main.py b/docs_src/app_testing/app_b_an_py39/test_main.py
deleted file mode 100644 (file)
index 4e1c51e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-from fastapi.testclient import TestClient
-
-from .main import app
-
-client = TestClient(app)
-
-
-def test_read_item():
-    response = client.get("/items/foo", headers={"X-Token": "coneofsilence"})
-    assert response.status_code == 200
-    assert response.json() == {
-        "id": "foo",
-        "title": "Foo",
-        "description": "There goes my hero",
-    }
-
-
-def test_read_item_bad_token():
-    response = client.get("/items/foo", headers={"X-Token": "hailhydra"})
-    assert response.status_code == 400
-    assert response.json() == {"detail": "Invalid X-Token header"}
-
-
-def test_read_nonexistent_item():
-    response = client.get("/items/baz", headers={"X-Token": "coneofsilence"})
-    assert response.status_code == 404
-    assert response.json() == {"detail": "Item not found"}
-
-
-def test_create_item():
-    response = client.post(
-        "/items/",
-        headers={"X-Token": "coneofsilence"},
-        json={"id": "foobar", "title": "Foo Bar", "description": "The Foo Barters"},
-    )
-    assert response.status_code == 200
-    assert response.json() == {
-        "id": "foobar",
-        "title": "Foo Bar",
-        "description": "The Foo Barters",
-    }
-
-
-def test_create_item_bad_token():
-    response = client.post(
-        "/items/",
-        headers={"X-Token": "hailhydra"},
-        json={"id": "bazz", "title": "Bazz", "description": "Drop the bazz"},
-    )
-    assert response.status_code == 400
-    assert response.json() == {"detail": "Invalid X-Token header"}
-
-
-def test_create_existing_item():
-    response = client.post(
-        "/items/",
-        headers={"X-Token": "coneofsilence"},
-        json={
-            "id": "foo",
-            "title": "The Foo ID Stealers",
-            "description": "There goes my stealer",
-        },
-    )
-    assert response.status_code == 409
-    assert response.json() == {"detail": "Item already exists"}
diff --git a/docs_src/app_testing/app_b_py39/main.py b/docs_src/app_testing/app_b_py39/main.py
deleted file mode 100644 (file)
index ed38f47..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header, HTTPException
-from pydantic import BaseModel
-
-fake_secret_token = "coneofsilence"
-
-fake_db = {
-    "foo": {"id": "foo", "title": "Foo", "description": "There goes my hero"},
-    "bar": {"id": "bar", "title": "Bar", "description": "The bartenders"},
-}
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    id: str
-    title: str
-    description: Union[str, None] = None
-
-
-@app.get("/items/{item_id}", response_model=Item)
-async def read_main(item_id: str, x_token: str = Header()):
-    if x_token != fake_secret_token:
-        raise HTTPException(status_code=400, detail="Invalid X-Token header")
-    if item_id not in fake_db:
-        raise HTTPException(status_code=404, detail="Item not found")
-    return fake_db[item_id]
-
-
-@app.post("/items/")
-async def create_item(item: Item, x_token: str = Header()) -> Item:
-    if x_token != fake_secret_token:
-        raise HTTPException(status_code=400, detail="Invalid X-Token header")
-    if item.id in fake_db:
-        raise HTTPException(status_code=409, detail="Item already exists")
-    fake_db[item.id] = item.model_dump()
-    return item
diff --git a/docs_src/app_testing/app_b_py39/test_main.py b/docs_src/app_testing/app_b_py39/test_main.py
deleted file mode 100644 (file)
index 4e1c51e..0000000
+++ /dev/null
@@ -1,65 +0,0 @@
-from fastapi.testclient import TestClient
-
-from .main import app
-
-client = TestClient(app)
-
-
-def test_read_item():
-    response = client.get("/items/foo", headers={"X-Token": "coneofsilence"})
-    assert response.status_code == 200
-    assert response.json() == {
-        "id": "foo",
-        "title": "Foo",
-        "description": "There goes my hero",
-    }
-
-
-def test_read_item_bad_token():
-    response = client.get("/items/foo", headers={"X-Token": "hailhydra"})
-    assert response.status_code == 400
-    assert response.json() == {"detail": "Invalid X-Token header"}
-
-
-def test_read_nonexistent_item():
-    response = client.get("/items/baz", headers={"X-Token": "coneofsilence"})
-    assert response.status_code == 404
-    assert response.json() == {"detail": "Item not found"}
-
-
-def test_create_item():
-    response = client.post(
-        "/items/",
-        headers={"X-Token": "coneofsilence"},
-        json={"id": "foobar", "title": "Foo Bar", "description": "The Foo Barters"},
-    )
-    assert response.status_code == 200
-    assert response.json() == {
-        "id": "foobar",
-        "title": "Foo Bar",
-        "description": "The Foo Barters",
-    }
-
-
-def test_create_item_bad_token():
-    response = client.post(
-        "/items/",
-        headers={"X-Token": "hailhydra"},
-        json={"id": "bazz", "title": "Bazz", "description": "Drop the bazz"},
-    )
-    assert response.status_code == 400
-    assert response.json() == {"detail": "Invalid X-Token header"}
-
-
-def test_create_existing_item():
-    response = client.post(
-        "/items/",
-        headers={"X-Token": "coneofsilence"},
-        json={
-            "id": "foo",
-            "title": "The Foo ID Stealers",
-            "description": "There goes my stealer",
-        },
-    )
-    assert response.status_code == 409
-    assert response.json() == {"detail": "Item already exists"}
diff --git a/docs_src/app_testing/tutorial001_py310.py b/docs_src/app_testing/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..79a853b
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI
+from fastapi.testclient import TestClient
+
+app = FastAPI()
+
+
+@app.get("/")
+async def read_main():
+    return {"msg": "Hello World"}
+
+
+client = TestClient(app)
+
+
+def test_read_main():
+    response = client.get("/")
+    assert response.status_code == 200
+    assert response.json() == {"msg": "Hello World"}
diff --git a/docs_src/app_testing/tutorial002_py310.py b/docs_src/app_testing/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..71c898b
--- /dev/null
@@ -0,0 +1,31 @@
+from fastapi import FastAPI
+from fastapi.testclient import TestClient
+from fastapi.websockets import WebSocket
+
+app = FastAPI()
+
+
+@app.get("/")
+async def read_main():
+    return {"msg": "Hello World"}
+
+
+@app.websocket("/ws")
+async def websocket(websocket: WebSocket):
+    await websocket.accept()
+    await websocket.send_json({"msg": "Hello WebSocket"})
+    await websocket.close()
+
+
+def test_read_main():
+    client = TestClient(app)
+    response = client.get("/")
+    assert response.status_code == 200
+    assert response.json() == {"msg": "Hello World"}
+
+
+def test_websocket():
+    client = TestClient(app)
+    with client.websocket_connect("/ws") as websocket:
+        data = websocket.receive_json()
+        assert data == {"msg": "Hello WebSocket"}
diff --git a/docs_src/app_testing/tutorial003_py310.py b/docs_src/app_testing/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..ca6b45c
--- /dev/null
@@ -0,0 +1,24 @@
+from fastapi import FastAPI
+from fastapi.testclient import TestClient
+
+app = FastAPI()
+
+items = {}
+
+
+@app.on_event("startup")
+async def startup_event():
+    items["foo"] = {"name": "Fighters"}
+    items["bar"] = {"name": "Tenders"}
+
+
+@app.get("/items/{item_id}")
+async def read_items(item_id: str):
+    return items[item_id]
+
+
+def test_read_items():
+    with TestClient(app) as client:
+        response = client.get("/items/foo")
+        assert response.status_code == 200
+        assert response.json() == {"name": "Fighters"}
diff --git a/docs_src/app_testing/tutorial004_py310.py b/docs_src/app_testing/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..f83ac9a
--- /dev/null
@@ -0,0 +1,43 @@
+from contextlib import asynccontextmanager
+
+from fastapi import FastAPI
+from fastapi.testclient import TestClient
+
+items = {}
+
+
+@asynccontextmanager
+async def lifespan(app: FastAPI):
+    items["foo"] = {"name": "Fighters"}
+    items["bar"] = {"name": "Tenders"}
+    yield
+    # clean up items
+    items.clear()
+
+
+app = FastAPI(lifespan=lifespan)
+
+
+@app.get("/items/{item_id}")
+async def read_items(item_id: str):
+    return items[item_id]
+
+
+def test_read_items():
+    # Before the lifespan starts, "items" is still empty
+    assert items == {}
+
+    with TestClient(app) as client:
+        # Inside the "with TestClient" block, the lifespan starts and items added
+        assert items == {"foo": {"name": "Fighters"}, "bar": {"name": "Tenders"}}
+
+        response = client.get("/items/foo")
+        assert response.status_code == 200
+        assert response.json() == {"name": "Fighters"}
+
+        # After the requests is done, the items are still there
+        assert items == {"foo": {"name": "Fighters"}, "bar": {"name": "Tenders"}}
+
+    # The end of the "with TestClient" block simulates terminating the app, so
+    # the lifespan ends and items are cleaned up
+    assert items == {}
diff --git a/docs_src/async_tests/app_a_py310/main.py b/docs_src/async_tests/app_a_py310/main.py
new file mode 100644 (file)
index 0000000..9594f85
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+async def root():
+    return {"message": "Tomato"}
diff --git a/docs_src/async_tests/app_a_py310/test_main.py b/docs_src/async_tests/app_a_py310/test_main.py
new file mode 100644 (file)
index 0000000..a57a31f
--- /dev/null
@@ -0,0 +1,14 @@
+import pytest
+from httpx import ASGITransport, AsyncClient
+
+from .main import app
+
+
+@pytest.mark.anyio
+async def test_root():
+    async with AsyncClient(
+        transport=ASGITransport(app=app), base_url="http://test"
+    ) as ac:
+        response = await ac.get("/")
+    assert response.status_code == 200
+    assert response.json() == {"message": "Tomato"}
diff --git a/docs_src/authentication_error_status_code/tutorial001_an_py310.py b/docs_src/authentication_error_status_code/tutorial001_an_py310.py
new file mode 100644 (file)
index 0000000..7bbc2f7
--- /dev/null
@@ -0,0 +1,21 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI, HTTPException, status
+from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
+
+app = FastAPI()
+
+
+class HTTPBearer403(HTTPBearer):
+    def make_not_authenticated_error(self) -> HTTPException:
+        return HTTPException(
+            status_code=status.HTTP_403_FORBIDDEN, detail="Not authenticated"
+        )
+
+
+CredentialsDep = Annotated[HTTPAuthorizationCredentials, Depends(HTTPBearer403())]
+
+
+@app.get("/me")
+def read_me(credentials: CredentialsDep):
+    return {"message": "You are authenticated", "token": credentials.credentials}
diff --git a/docs_src/background_tasks/tutorial001_py310.py b/docs_src/background_tasks/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..1720a74
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import BackgroundTasks, FastAPI
+
+app = FastAPI()
+
+
+def write_notification(email: str, message=""):
+    with open("log.txt", mode="w") as email_file:
+        content = f"notification for {email}: {message}"
+        email_file.write(content)
+
+
+@app.post("/send-notification/{email}")
+async def send_notification(email: str, background_tasks: BackgroundTasks):
+    background_tasks.add_task(write_notification, email, message="some notification")
+    return {"message": "Notification sent in the background"}
diff --git a/docs_src/background_tasks/tutorial002_an_py39.py b/docs_src/background_tasks/tutorial002_an_py39.py
deleted file mode 100644 (file)
index bfdd148..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import BackgroundTasks, Depends, FastAPI
-
-app = FastAPI()
-
-
-def write_log(message: str):
-    with open("log.txt", mode="a") as log:
-        log.write(message)
-
-
-def get_query(background_tasks: BackgroundTasks, q: Union[str, None] = None):
-    if q:
-        message = f"found query: {q}\n"
-        background_tasks.add_task(write_log, message)
-    return q
-
-
-@app.post("/send-notification/{email}")
-async def send_notification(
-    email: str, background_tasks: BackgroundTasks, q: Annotated[str, Depends(get_query)]
-):
-    message = f"message to {email}\n"
-    background_tasks.add_task(write_log, message)
-    return {"message": "Message sent"}
diff --git a/docs_src/background_tasks/tutorial002_py39.py b/docs_src/background_tasks/tutorial002_py39.py
deleted file mode 100644 (file)
index 2e1b2f6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import BackgroundTasks, Depends, FastAPI
-
-app = FastAPI()
-
-
-def write_log(message: str):
-    with open("log.txt", mode="a") as log:
-        log.write(message)
-
-
-def get_query(background_tasks: BackgroundTasks, q: Union[str, None] = None):
-    if q:
-        message = f"found query: {q}\n"
-        background_tasks.add_task(write_log, message)
-    return q
-
-
-@app.post("/send-notification/{email}")
-async def send_notification(
-    email: str, background_tasks: BackgroundTasks, q: str = Depends(get_query)
-):
-    message = f"message to {email}\n"
-    background_tasks.add_task(write_log, message)
-    return {"message": "Message sent"}
diff --git a/docs_src/behind_a_proxy/tutorial001_01_py310.py b/docs_src/behind_a_proxy/tutorial001_01_py310.py
new file mode 100644 (file)
index 0000000..52b1143
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/")
+def read_items():
+    return ["plumbus", "portal gun"]
diff --git a/docs_src/behind_a_proxy/tutorial001_py310.py b/docs_src/behind_a_proxy/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..ede59ad
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI, Request
+
+app = FastAPI()
+
+
+@app.get("/app")
+def read_main(request: Request):
+    return {"message": "Hello World", "root_path": request.scope.get("root_path")}
diff --git a/docs_src/behind_a_proxy/tutorial002_py310.py b/docs_src/behind_a_proxy/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..c1600cd
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI, Request
+
+app = FastAPI(root_path="/api/v1")
+
+
+@app.get("/app")
+def read_main(request: Request):
+    return {"message": "Hello World", "root_path": request.scope.get("root_path")}
diff --git a/docs_src/behind_a_proxy/tutorial003_py310.py b/docs_src/behind_a_proxy/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..3b7d8be
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI, Request
+
+app = FastAPI(
+    servers=[
+        {"url": "https://stag.example.com", "description": "Staging environment"},
+        {"url": "https://prod.example.com", "description": "Production environment"},
+    ],
+    root_path="/api/v1",
+)
+
+
+@app.get("/app")
+def read_main(request: Request):
+    return {"message": "Hello World", "root_path": request.scope.get("root_path")}
diff --git a/docs_src/behind_a_proxy/tutorial004_py310.py b/docs_src/behind_a_proxy/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..51bd5ba
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, Request
+
+app = FastAPI(
+    servers=[
+        {"url": "https://stag.example.com", "description": "Staging environment"},
+        {"url": "https://prod.example.com", "description": "Production environment"},
+    ],
+    root_path="/api/v1",
+    root_path_in_servers=False,
+)
+
+
+@app.get("/app")
+def read_main(request: Request):
+    return {"message": "Hello World", "root_path": request.scope.get("root_path")}
diff --git a/docs_src/bigger_applications/app_an_py310/dependencies.py b/docs_src/bigger_applications/app_an_py310/dependencies.py
new file mode 100644 (file)
index 0000000..5c7612a
--- /dev/null
@@ -0,0 +1,13 @@
+from typing import Annotated
+
+from fastapi import Header, HTTPException
+
+
+async def get_token_header(x_token: Annotated[str, Header()]):
+    if x_token != "fake-super-secret-token":
+        raise HTTPException(status_code=400, detail="X-Token header invalid")
+
+
+async def get_query_token(token: str):
+    if token != "jessica":
+        raise HTTPException(status_code=400, detail="No Jessica token provided")
diff --git a/docs_src/bigger_applications/app_an_py310/main.py b/docs_src/bigger_applications/app_an_py310/main.py
new file mode 100644 (file)
index 0000000..ae544a3
--- /dev/null
@@ -0,0 +1,23 @@
+from fastapi import Depends, FastAPI
+
+from .dependencies import get_query_token, get_token_header
+from .internal import admin
+from .routers import items, users
+
+app = FastAPI(dependencies=[Depends(get_query_token)])
+
+
+app.include_router(users.router)
+app.include_router(items.router)
+app.include_router(
+    admin.router,
+    prefix="/admin",
+    tags=["admin"],
+    dependencies=[Depends(get_token_header)],
+    responses={418: {"description": "I'm a teapot"}},
+)
+
+
+@app.get("/")
+async def root():
+    return {"message": "Hello Bigger Applications!"}
diff --git a/docs_src/bigger_applications/app_an_py310/routers/__init__.py b/docs_src/bigger_applications/app_an_py310/routers/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/body/tutorial001_py39.py b/docs_src/body/tutorial001_py39.py
deleted file mode 100644 (file)
index f933172..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-app = FastAPI()
-
-
-@app.post("/items/")
-async def create_item(item: Item):
-    return item
diff --git a/docs_src/body/tutorial002_py39.py b/docs_src/body/tutorial002_py39.py
deleted file mode 100644 (file)
index fb212e8..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-app = FastAPI()
-
-
-@app.post("/items/")
-async def create_item(item: Item):
-    item_dict = item.model_dump()
-    if item.tax is not None:
-        price_with_tax = item.price + item.tax
-        item_dict.update({"price_with_tax": price_with_tax})
-    return item_dict
diff --git a/docs_src/body/tutorial003_py39.py b/docs_src/body/tutorial003_py39.py
deleted file mode 100644 (file)
index 636ba22..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-app = FastAPI()
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    return {"item_id": item_id, **item.model_dump()}
diff --git a/docs_src/body/tutorial004_py39.py b/docs_src/body/tutorial004_py39.py
deleted file mode 100644 (file)
index 2c157ab..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-app = FastAPI()
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item, q: Union[str, None] = None):
-    result = {"item_id": item_id, **item.model_dump()}
-    if q:
-        result.update({"q": q})
-    return result
diff --git a/docs_src/body_fields/tutorial001_an_py39.py b/docs_src/body_fields/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 6ef1447..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = Field(
-        default=None, title="The description of the item", max_length=300
-    )
-    price: float = Field(gt=0, description="The price must be greater than zero")
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_fields/tutorial001_py39.py b/docs_src/body_fields/tutorial001_py39.py
deleted file mode 100644 (file)
index cbeebd6..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = Field(
-        default=None, title="The description of the item", max_length=300
-    )
-    price: float = Field(gt=0, description="The price must be greater than zero")
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item = Body(embed=True)):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_multiple_params/tutorial001_an_py39.py b/docs_src/body_multiple_params/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 1c0ac3a..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Path
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)],
-    q: Union[str, None] = None,
-    item: Union[Item, None] = None,
-):
-    results = {"item_id": item_id}
-    if q:
-        results.update({"q": q})
-    if item:
-        results.update({"item": item})
-    return results
diff --git a/docs_src/body_multiple_params/tutorial001_py39.py b/docs_src/body_multiple_params/tutorial001_py39.py
deleted file mode 100644 (file)
index a73975b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Path
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    *,
-    item_id: int = Path(title="The ID of the item to get", ge=0, le=1000),
-    q: Union[str, None] = None,
-    item: Union[Item, None] = None,
-):
-    results = {"item_id": item_id}
-    if q:
-        results.update({"q": q})
-    if item:
-        results.update({"item": item})
-    return results
diff --git a/docs_src/body_multiple_params/tutorial002_py39.py b/docs_src/body_multiple_params/tutorial002_py39.py
deleted file mode 100644 (file)
index 2d7160a..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-class User(BaseModel):
-    username: str
-    full_name: Union[str, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item, user: User):
-    results = {"item_id": item_id, "item": item, "user": user}
-    return results
diff --git a/docs_src/body_multiple_params/tutorial003_an_py39.py b/docs_src/body_multiple_params/tutorial003_an_py39.py
deleted file mode 100644 (file)
index 042351e..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-class User(BaseModel):
-    username: str
-    full_name: Union[str, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    item_id: int, item: Item, user: User, importance: Annotated[int, Body()]
-):
-    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
-    return results
diff --git a/docs_src/body_multiple_params/tutorial003_py39.py b/docs_src/body_multiple_params/tutorial003_py39.py
deleted file mode 100644 (file)
index cf344e6..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-class User(BaseModel):
-    username: str
-    full_name: Union[str, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item, user: User, importance: int = Body()):
-    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
-    return results
diff --git a/docs_src/body_multiple_params/tutorial004_an_py39.py b/docs_src/body_multiple_params/tutorial004_an_py39.py
deleted file mode 100644 (file)
index 567427c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-class User(BaseModel):
-    username: str
-    full_name: Union[str, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    *,
-    item_id: int,
-    item: Item,
-    user: User,
-    importance: Annotated[int, Body(gt=0)],
-    q: Union[str, None] = None,
-):
-    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/body_multiple_params/tutorial004_py39.py b/docs_src/body_multiple_params/tutorial004_py39.py
deleted file mode 100644 (file)
index 8ce4c7a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-class User(BaseModel):
-    username: str
-    full_name: Union[str, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    *,
-    item_id: int,
-    item: Item,
-    user: User,
-    importance: int = Body(gt=0),
-    q: Union[str, None] = None,
-):
-    results = {"item_id": item_id, "item": item, "user": user, "importance": importance}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/body_multiple_params/tutorial005_an_py39.py b/docs_src/body_multiple_params/tutorial005_an_py39.py
deleted file mode 100644 (file)
index 9a52425..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Annotated[Item, Body(embed=True)]):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_multiple_params/tutorial005_py39.py b/docs_src/body_multiple_params/tutorial005_py39.py
deleted file mode 100644 (file)
index 29e6e14..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item = Body(embed=True)):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_nested_models/tutorial001_py39.py b/docs_src/body_nested_models/tutorial001_py39.py
deleted file mode 100644 (file)
index 37ef6dd..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: list = []
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_nested_models/tutorial002_py39.py b/docs_src/body_nested_models/tutorial002_py39.py
deleted file mode 100644 (file)
index 8a93a72..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: list[str] = []
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_nested_models/tutorial003_py39.py b/docs_src/body_nested_models/tutorial003_py39.py
deleted file mode 100644 (file)
index b590ece..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_nested_models/tutorial004_py39.py b/docs_src/body_nested_models/tutorial004_py39.py
deleted file mode 100644 (file)
index dc2b175..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Image(BaseModel):
-    url: str
-    name: str
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-    image: Union[Image, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_nested_models/tutorial005_py39.py b/docs_src/body_nested_models/tutorial005_py39.py
deleted file mode 100644 (file)
index 47db900..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, HttpUrl
-
-app = FastAPI()
-
-
-class Image(BaseModel):
-    url: HttpUrl
-    name: str
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-    image: Union[Image, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_nested_models/tutorial006_py39.py b/docs_src/body_nested_models/tutorial006_py39.py
deleted file mode 100644 (file)
index b144097..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, HttpUrl
-
-app = FastAPI()
-
-
-class Image(BaseModel):
-    url: HttpUrl
-    name: str
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-    images: Union[list[Image], None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/body_nested_models/tutorial007_py39.py b/docs_src/body_nested_models/tutorial007_py39.py
deleted file mode 100644 (file)
index 59cf01e..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, HttpUrl
-
-app = FastAPI()
-
-
-class Image(BaseModel):
-    url: HttpUrl
-    name: str
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-    images: Union[list[Image], None] = None
-
-
-class Offer(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    items: list[Item]
-
-
-@app.post("/offers/")
-async def create_offer(offer: Offer):
-    return offer
diff --git a/docs_src/body_nested_models/tutorial008_py310.py b/docs_src/body_nested_models/tutorial008_py310.py
new file mode 100644 (file)
index 0000000..854a7a5
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI
+from pydantic import BaseModel, HttpUrl
+
+app = FastAPI()
+
+
+class Image(BaseModel):
+    url: HttpUrl
+    name: str
+
+
+@app.post("/images/multiple/")
+async def create_multiple_images(images: list[Image]):
+    return images
diff --git a/docs_src/body_nested_models/tutorial009_py310.py b/docs_src/body_nested_models/tutorial009_py310.py
new file mode 100644 (file)
index 0000000..59c1e50
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.post("/index-weights/")
+async def create_index_weights(weights: dict[int, float]):
+    return weights
diff --git a/docs_src/body_updates/tutorial001_py39.py b/docs_src/body_updates/tutorial001_py39.py
deleted file mode 100644 (file)
index 999bcdb..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from fastapi.encoders import jsonable_encoder
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: Union[str, None] = None
-    description: Union[str, None] = None
-    price: Union[float, None] = None
-    tax: float = 10.5
-    tags: list[str] = []
-
-
-items = {
-    "foo": {"name": "Foo", "price": 50.2},
-    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
-    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
-}
-
-
-@app.get("/items/{item_id}", response_model=Item)
-async def read_item(item_id: str):
-    return items[item_id]
-
-
-@app.put("/items/{item_id}", response_model=Item)
-async def update_item(item_id: str, item: Item):
-    update_item_encoded = jsonable_encoder(item)
-    items[item_id] = update_item_encoded
-    return update_item_encoded
diff --git a/docs_src/body_updates/tutorial002_py39.py b/docs_src/body_updates/tutorial002_py39.py
deleted file mode 100644 (file)
index 3714b5a..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from fastapi.encoders import jsonable_encoder
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: Union[str, None] = None
-    description: Union[str, None] = None
-    price: Union[float, None] = None
-    tax: float = 10.5
-    tags: list[str] = []
-
-
-items = {
-    "foo": {"name": "Foo", "price": 50.2},
-    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
-    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
-}
-
-
-@app.get("/items/{item_id}", response_model=Item)
-async def read_item(item_id: str):
-    return items[item_id]
-
-
-@app.patch("/items/{item_id}")
-async def update_item(item_id: str, item: Item) -> Item:
-    stored_item_data = items[item_id]
-    stored_item_model = Item(**stored_item_data)
-    update_data = item.model_dump(exclude_unset=True)
-    updated_item = stored_item_model.model_copy(update=update_data)
-    items[item_id] = jsonable_encoder(updated_item)
-    return updated_item
diff --git a/docs_src/conditional_openapi/tutorial001_py310.py b/docs_src/conditional_openapi/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..eedb0d2
--- /dev/null
@@ -0,0 +1,16 @@
+from fastapi import FastAPI
+from pydantic_settings import BaseSettings
+
+
+class Settings(BaseSettings):
+    openapi_url: str = "/openapi.json"
+
+
+settings = Settings()
+
+app = FastAPI(openapi_url=settings.openapi_url)
+
+
+@app.get("/")
+def root():
+    return {"message": "Hello World"}
diff --git a/docs_src/configure_swagger_ui/tutorial001_py310.py b/docs_src/configure_swagger_ui/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..6c24ce7
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI(swagger_ui_parameters={"syntaxHighlight": False})
+
+
+@app.get("/users/{username}")
+async def read_user(username: str):
+    return {"message": f"Hello {username}"}
diff --git a/docs_src/configure_swagger_ui/tutorial002_py310.py b/docs_src/configure_swagger_ui/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..cc75c21
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI(swagger_ui_parameters={"syntaxHighlight": {"theme": "obsidian"}})
+
+
+@app.get("/users/{username}")
+async def read_user(username: str):
+    return {"message": f"Hello {username}"}
diff --git a/docs_src/configure_swagger_ui/tutorial003_py310.py b/docs_src/configure_swagger_ui/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..b4449f5
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI(swagger_ui_parameters={"deepLinking": False})
+
+
+@app.get("/users/{username}")
+async def read_user(username: str):
+    return {"message": f"Hello {username}"}
diff --git a/docs_src/cookie_param_models/tutorial001_an_py39.py b/docs_src/cookie_param_models/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 3d90c20..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    session_id: str
-    fatebook_tracker: Union[str, None] = None
-    googall_tracker: Union[str, None] = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Annotated[Cookies, Cookie()]):
-    return cookies
diff --git a/docs_src/cookie_param_models/tutorial001_py39.py b/docs_src/cookie_param_models/tutorial001_py39.py
deleted file mode 100644 (file)
index cc65c43..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    session_id: str
-    fatebook_tracker: Union[str, None] = None
-    googall_tracker: Union[str, None] = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Cookies = Cookie()):
-    return cookies
diff --git a/docs_src/cookie_param_models/tutorial002_an_py39.py b/docs_src/cookie_param_models/tutorial002_an_py39.py
deleted file mode 100644 (file)
index a906ce6..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    model_config = {"extra": "forbid"}
-
-    session_id: str
-    fatebook_tracker: Union[str, None] = None
-    googall_tracker: Union[str, None] = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Annotated[Cookies, Cookie()]):
-    return cookies
diff --git a/docs_src/cookie_param_models/tutorial002_py39.py b/docs_src/cookie_param_models/tutorial002_py39.py
deleted file mode 100644 (file)
index 9679e89..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    model_config = {"extra": "forbid"}
-
-    session_id: str
-    fatebook_tracker: Union[str, None] = None
-    googall_tracker: Union[str, None] = None
-
-
-@app.get("/items/")
-async def read_items(cookies: Cookies = Cookie()):
-    return cookies
diff --git a/docs_src/cookie_params/tutorial001_an_py39.py b/docs_src/cookie_params/tutorial001_an_py39.py
deleted file mode 100644 (file)
index e18d0a3..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Cookie, FastAPI
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(ads_id: Annotated[Union[str, None], Cookie()] = None):
-    return {"ads_id": ads_id}
diff --git a/docs_src/cookie_params/tutorial001_py39.py b/docs_src/cookie_params/tutorial001_py39.py
deleted file mode 100644 (file)
index c4a497f..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(ads_id: Union[str, None] = Cookie(default=None)):
-    return {"ads_id": ads_id}
diff --git a/docs_src/cors/tutorial001_py310.py b/docs_src/cors/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..d59ab27
--- /dev/null
@@ -0,0 +1,24 @@
+from fastapi import FastAPI
+from fastapi.middleware.cors import CORSMiddleware
+
+app = FastAPI()
+
+origins = [
+    "http://localhost.tiangolo.com",
+    "https://localhost.tiangolo.com",
+    "http://localhost",
+    "http://localhost:8080",
+]
+
+app.add_middleware(
+    CORSMiddleware,
+    allow_origins=origins,
+    allow_credentials=True,
+    allow_methods=["*"],
+    allow_headers=["*"],
+)
+
+
+@app.get("/")
+async def main():
+    return {"message": "Hello World"}
diff --git a/docs_src/custom_docs_ui/tutorial001_py310.py b/docs_src/custom_docs_ui/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..1cfcce1
--- /dev/null
@@ -0,0 +1,38 @@
+from fastapi import FastAPI
+from fastapi.openapi.docs import (
+    get_redoc_html,
+    get_swagger_ui_html,
+    get_swagger_ui_oauth2_redirect_html,
+)
+
+app = FastAPI(docs_url=None, redoc_url=None)
+
+
+@app.get("/docs", include_in_schema=False)
+async def custom_swagger_ui_html():
+    return get_swagger_ui_html(
+        openapi_url=app.openapi_url,
+        title=app.title + " - Swagger UI",
+        oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
+        swagger_js_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui-bundle.js",
+        swagger_css_url="https://unpkg.com/swagger-ui-dist@5/swagger-ui.css",
+    )
+
+
+@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
+async def swagger_ui_redirect():
+    return get_swagger_ui_oauth2_redirect_html()
+
+
+@app.get("/redoc", include_in_schema=False)
+async def redoc_html():
+    return get_redoc_html(
+        openapi_url=app.openapi_url,
+        title=app.title + " - ReDoc",
+        redoc_js_url="https://unpkg.com/redoc@2/bundles/redoc.standalone.js",
+    )
+
+
+@app.get("/users/{username}")
+async def read_user(username: str):
+    return {"message": f"Hello {username}"}
diff --git a/docs_src/custom_docs_ui/tutorial002_py310.py b/docs_src/custom_docs_ui/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..23ea368
--- /dev/null
@@ -0,0 +1,41 @@
+from fastapi import FastAPI
+from fastapi.openapi.docs import (
+    get_redoc_html,
+    get_swagger_ui_html,
+    get_swagger_ui_oauth2_redirect_html,
+)
+from fastapi.staticfiles import StaticFiles
+
+app = FastAPI(docs_url=None, redoc_url=None)
+
+app.mount("/static", StaticFiles(directory="static"), name="static")
+
+
+@app.get("/docs", include_in_schema=False)
+async def custom_swagger_ui_html():
+    return get_swagger_ui_html(
+        openapi_url=app.openapi_url,
+        title=app.title + " - Swagger UI",
+        oauth2_redirect_url=app.swagger_ui_oauth2_redirect_url,
+        swagger_js_url="/static/swagger-ui-bundle.js",
+        swagger_css_url="/static/swagger-ui.css",
+    )
+
+
+@app.get(app.swagger_ui_oauth2_redirect_url, include_in_schema=False)
+async def swagger_ui_redirect():
+    return get_swagger_ui_oauth2_redirect_html()
+
+
+@app.get("/redoc", include_in_schema=False)
+async def redoc_html():
+    return get_redoc_html(
+        openapi_url=app.openapi_url,
+        title=app.title + " - ReDoc",
+        redoc_js_url="/static/redoc.standalone.js",
+    )
+
+
+@app.get("/users/{username}")
+async def read_user(username: str):
+    return {"message": f"Hello {username}"}
diff --git a/docs_src/custom_request_and_route/tutorial001_an_py39.py b/docs_src/custom_request_and_route/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 076727e..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-import gzip
-from typing import Annotated, Callable
-
-from fastapi import Body, FastAPI, Request, Response
-from fastapi.routing import APIRoute
-
-
-class GzipRequest(Request):
-    async def body(self) -> bytes:
-        if not hasattr(self, "_body"):
-            body = await super().body()
-            if "gzip" in self.headers.getlist("Content-Encoding"):
-                body = gzip.decompress(body)
-            self._body = body
-        return self._body
-
-
-class GzipRoute(APIRoute):
-    def get_route_handler(self) -> Callable:
-        original_route_handler = super().get_route_handler()
-
-        async def custom_route_handler(request: Request) -> Response:
-            request = GzipRequest(request.scope, request.receive)
-            return await original_route_handler(request)
-
-        return custom_route_handler
-
-
-app = FastAPI()
-app.router.route_class = GzipRoute
-
-
-@app.post("/sum")
-async def sum_numbers(numbers: Annotated[list[int], Body()]):
-    return {"sum": sum(numbers)}
diff --git a/docs_src/custom_request_and_route/tutorial001_py39.py b/docs_src/custom_request_and_route/tutorial001_py39.py
deleted file mode 100644 (file)
index 54b20b9..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-import gzip
-from typing import Callable
-
-from fastapi import Body, FastAPI, Request, Response
-from fastapi.routing import APIRoute
-
-
-class GzipRequest(Request):
-    async def body(self) -> bytes:
-        if not hasattr(self, "_body"):
-            body = await super().body()
-            if "gzip" in self.headers.getlist("Content-Encoding"):
-                body = gzip.decompress(body)
-            self._body = body
-        return self._body
-
-
-class GzipRoute(APIRoute):
-    def get_route_handler(self) -> Callable:
-        original_route_handler = super().get_route_handler()
-
-        async def custom_route_handler(request: Request) -> Response:
-            request = GzipRequest(request.scope, request.receive)
-            return await original_route_handler(request)
-
-        return custom_route_handler
-
-
-app = FastAPI()
-app.router.route_class = GzipRoute
-
-
-@app.post("/sum")
-async def sum_numbers(numbers: list[int] = Body()):
-    return {"sum": sum(numbers)}
diff --git a/docs_src/custom_request_and_route/tutorial002_an_py39.py b/docs_src/custom_request_and_route/tutorial002_an_py39.py
deleted file mode 100644 (file)
index e7de09d..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from typing import Annotated, Callable
-
-from fastapi import Body, FastAPI, HTTPException, Request, Response
-from fastapi.exceptions import RequestValidationError
-from fastapi.routing import APIRoute
-
-
-class ValidationErrorLoggingRoute(APIRoute):
-    def get_route_handler(self) -> Callable:
-        original_route_handler = super().get_route_handler()
-
-        async def custom_route_handler(request: Request) -> Response:
-            try:
-                return await original_route_handler(request)
-            except RequestValidationError as exc:
-                body = await request.body()
-                detail = {"errors": exc.errors(), "body": body.decode()}
-                raise HTTPException(status_code=422, detail=detail)
-
-        return custom_route_handler
-
-
-app = FastAPI()
-app.router.route_class = ValidationErrorLoggingRoute
-
-
-@app.post("/")
-async def sum_numbers(numbers: Annotated[list[int], Body()]):
-    return sum(numbers)
diff --git a/docs_src/custom_request_and_route/tutorial002_py39.py b/docs_src/custom_request_and_route/tutorial002_py39.py
deleted file mode 100644 (file)
index c4e4748..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from typing import Callable
-
-from fastapi import Body, FastAPI, HTTPException, Request, Response
-from fastapi.exceptions import RequestValidationError
-from fastapi.routing import APIRoute
-
-
-class ValidationErrorLoggingRoute(APIRoute):
-    def get_route_handler(self) -> Callable:
-        original_route_handler = super().get_route_handler()
-
-        async def custom_route_handler(request: Request) -> Response:
-            try:
-                return await original_route_handler(request)
-            except RequestValidationError as exc:
-                body = await request.body()
-                detail = {"errors": exc.errors(), "body": body.decode()}
-                raise HTTPException(status_code=422, detail=detail)
-
-        return custom_route_handler
-
-
-app = FastAPI()
-app.router.route_class = ValidationErrorLoggingRoute
-
-
-@app.post("/")
-async def sum_numbers(numbers: list[int] = Body()):
-    return sum(numbers)
diff --git a/docs_src/custom_request_and_route/tutorial003_py39.py b/docs_src/custom_request_and_route/tutorial003_py39.py
deleted file mode 100644 (file)
index aabe760..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-import time
-from typing import Callable
-
-from fastapi import APIRouter, FastAPI, Request, Response
-from fastapi.routing import APIRoute
-
-
-class TimedRoute(APIRoute):
-    def get_route_handler(self) -> Callable:
-        original_route_handler = super().get_route_handler()
-
-        async def custom_route_handler(request: Request) -> Response:
-            before = time.time()
-            response: Response = await original_route_handler(request)
-            duration = time.time() - before
-            response.headers["X-Response-Time"] = str(duration)
-            print(f"route duration: {duration}")
-            print(f"route response: {response}")
-            print(f"route response headers: {response.headers}")
-            return response
-
-        return custom_route_handler
-
-
-app = FastAPI()
-router = APIRouter(route_class=TimedRoute)
-
-
-@app.get("/")
-async def not_timed():
-    return {"message": "Not timed"}
-
-
-@router.get("/timed")
-async def timed():
-    return {"message": "It's the time of my life"}
-
-
-app.include_router(router)
diff --git a/docs_src/custom_response/tutorial001_py310.py b/docs_src/custom_response/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..0f09bdf
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import UJSONResponse
+
+app = FastAPI()
+
+
+@app.get("/items/", response_class=UJSONResponse)
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs_src/custom_response/tutorial001b_py310.py b/docs_src/custom_response/tutorial001b_py310.py
new file mode 100644 (file)
index 0000000..95e6ca7
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import ORJSONResponse
+
+app = FastAPI()
+
+
+@app.get("/items/", response_class=ORJSONResponse)
+async def read_items():
+    return ORJSONResponse([{"item_id": "Foo"}])
diff --git a/docs_src/custom_response/tutorial002_py310.py b/docs_src/custom_response/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..23c4958
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.get("/items/", response_class=HTMLResponse)
+async def read_items():
+    return """
+    <html>
+        <head>
+            <title>Some HTML in here</title>
+        </head>
+        <body>
+            <h1>Look ma! HTML!</h1>
+        </body>
+    </html>
+    """
diff --git a/docs_src/custom_response/tutorial003_py310.py b/docs_src/custom_response/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..51ad3c1
--- /dev/null
@@ -0,0 +1,19 @@
+from fastapi import FastAPI
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items():
+    html_content = """
+    <html>
+        <head>
+            <title>Some HTML in here</title>
+        </head>
+        <body>
+            <h1>Look ma! HTML!</h1>
+        </body>
+    </html>
+    """
+    return HTMLResponse(content=html_content, status_code=200)
diff --git a/docs_src/custom_response/tutorial004_py310.py b/docs_src/custom_response/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..0e90f20
--- /dev/null
@@ -0,0 +1,23 @@
+from fastapi import FastAPI
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+
+def generate_html_response():
+    html_content = """
+    <html>
+        <head>
+            <title>Some HTML in here</title>
+        </head>
+        <body>
+            <h1>Look ma! HTML!</h1>
+        </body>
+    </html>
+    """
+    return HTMLResponse(content=html_content, status_code=200)
+
+
+@app.get("/items/", response_class=HTMLResponse)
+async def read_items():
+    return generate_html_response()
diff --git a/docs_src/custom_response/tutorial005_py310.py b/docs_src/custom_response/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..3d58f57
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import PlainTextResponse
+
+app = FastAPI()
+
+
+@app.get("/", response_class=PlainTextResponse)
+async def main():
+    return "Hello World"
diff --git a/docs_src/custom_response/tutorial006_py310.py b/docs_src/custom_response/tutorial006_py310.py
new file mode 100644 (file)
index 0000000..332f8f8
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import RedirectResponse
+
+app = FastAPI()
+
+
+@app.get("/typer")
+async def redirect_typer():
+    return RedirectResponse("https://typer.tiangolo.com")
diff --git a/docs_src/custom_response/tutorial006b_py310.py b/docs_src/custom_response/tutorial006b_py310.py
new file mode 100644 (file)
index 0000000..03a7be3
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import RedirectResponse
+
+app = FastAPI()
+
+
+@app.get("/fastapi", response_class=RedirectResponse)
+async def redirect_fastapi():
+    return "https://fastapi.tiangolo.com"
diff --git a/docs_src/custom_response/tutorial006c_py310.py b/docs_src/custom_response/tutorial006c_py310.py
new file mode 100644 (file)
index 0000000..87c7203
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import RedirectResponse
+
+app = FastAPI()
+
+
+@app.get("/pydantic", response_class=RedirectResponse, status_code=302)
+async def redirect_pydantic():
+    return "https://docs.pydantic.dev/"
diff --git a/docs_src/custom_response/tutorial007_py310.py b/docs_src/custom_response/tutorial007_py310.py
new file mode 100644 (file)
index 0000000..e2a53a2
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI
+from fastapi.responses import StreamingResponse
+
+app = FastAPI()
+
+
+async def fake_video_streamer():
+    for i in range(10):
+        yield b"some fake video bytes"
+
+
+@app.get("/")
+async def main():
+    return StreamingResponse(fake_video_streamer())
diff --git a/docs_src/custom_response/tutorial008_py310.py b/docs_src/custom_response/tutorial008_py310.py
new file mode 100644 (file)
index 0000000..fc071cb
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI
+from fastapi.responses import StreamingResponse
+
+some_file_path = "large-video-file.mp4"
+app = FastAPI()
+
+
+@app.get("/")
+def main():
+    def iterfile():  # (1)
+        with open(some_file_path, mode="rb") as file_like:  # (2)
+            yield from file_like  # (3)
+
+    return StreamingResponse(iterfile(), media_type="video/mp4")
diff --git a/docs_src/custom_response/tutorial009_py310.py b/docs_src/custom_response/tutorial009_py310.py
new file mode 100644 (file)
index 0000000..71cf50c
--- /dev/null
@@ -0,0 +1,10 @@
+from fastapi import FastAPI
+from fastapi.responses import FileResponse
+
+some_file_path = "large-video-file.mp4"
+app = FastAPI()
+
+
+@app.get("/")
+async def main():
+    return FileResponse(some_file_path)
diff --git a/docs_src/custom_response/tutorial009b_py310.py b/docs_src/custom_response/tutorial009b_py310.py
new file mode 100644 (file)
index 0000000..27200ee
--- /dev/null
@@ -0,0 +1,10 @@
+from fastapi import FastAPI
+from fastapi.responses import FileResponse
+
+some_file_path = "large-video-file.mp4"
+app = FastAPI()
+
+
+@app.get("/", response_class=FileResponse)
+async def main():
+    return some_file_path
diff --git a/docs_src/custom_response/tutorial009c_py310.py b/docs_src/custom_response/tutorial009c_py310.py
new file mode 100644 (file)
index 0000000..de6b668
--- /dev/null
@@ -0,0 +1,19 @@
+from typing import Any
+
+import orjson
+from fastapi import FastAPI, Response
+
+app = FastAPI()
+
+
+class CustomORJSONResponse(Response):
+    media_type = "application/json"
+
+    def render(self, content: Any) -> bytes:
+        assert orjson is not None, "orjson must be installed"
+        return orjson.dumps(content, option=orjson.OPT_INDENT_2)
+
+
+@app.get("/", response_class=CustomORJSONResponse)
+async def main():
+    return {"message": "Hello World"}
diff --git a/docs_src/custom_response/tutorial010_py310.py b/docs_src/custom_response/tutorial010_py310.py
new file mode 100644 (file)
index 0000000..57cb062
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import ORJSONResponse
+
+app = FastAPI(default_response_class=ORJSONResponse)
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs_src/dataclasses_/tutorial001_py39.py b/docs_src/dataclasses_/tutorial001_py39.py
deleted file mode 100644 (file)
index 2954c39..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from dataclasses import dataclass
-from typing import Union
-
-from fastapi import FastAPI
-
-
-@dataclass
-class Item:
-    name: str
-    price: float
-    description: Union[str, None] = None
-    tax: Union[float, None] = None
-
-
-app = FastAPI()
-
-
-@app.post("/items/")
-async def create_item(item: Item):
-    return item
diff --git a/docs_src/dataclasses_/tutorial002_py39.py b/docs_src/dataclasses_/tutorial002_py39.py
deleted file mode 100644 (file)
index 0c23765..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from dataclasses import dataclass, field
-from typing import Union
-
-from fastapi import FastAPI
-
-
-@dataclass
-class Item:
-    name: str
-    price: float
-    tags: list[str] = field(default_factory=list)
-    description: Union[str, None] = None
-    tax: Union[float, None] = None
-
-
-app = FastAPI()
-
-
-@app.get("/items/next", response_model=Item)
-async def read_next_item():
-    return {
-        "name": "Island In The Moon",
-        "price": 12.99,
-        "description": "A place to be playin' and havin' fun",
-        "tags": ["breater"],
-    }
diff --git a/docs_src/dataclasses_/tutorial003_py39.py b/docs_src/dataclasses_/tutorial003_py39.py
deleted file mode 100644 (file)
index 991708c..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-from dataclasses import field  # (1)
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic.dataclasses import dataclass  # (2)
-
-
-@dataclass
-class Item:
-    name: str
-    description: Union[str, None] = None
-
-
-@dataclass
-class Author:
-    name: str
-    items: list[Item] = field(default_factory=list)  # (3)
-
-
-app = FastAPI()
-
-
-@app.post("/authors/{author_id}/items/", response_model=Author)  # (4)
-async def create_author_items(author_id: str, items: list[Item]):  # (5)
-    return {"name": author_id, "items": items}  # (6)
-
-
-@app.get("/authors/", response_model=list[Author])  # (7)
-def get_authors():  # (8)
-    return [  # (9)
-        {
-            "name": "Breaters",
-            "items": [
-                {
-                    "name": "Island In The Moon",
-                    "description": "A place to be playin' and havin' fun",
-                },
-                {"name": "Holy Buddies"},
-            ],
-        },
-        {
-            "name": "System of an Up",
-            "items": [
-                {
-                    "name": "Salt",
-                    "description": "The kombucha mushroom people's favorite",
-                },
-                {"name": "Pad Thai"},
-                {
-                    "name": "Lonely Night",
-                    "description": "The mostests lonliest nightiest of allest",
-                },
-            ],
-        },
-    ]
diff --git a/docs_src/debugging/tutorial001_py310.py b/docs_src/debugging/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..3de21d2
--- /dev/null
@@ -0,0 +1,15 @@
+import uvicorn
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+def root():
+    a = "a"
+    b = "b" + a
+    return {"hello world": b}
+
+
+if __name__ == "__main__":
+    uvicorn.run(app, host="0.0.0.0", port=8000)
diff --git a/docs_src/dependencies/tutorial001_02_an_py39.py b/docs_src/dependencies/tutorial001_02_an_py39.py
deleted file mode 100644 (file)
index df969ae..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-async def common_parameters(
-    q: Union[str, None] = None, skip: int = 0, limit: int = 100
-):
-    return {"q": q, "skip": skip, "limit": limit}
-
-
-CommonsDep = Annotated[dict, Depends(common_parameters)]
-
-
-@app.get("/items/")
-async def read_items(commons: CommonsDep):
-    return commons
-
-
-@app.get("/users/")
-async def read_users(commons: CommonsDep):
-    return commons
diff --git a/docs_src/dependencies/tutorial001_an_py39.py b/docs_src/dependencies/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 5d9fe6d..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-async def common_parameters(
-    q: Union[str, None] = None, skip: int = 0, limit: int = 100
-):
-    return {"q": q, "skip": skip, "limit": limit}
-
-
-@app.get("/items/")
-async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
-    return commons
-
-
-@app.get("/users/")
-async def read_users(commons: Annotated[dict, Depends(common_parameters)]):
-    return commons
diff --git a/docs_src/dependencies/tutorial001_py39.py b/docs_src/dependencies/tutorial001_py39.py
deleted file mode 100644 (file)
index b127510..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-async def common_parameters(
-    q: Union[str, None] = None, skip: int = 0, limit: int = 100
-):
-    return {"q": q, "skip": skip, "limit": limit}
-
-
-@app.get("/items/")
-async def read_items(commons: dict = Depends(common_parameters)):
-    return commons
-
-
-@app.get("/users/")
-async def read_users(commons: dict = Depends(common_parameters)):
-    return commons
diff --git a/docs_src/dependencies/tutorial002_an_py39.py b/docs_src/dependencies/tutorial002_an_py39.py
deleted file mode 100644 (file)
index 844a23c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
-
-
-class CommonQueryParams:
-    def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100):
-        self.q = q
-        self.skip = skip
-        self.limit = limit
-
-
-@app.get("/items/")
-async def read_items(commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]):
-    response = {}
-    if commons.q:
-        response.update({"q": commons.q})
-    items = fake_items_db[commons.skip : commons.skip + commons.limit]
-    response.update({"items": items})
-    return response
diff --git a/docs_src/dependencies/tutorial002_py39.py b/docs_src/dependencies/tutorial002_py39.py
deleted file mode 100644 (file)
index 8e863e4..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
-
-
-class CommonQueryParams:
-    def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100):
-        self.q = q
-        self.skip = skip
-        self.limit = limit
-
-
-@app.get("/items/")
-async def read_items(commons: CommonQueryParams = Depends(CommonQueryParams)):
-    response = {}
-    if commons.q:
-        response.update({"q": commons.q})
-    items = fake_items_db[commons.skip : commons.skip + commons.limit]
-    response.update({"items": items})
-    return response
diff --git a/docs_src/dependencies/tutorial003_an_py39.py b/docs_src/dependencies/tutorial003_an_py39.py
deleted file mode 100644 (file)
index 9e9123a..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Annotated, Any, Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
-
-
-class CommonQueryParams:
-    def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100):
-        self.q = q
-        self.skip = skip
-        self.limit = limit
-
-
-@app.get("/items/")
-async def read_items(commons: Annotated[Any, Depends(CommonQueryParams)]):
-    response = {}
-    if commons.q:
-        response.update({"q": commons.q})
-    items = fake_items_db[commons.skip : commons.skip + commons.limit]
-    response.update({"items": items})
-    return response
diff --git a/docs_src/dependencies/tutorial003_py39.py b/docs_src/dependencies/tutorial003_py39.py
deleted file mode 100644 (file)
index 34614e5..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
-
-
-class CommonQueryParams:
-    def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100):
-        self.q = q
-        self.skip = skip
-        self.limit = limit
-
-
-@app.get("/items/")
-async def read_items(commons=Depends(CommonQueryParams)):
-    response = {}
-    if commons.q:
-        response.update({"q": commons.q})
-    items = fake_items_db[commons.skip : commons.skip + commons.limit]
-    response.update({"items": items})
-    return response
diff --git a/docs_src/dependencies/tutorial004_an_py39.py b/docs_src/dependencies/tutorial004_an_py39.py
deleted file mode 100644 (file)
index 7426862..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
-
-
-class CommonQueryParams:
-    def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100):
-        self.q = q
-        self.skip = skip
-        self.limit = limit
-
-
-@app.get("/items/")
-async def read_items(commons: Annotated[CommonQueryParams, Depends()]):
-    response = {}
-    if commons.q:
-        response.update({"q": commons.q})
-    items = fake_items_db[commons.skip : commons.skip + commons.limit]
-    response.update({"items": items})
-    return response
diff --git a/docs_src/dependencies/tutorial004_py39.py b/docs_src/dependencies/tutorial004_py39.py
deleted file mode 100644 (file)
index d9fe881..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-
-app = FastAPI()
-
-
-fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
-
-
-class CommonQueryParams:
-    def __init__(self, q: Union[str, None] = None, skip: int = 0, limit: int = 100):
-        self.q = q
-        self.skip = skip
-        self.limit = limit
-
-
-@app.get("/items/")
-async def read_items(commons: CommonQueryParams = Depends()):
-    response = {}
-    if commons.q:
-        response.update({"q": commons.q})
-    items = fake_items_db[commons.skip : commons.skip + commons.limit]
-    response.update({"items": items})
-    return response
diff --git a/docs_src/dependencies/tutorial005_an_py39.py b/docs_src/dependencies/tutorial005_an_py39.py
deleted file mode 100644 (file)
index d5dd8dc..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Cookie, Depends, FastAPI
-
-app = FastAPI()
-
-
-def query_extractor(q: Union[str, None] = None):
-    return q
-
-
-def query_or_cookie_extractor(
-    q: Annotated[str, Depends(query_extractor)],
-    last_query: Annotated[Union[str, None], Cookie()] = None,
-):
-    if not q:
-        return last_query
-    return q
-
-
-@app.get("/items/")
-async def read_query(
-    query_or_default: Annotated[str, Depends(query_or_cookie_extractor)],
-):
-    return {"q_or_cookie": query_or_default}
diff --git a/docs_src/dependencies/tutorial005_py39.py b/docs_src/dependencies/tutorial005_py39.py
deleted file mode 100644 (file)
index 697332b..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, Depends, FastAPI
-
-app = FastAPI()
-
-
-def query_extractor(q: Union[str, None] = None):
-    return q
-
-
-def query_or_cookie_extractor(
-    q: str = Depends(query_extractor),
-    last_query: Union[str, None] = Cookie(default=None),
-):
-    if not q:
-        return last_query
-    return q
-
-
-@app.get("/items/")
-async def read_query(query_or_default: str = Depends(query_or_cookie_extractor)):
-    return {"q_or_cookie": query_or_default}
diff --git a/docs_src/dependencies/tutorial006_an_py310.py b/docs_src/dependencies/tutorial006_an_py310.py
new file mode 100644 (file)
index 0000000..11976ed
--- /dev/null
@@ -0,0 +1,21 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI, Header, HTTPException
+
+app = FastAPI()
+
+
+async def verify_token(x_token: Annotated[str, Header()]):
+    if x_token != "fake-super-secret-token":
+        raise HTTPException(status_code=400, detail="X-Token header invalid")
+
+
+async def verify_key(x_key: Annotated[str, Header()]):
+    if x_key != "fake-super-secret-key":
+        raise HTTPException(status_code=400, detail="X-Key header invalid")
+    return x_key
+
+
+@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
+async def read_items():
+    return [{"item": "Foo"}, {"item": "Bar"}]
diff --git a/docs_src/dependencies/tutorial006_py310.py b/docs_src/dependencies/tutorial006_py310.py
new file mode 100644 (file)
index 0000000..9aff415
--- /dev/null
@@ -0,0 +1,19 @@
+from fastapi import Depends, FastAPI, Header, HTTPException
+
+app = FastAPI()
+
+
+async def verify_token(x_token: str = Header()):
+    if x_token != "fake-super-secret-token":
+        raise HTTPException(status_code=400, detail="X-Token header invalid")
+
+
+async def verify_key(x_key: str = Header()):
+    if x_key != "fake-super-secret-key":
+        raise HTTPException(status_code=400, detail="X-Key header invalid")
+    return x_key
+
+
+@app.get("/items/", dependencies=[Depends(verify_token), Depends(verify_key)])
+async def read_items():
+    return [{"item": "Foo"}, {"item": "Bar"}]
diff --git a/docs_src/dependencies/tutorial007_py310.py b/docs_src/dependencies/tutorial007_py310.py
new file mode 100644 (file)
index 0000000..2e4ab47
--- /dev/null
@@ -0,0 +1,6 @@
+async def get_db():
+    db = DBSession()
+    try:
+        yield db
+    finally:
+        db.close()
diff --git a/docs_src/dependencies/tutorial008_an_py310.py b/docs_src/dependencies/tutorial008_an_py310.py
new file mode 100644 (file)
index 0000000..acc804c
--- /dev/null
@@ -0,0 +1,27 @@
+from typing import Annotated
+
+from fastapi import Depends
+
+
+async def dependency_a():
+    dep_a = generate_dep_a()
+    try:
+        yield dep_a
+    finally:
+        dep_a.close()
+
+
+async def dependency_b(dep_a: Annotated[DepA, Depends(dependency_a)]):
+    dep_b = generate_dep_b()
+    try:
+        yield dep_b
+    finally:
+        dep_b.close(dep_a)
+
+
+async def dependency_c(dep_b: Annotated[DepB, Depends(dependency_b)]):
+    dep_c = generate_dep_c()
+    try:
+        yield dep_c
+    finally:
+        dep_c.close(dep_b)
diff --git a/docs_src/dependencies/tutorial008_py310.py b/docs_src/dependencies/tutorial008_py310.py
new file mode 100644 (file)
index 0000000..8472f64
--- /dev/null
@@ -0,0 +1,25 @@
+from fastapi import Depends
+
+
+async def dependency_a():
+    dep_a = generate_dep_a()
+    try:
+        yield dep_a
+    finally:
+        dep_a.close()
+
+
+async def dependency_b(dep_a=Depends(dependency_a)):
+    dep_b = generate_dep_b()
+    try:
+        yield dep_b
+    finally:
+        dep_b.close(dep_a)
+
+
+async def dependency_c(dep_b=Depends(dependency_b)):
+    dep_c = generate_dep_c()
+    try:
+        yield dep_c
+    finally:
+        dep_c.close(dep_b)
diff --git a/docs_src/dependencies/tutorial008b_an_py310.py b/docs_src/dependencies/tutorial008b_an_py310.py
new file mode 100644 (file)
index 0000000..3b8434c
--- /dev/null
@@ -0,0 +1,32 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI, HTTPException
+
+app = FastAPI()
+
+
+data = {
+    "plumbus": {"description": "Freshly pickled plumbus", "owner": "Morty"},
+    "portal-gun": {"description": "Gun to create portals", "owner": "Rick"},
+}
+
+
+class OwnerError(Exception):
+    pass
+
+
+def get_username():
+    try:
+        yield "Rick"
+    except OwnerError as e:
+        raise HTTPException(status_code=400, detail=f"Owner error: {e}")
+
+
+@app.get("/items/{item_id}")
+def get_item(item_id: str, username: Annotated[str, Depends(get_username)]):
+    if item_id not in data:
+        raise HTTPException(status_code=404, detail="Item not found")
+    item = data[item_id]
+    if item["owner"] != username:
+        raise OwnerError(username)
+    return item
diff --git a/docs_src/dependencies/tutorial008b_py310.py b/docs_src/dependencies/tutorial008b_py310.py
new file mode 100644 (file)
index 0000000..163e966
--- /dev/null
@@ -0,0 +1,30 @@
+from fastapi import Depends, FastAPI, HTTPException
+
+app = FastAPI()
+
+
+data = {
+    "plumbus": {"description": "Freshly pickled plumbus", "owner": "Morty"},
+    "portal-gun": {"description": "Gun to create portals", "owner": "Rick"},
+}
+
+
+class OwnerError(Exception):
+    pass
+
+
+def get_username():
+    try:
+        yield "Rick"
+    except OwnerError as e:
+        raise HTTPException(status_code=400, detail=f"Owner error: {e}")
+
+
+@app.get("/items/{item_id}")
+def get_item(item_id: str, username: str = Depends(get_username)):
+    if item_id not in data:
+        raise HTTPException(status_code=404, detail="Item not found")
+    item = data[item_id]
+    if item["owner"] != username:
+        raise OwnerError(username)
+    return item
diff --git a/docs_src/dependencies/tutorial008c_an_py310.py b/docs_src/dependencies/tutorial008c_an_py310.py
new file mode 100644 (file)
index 0000000..da92efa
--- /dev/null
@@ -0,0 +1,29 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI, HTTPException
+
+app = FastAPI()
+
+
+class InternalError(Exception):
+    pass
+
+
+def get_username():
+    try:
+        yield "Rick"
+    except InternalError:
+        print("Oops, we didn't raise again, Britney 😱")
+
+
+@app.get("/items/{item_id}")
+def get_item(item_id: str, username: Annotated[str, Depends(get_username)]):
+    if item_id == "portal-gun":
+        raise InternalError(
+            f"The portal gun is too dangerous to be owned by {username}"
+        )
+    if item_id != "plumbus":
+        raise HTTPException(
+            status_code=404, detail="Item not found, there's only a plumbus here"
+        )
+    return item_id
diff --git a/docs_src/dependencies/tutorial008c_py310.py b/docs_src/dependencies/tutorial008c_py310.py
new file mode 100644 (file)
index 0000000..4b99a5a
--- /dev/null
@@ -0,0 +1,27 @@
+from fastapi import Depends, FastAPI, HTTPException
+
+app = FastAPI()
+
+
+class InternalError(Exception):
+    pass
+
+
+def get_username():
+    try:
+        yield "Rick"
+    except InternalError:
+        print("Oops, we didn't raise again, Britney 😱")
+
+
+@app.get("/items/{item_id}")
+def get_item(item_id: str, username: str = Depends(get_username)):
+    if item_id == "portal-gun":
+        raise InternalError(
+            f"The portal gun is too dangerous to be owned by {username}"
+        )
+    if item_id != "plumbus":
+        raise HTTPException(
+            status_code=404, detail="Item not found, there's only a plumbus here"
+        )
+    return item_id
diff --git a/docs_src/dependencies/tutorial008d_an_py310.py b/docs_src/dependencies/tutorial008d_an_py310.py
new file mode 100644 (file)
index 0000000..99bd5cb
--- /dev/null
@@ -0,0 +1,30 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI, HTTPException
+
+app = FastAPI()
+
+
+class InternalError(Exception):
+    pass
+
+
+def get_username():
+    try:
+        yield "Rick"
+    except InternalError:
+        print("We don't swallow the internal error here, we raise again 😎")
+        raise
+
+
+@app.get("/items/{item_id}")
+def get_item(item_id: str, username: Annotated[str, Depends(get_username)]):
+    if item_id == "portal-gun":
+        raise InternalError(
+            f"The portal gun is too dangerous to be owned by {username}"
+        )
+    if item_id != "plumbus":
+        raise HTTPException(
+            status_code=404, detail="Item not found, there's only a plumbus here"
+        )
+    return item_id
diff --git a/docs_src/dependencies/tutorial008d_py310.py b/docs_src/dependencies/tutorial008d_py310.py
new file mode 100644 (file)
index 0000000..9303934
--- /dev/null
@@ -0,0 +1,28 @@
+from fastapi import Depends, FastAPI, HTTPException
+
+app = FastAPI()
+
+
+class InternalError(Exception):
+    pass
+
+
+def get_username():
+    try:
+        yield "Rick"
+    except InternalError:
+        print("We don't swallow the internal error here, we raise again 😎")
+        raise
+
+
+@app.get("/items/{item_id}")
+def get_item(item_id: str, username: str = Depends(get_username)):
+    if item_id == "portal-gun":
+        raise InternalError(
+            f"The portal gun is too dangerous to be owned by {username}"
+        )
+    if item_id != "plumbus":
+        raise HTTPException(
+            status_code=404, detail="Item not found, there's only a plumbus here"
+        )
+    return item_id
diff --git a/docs_src/dependencies/tutorial008e_an_py310.py b/docs_src/dependencies/tutorial008e_an_py310.py
new file mode 100644 (file)
index 0000000..80a44c7
--- /dev/null
@@ -0,0 +1,17 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI
+
+app = FastAPI()
+
+
+def get_username():
+    try:
+        yield "Rick"
+    finally:
+        print("Cleanup up before response is sent")
+
+
+@app.get("/users/me")
+def get_user_me(username: Annotated[str, Depends(get_username, scope="function")]):
+    return username
diff --git a/docs_src/dependencies/tutorial008e_py310.py b/docs_src/dependencies/tutorial008e_py310.py
new file mode 100644 (file)
index 0000000..1ed056e
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import Depends, FastAPI
+
+app = FastAPI()
+
+
+def get_username():
+    try:
+        yield "Rick"
+    finally:
+        print("Cleanup up before response is sent")
+
+
+@app.get("/users/me")
+def get_user_me(username: str = Depends(get_username, scope="function")):
+    return username
diff --git a/docs_src/dependencies/tutorial010_py310.py b/docs_src/dependencies/tutorial010_py310.py
new file mode 100644 (file)
index 0000000..c27f1b1
--- /dev/null
@@ -0,0 +1,14 @@
+class MySuperContextManager:
+    def __init__(self):
+        self.db = DBSession()
+
+    def __enter__(self):
+        return self.db
+
+    def __exit__(self, exc_type, exc_value, traceback):
+        self.db.close()
+
+
+async def get_db():
+    with MySuperContextManager() as db:
+        yield db
diff --git a/docs_src/dependencies/tutorial011_an_py310.py b/docs_src/dependencies/tutorial011_an_py310.py
new file mode 100644 (file)
index 0000000..68b7434
--- /dev/null
@@ -0,0 +1,23 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI
+
+app = FastAPI()
+
+
+class FixedContentQueryChecker:
+    def __init__(self, fixed_content: str):
+        self.fixed_content = fixed_content
+
+    def __call__(self, q: str = ""):
+        if q:
+            return self.fixed_content in q
+        return False
+
+
+checker = FixedContentQueryChecker("bar")
+
+
+@app.get("/query-checker/")
+async def read_query_check(fixed_content_included: Annotated[bool, Depends(checker)]):
+    return {"fixed_content_in_query": fixed_content_included}
diff --git a/docs_src/dependencies/tutorial011_py310.py b/docs_src/dependencies/tutorial011_py310.py
new file mode 100644 (file)
index 0000000..5d22f68
--- /dev/null
@@ -0,0 +1,21 @@
+from fastapi import Depends, FastAPI
+
+app = FastAPI()
+
+
+class FixedContentQueryChecker:
+    def __init__(self, fixed_content: str):
+        self.fixed_content = fixed_content
+
+    def __call__(self, q: str = ""):
+        if q:
+            return self.fixed_content in q
+        return False
+
+
+checker = FixedContentQueryChecker("bar")
+
+
+@app.get("/query-checker/")
+async def read_query_check(fixed_content_included: bool = Depends(checker)):
+    return {"fixed_content_in_query": fixed_content_included}
diff --git a/docs_src/dependencies/tutorial012_an_py310.py b/docs_src/dependencies/tutorial012_an_py310.py
new file mode 100644 (file)
index 0000000..6503591
--- /dev/null
@@ -0,0 +1,27 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI, Header, HTTPException
+
+
+async def verify_token(x_token: Annotated[str, Header()]):
+    if x_token != "fake-super-secret-token":
+        raise HTTPException(status_code=400, detail="X-Token header invalid")
+
+
+async def verify_key(x_key: Annotated[str, Header()]):
+    if x_key != "fake-super-secret-key":
+        raise HTTPException(status_code=400, detail="X-Key header invalid")
+    return x_key
+
+
+app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"item": "Portal Gun"}, {"item": "Plumbus"}]
+
+
+@app.get("/users/")
+async def read_users():
+    return [{"username": "Rick"}, {"username": "Morty"}]
diff --git a/docs_src/dependencies/tutorial012_py310.py b/docs_src/dependencies/tutorial012_py310.py
new file mode 100644 (file)
index 0000000..36ce6c7
--- /dev/null
@@ -0,0 +1,25 @@
+from fastapi import Depends, FastAPI, Header, HTTPException
+
+
+async def verify_token(x_token: str = Header()):
+    if x_token != "fake-super-secret-token":
+        raise HTTPException(status_code=400, detail="X-Token header invalid")
+
+
+async def verify_key(x_key: str = Header()):
+    if x_key != "fake-super-secret-key":
+        raise HTTPException(status_code=400, detail="X-Key header invalid")
+    return x_key
+
+
+app = FastAPI(dependencies=[Depends(verify_token), Depends(verify_key)])
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"item": "Portal Gun"}, {"item": "Plumbus"}]
+
+
+@app.get("/users/")
+async def read_users():
+    return [{"username": "Rick"}, {"username": "Morty"}]
diff --git a/docs_src/dependency_testing/tutorial001_an_py39.py b/docs_src/dependency_testing/tutorial001_an_py39.py
deleted file mode 100644 (file)
index bccb0cd..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI
-from fastapi.testclient import TestClient
-
-app = FastAPI()
-
-
-async def common_parameters(
-    q: Union[str, None] = None, skip: int = 0, limit: int = 100
-):
-    return {"q": q, "skip": skip, "limit": limit}
-
-
-@app.get("/items/")
-async def read_items(commons: Annotated[dict, Depends(common_parameters)]):
-    return {"message": "Hello Items!", "params": commons}
-
-
-@app.get("/users/")
-async def read_users(commons: Annotated[dict, Depends(common_parameters)]):
-    return {"message": "Hello Users!", "params": commons}
-
-
-client = TestClient(app)
-
-
-async def override_dependency(q: Union[str, None] = None):
-    return {"q": q, "skip": 5, "limit": 10}
-
-
-app.dependency_overrides[common_parameters] = override_dependency
-
-
-def test_override_in_items():
-    response = client.get("/items/")
-    assert response.status_code == 200
-    assert response.json() == {
-        "message": "Hello Items!",
-        "params": {"q": None, "skip": 5, "limit": 10},
-    }
-
-
-def test_override_in_items_with_q():
-    response = client.get("/items/?q=foo")
-    assert response.status_code == 200
-    assert response.json() == {
-        "message": "Hello Items!",
-        "params": {"q": "foo", "skip": 5, "limit": 10},
-    }
-
-
-def test_override_in_items_with_params():
-    response = client.get("/items/?q=foo&skip=100&limit=200")
-    assert response.status_code == 200
-    assert response.json() == {
-        "message": "Hello Items!",
-        "params": {"q": "foo", "skip": 5, "limit": 10},
-    }
diff --git a/docs_src/dependency_testing/tutorial001_py39.py b/docs_src/dependency_testing/tutorial001_py39.py
deleted file mode 100644 (file)
index a5fe1d9..0000000
+++ /dev/null
@@ -1,59 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from fastapi.testclient import TestClient
-
-app = FastAPI()
-
-
-async def common_parameters(
-    q: Union[str, None] = None, skip: int = 0, limit: int = 100
-):
-    return {"q": q, "skip": skip, "limit": limit}
-
-
-@app.get("/items/")
-async def read_items(commons: dict = Depends(common_parameters)):
-    return {"message": "Hello Items!", "params": commons}
-
-
-@app.get("/users/")
-async def read_users(commons: dict = Depends(common_parameters)):
-    return {"message": "Hello Users!", "params": commons}
-
-
-client = TestClient(app)
-
-
-async def override_dependency(q: Union[str, None] = None):
-    return {"q": q, "skip": 5, "limit": 10}
-
-
-app.dependency_overrides[common_parameters] = override_dependency
-
-
-def test_override_in_items():
-    response = client.get("/items/")
-    assert response.status_code == 200
-    assert response.json() == {
-        "message": "Hello Items!",
-        "params": {"q": None, "skip": 5, "limit": 10},
-    }
-
-
-def test_override_in_items_with_q():
-    response = client.get("/items/?q=foo")
-    assert response.status_code == 200
-    assert response.json() == {
-        "message": "Hello Items!",
-        "params": {"q": "foo", "skip": 5, "limit": 10},
-    }
-
-
-def test_override_in_items_with_params():
-    response = client.get("/items/?q=foo&skip=100&limit=200")
-    assert response.status_code == 200
-    assert response.json() == {
-        "message": "Hello Items!",
-        "params": {"q": "foo", "skip": 5, "limit": 10},
-    }
diff --git a/docs_src/encoder/tutorial001_py39.py b/docs_src/encoder/tutorial001_py39.py
deleted file mode 100644 (file)
index 5f7e706..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from datetime import datetime
-from typing import Union
-
-from fastapi import FastAPI
-from fastapi.encoders import jsonable_encoder
-from pydantic import BaseModel
-
-fake_db = {}
-
-
-class Item(BaseModel):
-    title: str
-    timestamp: datetime
-    description: Union[str, None] = None
-
-
-app = FastAPI()
-
-
-@app.put("/items/{id}")
-def update_item(id: str, item: Item):
-    json_compatible_item_data = jsonable_encoder(item)
-    fake_db[id] = json_compatible_item_data
diff --git a/docs_src/events/tutorial001_py310.py b/docs_src/events/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..128004c
--- /dev/null
@@ -0,0 +1,16 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+items = {}
+
+
+@app.on_event("startup")
+async def startup_event():
+    items["foo"] = {"name": "Fighters"}
+    items["bar"] = {"name": "Tenders"}
+
+
+@app.get("/items/{item_id}")
+async def read_items(item_id: str):
+    return items[item_id]
diff --git a/docs_src/events/tutorial002_py310.py b/docs_src/events/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..a71fea8
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.on_event("shutdown")
+def shutdown_event():
+    with open("log.txt", mode="a") as log:
+        log.write("Application shutdown")
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"name": "Foo"}]
diff --git a/docs_src/events/tutorial003_py310.py b/docs_src/events/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..2b65059
--- /dev/null
@@ -0,0 +1,28 @@
+from contextlib import asynccontextmanager
+
+from fastapi import FastAPI
+
+
+def fake_answer_to_everything_ml_model(x: float):
+    return x * 42
+
+
+ml_models = {}
+
+
+@asynccontextmanager
+async def lifespan(app: FastAPI):
+    # Load the ML model
+    ml_models["answer_to_everything"] = fake_answer_to_everything_ml_model
+    yield
+    # Clean up the ML models and release the resources
+    ml_models.clear()
+
+
+app = FastAPI(lifespan=lifespan)
+
+
+@app.get("/predict")
+async def predict(x: float):
+    result = ml_models["answer_to_everything"](x)
+    return {"result": result}
diff --git a/docs_src/extending_openapi/tutorial001_py310.py b/docs_src/extending_openapi/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..35e31c0
--- /dev/null
@@ -0,0 +1,29 @@
+from fastapi import FastAPI
+from fastapi.openapi.utils import get_openapi
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"name": "Foo"}]
+
+
+def custom_openapi():
+    if app.openapi_schema:
+        return app.openapi_schema
+    openapi_schema = get_openapi(
+        title="Custom title",
+        version="2.5.0",
+        summary="This is a very custom OpenAPI schema",
+        description="Here's a longer description of the custom **OpenAPI** schema",
+        routes=app.routes,
+    )
+    openapi_schema["info"]["x-logo"] = {
+        "url": "https://fastapi.tiangolo.com/img/logo-margin/logo-teal.png"
+    }
+    app.openapi_schema = openapi_schema
+    return app.openapi_schema
+
+
+app.openapi = custom_openapi
diff --git a/docs_src/extra_data_types/tutorial001_an_py39.py b/docs_src/extra_data_types/tutorial001_an_py39.py
deleted file mode 100644 (file)
index fa3551d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from datetime import datetime, time, timedelta
-from typing import Annotated, Union
-from uuid import UUID
-
-from fastapi import Body, FastAPI
-
-app = FastAPI()
-
-
-@app.put("/items/{item_id}")
-async def read_items(
-    item_id: UUID,
-    start_datetime: Annotated[datetime, Body()],
-    end_datetime: Annotated[datetime, Body()],
-    process_after: Annotated[timedelta, Body()],
-    repeat_at: Annotated[Union[time, None], Body()] = None,
-):
-    start_process = start_datetime + process_after
-    duration = end_datetime - start_process
-    return {
-        "item_id": item_id,
-        "start_datetime": start_datetime,
-        "end_datetime": end_datetime,
-        "process_after": process_after,
-        "repeat_at": repeat_at,
-        "start_process": start_process,
-        "duration": duration,
-    }
diff --git a/docs_src/extra_data_types/tutorial001_py39.py b/docs_src/extra_data_types/tutorial001_py39.py
deleted file mode 100644 (file)
index 71de958..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from datetime import datetime, time, timedelta
-from typing import Union
-from uuid import UUID
-
-from fastapi import Body, FastAPI
-
-app = FastAPI()
-
-
-@app.put("/items/{item_id}")
-async def read_items(
-    item_id: UUID,
-    start_datetime: datetime = Body(),
-    end_datetime: datetime = Body(),
-    process_after: timedelta = Body(),
-    repeat_at: Union[time, None] = Body(default=None),
-):
-    start_process = start_datetime + process_after
-    duration = end_datetime - start_process
-    return {
-        "item_id": item_id,
-        "start_datetime": start_datetime,
-        "end_datetime": end_datetime,
-        "process_after": process_after,
-        "repeat_at": repeat_at,
-        "start_process": start_process,
-        "duration": duration,
-    }
diff --git a/docs_src/extra_models/tutorial001_py39.py b/docs_src/extra_models/tutorial001_py39.py
deleted file mode 100644 (file)
index 327ffcd..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, EmailStr
-
-app = FastAPI()
-
-
-class UserIn(BaseModel):
-    username: str
-    password: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-class UserOut(BaseModel):
-    username: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-class UserInDB(BaseModel):
-    username: str
-    hashed_password: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-def fake_password_hasher(raw_password: str):
-    return "supersecret" + raw_password
-
-
-def fake_save_user(user_in: UserIn):
-    hashed_password = fake_password_hasher(user_in.password)
-    user_in_db = UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
-    print("User saved! ..not really")
-    return user_in_db
-
-
-@app.post("/user/", response_model=UserOut)
-async def create_user(user_in: UserIn):
-    user_saved = fake_save_user(user_in)
-    return user_saved
diff --git a/docs_src/extra_models/tutorial002_py39.py b/docs_src/extra_models/tutorial002_py39.py
deleted file mode 100644 (file)
index 6543796..0000000
+++ /dev/null
@@ -1,41 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, EmailStr
-
-app = FastAPI()
-
-
-class UserBase(BaseModel):
-    username: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-class UserIn(UserBase):
-    password: str
-
-
-class UserOut(UserBase):
-    pass
-
-
-class UserInDB(UserBase):
-    hashed_password: str
-
-
-def fake_password_hasher(raw_password: str):
-    return "supersecret" + raw_password
-
-
-def fake_save_user(user_in: UserIn):
-    hashed_password = fake_password_hasher(user_in.password)
-    user_in_db = UserInDB(**user_in.model_dump(), hashed_password=hashed_password)
-    print("User saved! ..not really")
-    return user_in_db
-
-
-@app.post("/user/", response_model=UserOut)
-async def create_user(user_in: UserIn):
-    user_saved = fake_save_user(user_in)
-    return user_saved
diff --git a/docs_src/extra_models/tutorial003_py39.py b/docs_src/extra_models/tutorial003_py39.py
deleted file mode 100644 (file)
index 06675cb..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class BaseItem(BaseModel):
-    description: str
-    type: str
-
-
-class CarItem(BaseItem):
-    type: str = "car"
-
-
-class PlaneItem(BaseItem):
-    type: str = "plane"
-    size: int
-
-
-items = {
-    "item1": {"description": "All my friends drive a low rider", "type": "car"},
-    "item2": {
-        "description": "Music is my aeroplane, it's my aeroplane",
-        "type": "plane",
-        "size": 5,
-    },
-}
-
-
-@app.get("/items/{item_id}", response_model=Union[PlaneItem, CarItem])
-async def read_item(item_id: str):
-    return items[item_id]
diff --git a/docs_src/extra_models/tutorial004_py310.py b/docs_src/extra_models/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..28cacde
--- /dev/null
@@ -0,0 +1,20 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    description: str
+
+
+items = [
+    {"name": "Foo", "description": "There comes my hero"},
+    {"name": "Red", "description": "It's my aeroplane"},
+]
+
+
+@app.get("/items/", response_model=list[Item])
+async def read_items():
+    return items
diff --git a/docs_src/extra_models/tutorial005_py310.py b/docs_src/extra_models/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..9da2a0a
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/keyword-weights/", response_model=dict[str, float])
+async def read_keyword_weights():
+    return {"foo": 2.3, "bar": 3.4}
diff --git a/docs_src/first_steps/tutorial001_py310.py b/docs_src/first_steps/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..ee60be1
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+async def root():
+    return {"message": "Hello World"}
diff --git a/docs_src/first_steps/tutorial003_py310.py b/docs_src/first_steps/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..e30b827
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/")
+def root():
+    return {"message": "Hello World"}
diff --git a/docs_src/generate_clients/tutorial001_py310.py b/docs_src/generate_clients/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..6a5ae23
--- /dev/null
@@ -0,0 +1,26 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    price: float
+
+
+class ResponseMessage(BaseModel):
+    message: str
+
+
+@app.post("/items/", response_model=ResponseMessage)
+async def create_item(item: Item):
+    return {"message": "item received"}
+
+
+@app.get("/items/", response_model=list[Item])
+async def get_items():
+    return [
+        {"name": "Plumbus", "price": 3},
+        {"name": "Portal Gun", "price": 9001},
+    ]
diff --git a/docs_src/generate_clients/tutorial002_py310.py b/docs_src/generate_clients/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..8330976
--- /dev/null
@@ -0,0 +1,36 @@
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Item(BaseModel):
+    name: str
+    price: float
+
+
+class ResponseMessage(BaseModel):
+    message: str
+
+
+class User(BaseModel):
+    username: str
+    email: str
+
+
+@app.post("/items/", response_model=ResponseMessage, tags=["items"])
+async def create_item(item: Item):
+    return {"message": "Item received"}
+
+
+@app.get("/items/", response_model=list[Item], tags=["items"])
+async def get_items():
+    return [
+        {"name": "Plumbus", "price": 3},
+        {"name": "Portal Gun", "price": 9001},
+    ]
+
+
+@app.post("/users/", response_model=ResponseMessage, tags=["users"])
+async def create_user(user: User):
+    return {"message": "User received"}
diff --git a/docs_src/generate_clients/tutorial003_py310.py b/docs_src/generate_clients/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..40722cf
--- /dev/null
@@ -0,0 +1,42 @@
+from fastapi import FastAPI
+from fastapi.routing import APIRoute
+from pydantic import BaseModel
+
+
+def custom_generate_unique_id(route: APIRoute):
+    return f"{route.tags[0]}-{route.name}"
+
+
+app = FastAPI(generate_unique_id_function=custom_generate_unique_id)
+
+
+class Item(BaseModel):
+    name: str
+    price: float
+
+
+class ResponseMessage(BaseModel):
+    message: str
+
+
+class User(BaseModel):
+    username: str
+    email: str
+
+
+@app.post("/items/", response_model=ResponseMessage, tags=["items"])
+async def create_item(item: Item):
+    return {"message": "Item received"}
+
+
+@app.get("/items/", response_model=list[Item], tags=["items"])
+async def get_items():
+    return [
+        {"name": "Plumbus", "price": 3},
+        {"name": "Portal Gun", "price": 9001},
+    ]
+
+
+@app.post("/users/", response_model=ResponseMessage, tags=["users"])
+async def create_user(user: User):
+    return {"message": "User received"}
diff --git a/docs_src/generate_clients/tutorial004_py310.py b/docs_src/generate_clients/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..894dc7f
--- /dev/null
@@ -0,0 +1,15 @@
+import json
+from pathlib import Path
+
+file_path = Path("./openapi.json")
+openapi_content = json.loads(file_path.read_text())
+
+for path_data in openapi_content["paths"].values():
+    for operation in path_data.values():
+        tag = operation["tags"][0]
+        operation_id = operation["operationId"]
+        to_remove = f"{tag}-"
+        new_operation_id = operation_id[len(to_remove) :]
+        operation["operationId"] = new_operation_id
+
+file_path.write_text(json.dumps(openapi_content))
diff --git a/docs_src/graphql_/tutorial001_py310.py b/docs_src/graphql_/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..e92b2d7
--- /dev/null
@@ -0,0 +1,25 @@
+import strawberry
+from fastapi import FastAPI
+from strawberry.fastapi import GraphQLRouter
+
+
+@strawberry.type
+class User:
+    name: str
+    age: int
+
+
+@strawberry.type
+class Query:
+    @strawberry.field
+    def user(self) -> User:
+        return User(name="Patrick", age=100)
+
+
+schema = strawberry.Schema(query=Query)
+
+
+graphql_app = GraphQLRouter(schema)
+
+app = FastAPI()
+app.include_router(graphql_app, prefix="/graphql")
diff --git a/docs_src/handling_errors/tutorial001_py310.py b/docs_src/handling_errors/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..e5f32aa
--- /dev/null
@@ -0,0 +1,12 @@
+from fastapi import FastAPI, HTTPException
+
+app = FastAPI()
+
+items = {"foo": "The Foo Wrestlers"}
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: str):
+    if item_id not in items:
+        raise HTTPException(status_code=404, detail="Item not found")
+    return {"item": items[item_id]}
diff --git a/docs_src/handling_errors/tutorial002_py310.py b/docs_src/handling_errors/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..e48c295
--- /dev/null
@@ -0,0 +1,16 @@
+from fastapi import FastAPI, HTTPException
+
+app = FastAPI()
+
+items = {"foo": "The Foo Wrestlers"}
+
+
+@app.get("/items-header/{item_id}")
+async def read_item_header(item_id: str):
+    if item_id not in items:
+        raise HTTPException(
+            status_code=404,
+            detail="Item not found",
+            headers={"X-Error": "There goes my error"},
+        )
+    return {"item": items[item_id]}
diff --git a/docs_src/handling_errors/tutorial003_py310.py b/docs_src/handling_errors/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..791cd68
--- /dev/null
@@ -0,0 +1,25 @@
+from fastapi import FastAPI, Request
+from fastapi.responses import JSONResponse
+
+
+class UnicornException(Exception):
+    def __init__(self, name: str):
+        self.name = name
+
+
+app = FastAPI()
+
+
+@app.exception_handler(UnicornException)
+async def unicorn_exception_handler(request: Request, exc: UnicornException):
+    return JSONResponse(
+        status_code=418,
+        content={"message": f"Oops! {exc.name} did something. There goes a rainbow..."},
+    )
+
+
+@app.get("/unicorns/{name}")
+async def read_unicorn(name: str):
+    if name == "yolo":
+        raise UnicornException(name=name)
+    return {"unicorn_name": name}
diff --git a/docs_src/handling_errors/tutorial004_py310.py b/docs_src/handling_errors/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..ae50807
--- /dev/null
@@ -0,0 +1,26 @@
+from fastapi import FastAPI, HTTPException
+from fastapi.exceptions import RequestValidationError
+from fastapi.responses import PlainTextResponse
+from starlette.exceptions import HTTPException as StarletteHTTPException
+
+app = FastAPI()
+
+
+@app.exception_handler(StarletteHTTPException)
+async def http_exception_handler(request, exc):
+    return PlainTextResponse(str(exc.detail), status_code=exc.status_code)
+
+
+@app.exception_handler(RequestValidationError)
+async def validation_exception_handler(request, exc: RequestValidationError):
+    message = "Validation errors:"
+    for error in exc.errors():
+        message += f"\nField: {error['loc']}, Error: {error['msg']}"
+    return PlainTextResponse(message, status_code=400)
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: int):
+    if item_id == 3:
+        raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
+    return {"item_id": item_id}
diff --git a/docs_src/handling_errors/tutorial005_py310.py b/docs_src/handling_errors/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..0e04fa0
--- /dev/null
@@ -0,0 +1,25 @@
+from fastapi import FastAPI, Request
+from fastapi.encoders import jsonable_encoder
+from fastapi.exceptions import RequestValidationError
+from fastapi.responses import JSONResponse
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+@app.exception_handler(RequestValidationError)
+async def validation_exception_handler(request: Request, exc: RequestValidationError):
+    return JSONResponse(
+        status_code=422,
+        content=jsonable_encoder({"detail": exc.errors(), "body": exc.body}),
+    )
+
+
+class Item(BaseModel):
+    title: str
+    size: int
+
+
+@app.post("/items/")
+async def create_item(item: Item):
+    return item
diff --git a/docs_src/handling_errors/tutorial006_py310.py b/docs_src/handling_errors/tutorial006_py310.py
new file mode 100644 (file)
index 0000000..e05160d
--- /dev/null
@@ -0,0 +1,28 @@
+from fastapi import FastAPI, HTTPException
+from fastapi.exception_handlers import (
+    http_exception_handler,
+    request_validation_exception_handler,
+)
+from fastapi.exceptions import RequestValidationError
+from starlette.exceptions import HTTPException as StarletteHTTPException
+
+app = FastAPI()
+
+
+@app.exception_handler(StarletteHTTPException)
+async def custom_http_exception_handler(request, exc):
+    print(f"OMG! An HTTP error!: {repr(exc)}")
+    return await http_exception_handler(request, exc)
+
+
+@app.exception_handler(RequestValidationError)
+async def validation_exception_handler(request, exc):
+    print(f"OMG! The client sent invalid data!: {exc}")
+    return await request_validation_exception_handler(request, exc)
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: int):
+    if item_id == 3:
+        raise HTTPException(status_code=418, detail="Nope! I don't like 3.")
+    return {"item_id": item_id}
diff --git a/docs_src/header_param_models/tutorial001_an_py39.py b/docs_src/header_param_models/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 51a5f94..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: Annotated[CommonHeaders, Header()]):
-    return headers
diff --git a/docs_src/header_param_models/tutorial001_py39.py b/docs_src/header_param_models/tutorial001_py39.py
deleted file mode 100644 (file)
index 4c11378..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: CommonHeaders = Header()):
-    return headers
diff --git a/docs_src/header_param_models/tutorial002_an_py39.py b/docs_src/header_param_models/tutorial002_an_py39.py
deleted file mode 100644 (file)
index ca5208c..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    model_config = {"extra": "forbid"}
-
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: Annotated[CommonHeaders, Header()]):
-    return headers
diff --git a/docs_src/header_param_models/tutorial002_py39.py b/docs_src/header_param_models/tutorial002_py39.py
deleted file mode 100644 (file)
index f8ce559..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    model_config = {"extra": "forbid"}
-
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: CommonHeaders = Header()):
-    return headers
diff --git a/docs_src/header_param_models/tutorial003_an_py39.py b/docs_src/header_param_models/tutorial003_an_py39.py
deleted file mode 100644 (file)
index 8be6b01..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(
-    headers: Annotated[CommonHeaders, Header(convert_underscores=False)],
-):
-    return headers
diff --git a/docs_src/header_param_models/tutorial003_py39.py b/docs_src/header_param_models/tutorial003_py39.py
deleted file mode 100644 (file)
index 848c341..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    host: str
-    save_data: bool
-    if_modified_since: Union[str, None] = None
-    traceparent: Union[str, None] = None
-    x_tag: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(headers: CommonHeaders = Header(convert_underscores=False)):
-    return headers
diff --git a/docs_src/header_params/tutorial001_an_py39.py b/docs_src/header_params/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 1fbe3bb..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(user_agent: Annotated[Union[str, None], Header()] = None):
-    return {"User-Agent": user_agent}
diff --git a/docs_src/header_params/tutorial001_py39.py b/docs_src/header_params/tutorial001_py39.py
deleted file mode 100644 (file)
index 74429c8..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(user_agent: Union[str, None] = Header(default=None)):
-    return {"User-Agent": user_agent}
diff --git a/docs_src/header_params/tutorial002_an_py39.py b/docs_src/header_params/tutorial002_an_py39.py
deleted file mode 100644 (file)
index 008e4b6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    strange_header: Annotated[
-        Union[str, None], Header(convert_underscores=False)
-    ] = None,
-):
-    return {"strange_header": strange_header}
diff --git a/docs_src/header_params/tutorial002_py39.py b/docs_src/header_params/tutorial002_py39.py
deleted file mode 100644 (file)
index 0a34f17..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    strange_header: Union[str, None] = Header(default=None, convert_underscores=False),
-):
-    return {"strange_header": strange_header}
diff --git a/docs_src/header_params/tutorial003_an_py39.py b/docs_src/header_params/tutorial003_an_py39.py
deleted file mode 100644 (file)
index 5aad894..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Header
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(x_token: Annotated[Union[list[str], None], Header()] = None):
-    return {"X-Token values": x_token}
diff --git a/docs_src/header_params/tutorial003_py39.py b/docs_src/header_params/tutorial003_py39.py
deleted file mode 100644 (file)
index 34437db..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(x_token: Union[list[str], None] = Header(default=None)):
-    return {"X-Token values": x_token}
diff --git a/docs_src/metadata/tutorial001_1_py310.py b/docs_src/metadata/tutorial001_1_py310.py
new file mode 100644 (file)
index 0000000..419232d
--- /dev/null
@@ -0,0 +1,38 @@
+from fastapi import FastAPI
+
+description = """
+ChimichangApp API helps you do awesome stuff. 🚀
+
+## Items
+
+You can **read items**.
+
+## Users
+
+You will be able to:
+
+* **Create users** (_not implemented_).
+* **Read users** (_not implemented_).
+"""
+
+app = FastAPI(
+    title="ChimichangApp",
+    description=description,
+    summary="Deadpool's favorite app. Nuff said.",
+    version="0.0.1",
+    terms_of_service="http://example.com/terms/",
+    contact={
+        "name": "Deadpoolio the Amazing",
+        "url": "http://x-force.example.com/contact/",
+        "email": "dp@x-force.example.com",
+    },
+    license_info={
+        "name": "Apache 2.0",
+        "identifier": "Apache-2.0",
+    },
+)
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"name": "Katana"}]
diff --git a/docs_src/metadata/tutorial001_py310.py b/docs_src/metadata/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..76656e8
--- /dev/null
@@ -0,0 +1,38 @@
+from fastapi import FastAPI
+
+description = """
+ChimichangApp API helps you do awesome stuff. 🚀
+
+## Items
+
+You can **read items**.
+
+## Users
+
+You will be able to:
+
+* **Create users** (_not implemented_).
+* **Read users** (_not implemented_).
+"""
+
+app = FastAPI(
+    title="ChimichangApp",
+    description=description,
+    summary="Deadpool's favorite app. Nuff said.",
+    version="0.0.1",
+    terms_of_service="http://example.com/terms/",
+    contact={
+        "name": "Deadpoolio the Amazing",
+        "url": "http://x-force.example.com/contact/",
+        "email": "dp@x-force.example.com",
+    },
+    license_info={
+        "name": "Apache 2.0",
+        "url": "https://www.apache.org/licenses/LICENSE-2.0.html",
+    },
+)
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"name": "Katana"}]
diff --git a/docs_src/metadata/tutorial002_py310.py b/docs_src/metadata/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..cf9ed70
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI(openapi_url="/api/v1/openapi.json")
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"name": "Foo"}]
diff --git a/docs_src/metadata/tutorial003_py310.py b/docs_src/metadata/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..ee09c7f
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI(docs_url="/documentation", redoc_url=None)
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"name": "Foo"}]
diff --git a/docs_src/metadata/tutorial004_py310.py b/docs_src/metadata/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..465bd65
--- /dev/null
@@ -0,0 +1,28 @@
+from fastapi import FastAPI
+
+tags_metadata = [
+    {
+        "name": "users",
+        "description": "Operations with users. The **login** logic is also here.",
+    },
+    {
+        "name": "items",
+        "description": "Manage items. So _fancy_ they have their own docs.",
+        "externalDocs": {
+            "description": "Items external docs",
+            "url": "https://fastapi.tiangolo.com/",
+        },
+    },
+]
+
+app = FastAPI(openapi_tags=tags_metadata)
+
+
+@app.get("/users/", tags=["users"])
+async def get_users():
+    return [{"name": "Harry"}, {"name": "Ron"}]
+
+
+@app.get("/items/", tags=["items"])
+async def get_items():
+    return [{"name": "wand"}, {"name": "flying broom"}]
diff --git a/docs_src/middleware/tutorial001_py310.py b/docs_src/middleware/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..e65a7da
--- /dev/null
@@ -0,0 +1,14 @@
+import time
+
+from fastapi import FastAPI, Request
+
+app = FastAPI()
+
+
+@app.middleware("http")
+async def add_process_time_header(request: Request, call_next):
+    start_time = time.perf_counter()
+    response = await call_next(request)
+    process_time = time.perf_counter() - start_time
+    response.headers["X-Process-Time"] = str(process_time)
+    return response
diff --git a/docs_src/openapi_callbacks/tutorial001_py39.py b/docs_src/openapi_callbacks/tutorial001_py39.py
deleted file mode 100644 (file)
index 3f1bac6..0000000
+++ /dev/null
@@ -1,53 +0,0 @@
-from typing import Union
-
-from fastapi import APIRouter, FastAPI
-from pydantic import BaseModel, HttpUrl
-
-app = FastAPI()
-
-
-class Invoice(BaseModel):
-    id: str
-    title: Union[str, None] = None
-    customer: str
-    total: float
-
-
-class InvoiceEvent(BaseModel):
-    description: str
-    paid: bool
-
-
-class InvoiceEventReceived(BaseModel):
-    ok: bool
-
-
-invoices_callback_router = APIRouter()
-
-
-@invoices_callback_router.post(
-    "{$callback_url}/invoices/{$request.body.id}", response_model=InvoiceEventReceived
-)
-def invoice_notification(body: InvoiceEvent):
-    pass
-
-
-@app.post("/invoices/", callbacks=invoices_callback_router.routes)
-def create_invoice(invoice: Invoice, callback_url: Union[HttpUrl, None] = None):
-    """
-    Create an invoice.
-
-    This will (let's imagine) let the API user (some external developer) create an
-    invoice.
-
-    And this path operation will:
-
-    * Send the invoice to the client.
-    * Collect the money from the client.
-    * Send a notification back to the API user (the external developer), as a callback.
-        * At this point is that the API will somehow send a POST request to the
-            external API with the notification of the invoice event
-            (e.g. "payment successful").
-    """
-    # Send the invoice, collect the money, send the notification (the callback)
-    return {"msg": "Invoice received"}
diff --git a/docs_src/openapi_webhooks/tutorial001_py310.py b/docs_src/openapi_webhooks/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..55822bb
--- /dev/null
@@ -0,0 +1,25 @@
+from datetime import datetime
+
+from fastapi import FastAPI
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class Subscription(BaseModel):
+    username: str
+    monthly_fee: float
+    start_date: datetime
+
+
+@app.webhooks.post("new-subscription")
+def new_subscription(body: Subscription):
+    """
+    When a new user subscribes to your service we'll send you a POST request with this
+    data to the URL that you register for the event `new-subscription` in the dashboard.
+    """
+
+
+@app.get("/users/")
+def read_users():
+    return ["Rick", "Morty"]
diff --git a/docs_src/path_operation_advanced_configuration/tutorial001_py310.py b/docs_src/path_operation_advanced_configuration/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..fafa8ff
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/", operation_id="some_specific_id_you_define")
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs_src/path_operation_advanced_configuration/tutorial002_py310.py b/docs_src/path_operation_advanced_configuration/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..3aaae9b
--- /dev/null
@@ -0,0 +1,24 @@
+from fastapi import FastAPI
+from fastapi.routing import APIRoute
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items():
+    return [{"item_id": "Foo"}]
+
+
+def use_route_names_as_operation_ids(app: FastAPI) -> None:
+    """
+    Simplify operation IDs so that generated API clients have simpler function
+    names.
+
+    Should be called only after all routes have been added.
+    """
+    for route in app.routes:
+        if isinstance(route, APIRoute):
+            route.operation_id = route.name  # in this case, 'read_items'
+
+
+use_route_names_as_operation_ids(app)
diff --git a/docs_src/path_operation_advanced_configuration/tutorial003_py310.py b/docs_src/path_operation_advanced_configuration/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..dcc358e
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/", include_in_schema=False)
+async def read_items():
+    return [{"item_id": "Foo"}]
diff --git a/docs_src/path_operation_advanced_configuration/tutorial004_py39.py b/docs_src/path_operation_advanced_configuration/tutorial004_py39.py
deleted file mode 100644 (file)
index 8fabe7c..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-
-
-@app.post("/items/", summary="Create an item")
-async def create_item(item: Item) -> Item:
-    """
-    Create an item with all the information:
-
-    - **name**: each item must have a name
-    - **description**: a long description
-    - **price**: required
-    - **tax**: if the item doesn't have tax, you can omit this
-    - **tags**: a set of unique tag strings for this item
-    \f
-    :param item: User input.
-    """
-    return item
diff --git a/docs_src/path_operation_advanced_configuration/tutorial005_py310.py b/docs_src/path_operation_advanced_configuration/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..5837ad8
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/", openapi_extra={"x-aperture-labs-portal": "blue"})
+async def read_items():
+    return [{"item_id": "portal-gun"}]
diff --git a/docs_src/path_operation_advanced_configuration/tutorial006_py310.py b/docs_src/path_operation_advanced_configuration/tutorial006_py310.py
new file mode 100644 (file)
index 0000000..403c3ee
--- /dev/null
@@ -0,0 +1,41 @@
+from fastapi import FastAPI, Request
+
+app = FastAPI()
+
+
+def magic_data_reader(raw_body: bytes):
+    return {
+        "size": len(raw_body),
+        "content": {
+            "name": "Maaaagic",
+            "price": 42,
+            "description": "Just kiddin', no magic here. ✨",
+        },
+    }
+
+
+@app.post(
+    "/items/",
+    openapi_extra={
+        "requestBody": {
+            "content": {
+                "application/json": {
+                    "schema": {
+                        "required": ["name", "price"],
+                        "type": "object",
+                        "properties": {
+                            "name": {"type": "string"},
+                            "price": {"type": "number"},
+                            "description": {"type": "string"},
+                        },
+                    }
+                }
+            },
+            "required": True,
+        },
+    },
+)
+async def create_item(request: Request):
+    raw_body = await request.body()
+    data = magic_data_reader(raw_body)
+    return data
similarity index 68%
rename from docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py
rename to docs_src/path_operation_advanced_configuration/tutorial007_py310.py
index 849f648e12535fd01e0165b622b8c130f1f71e57..ff64ef792323501fa78f0c54382cc3253e6f8678 100644 (file)
@@ -1,6 +1,6 @@
 import yaml
 from fastapi import FastAPI, HTTPException, Request
-from pydantic.v1 import BaseModel, ValidationError
+from pydantic import BaseModel, ValidationError
 
 app = FastAPI()
 
@@ -14,7 +14,7 @@ class Item(BaseModel):
     "/items/",
     openapi_extra={
         "requestBody": {
-            "content": {"application/x-yaml": {"schema": Item.schema()}},
+            "content": {"application/x-yaml": {"schema": Item.model_json_schema()}},
             "required": True,
         },
     },
@@ -26,7 +26,7 @@ async def create_item(request: Request):
     except yaml.YAMLError:
         raise HTTPException(status_code=422, detail="Invalid YAML")
     try:
-        item = Item.parse_obj(data)
+        item = Item.model_validate(data)
     except ValidationError as e:
-        raise HTTPException(status_code=422, detail=e.errors())
+        raise HTTPException(status_code=422, detail=e.errors(include_url=False))
     return item
diff --git a/docs_src/path_operation_configuration/tutorial001_py39.py b/docs_src/path_operation_configuration/tutorial001_py39.py
deleted file mode 100644 (file)
index 09b3182..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, status
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-
-
-@app.post("/items/", status_code=status.HTTP_201_CREATED)
-async def create_item(item: Item) -> Item:
-    return item
diff --git a/docs_src/path_operation_configuration/tutorial002_py39.py b/docs_src/path_operation_configuration/tutorial002_py39.py
deleted file mode 100644 (file)
index fca3b0d..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-
-
-@app.post("/items/", tags=["items"])
-async def create_item(item: Item) -> Item:
-    return item
-
-
-@app.get("/items/", tags=["items"])
-async def read_items():
-    return [{"name": "Foo", "price": 42}]
-
-
-@app.get("/users/", tags=["users"])
-async def read_users():
-    return [{"username": "johndoe"}]
diff --git a/docs_src/path_operation_configuration/tutorial002b_py310.py b/docs_src/path_operation_configuration/tutorial002b_py310.py
new file mode 100644 (file)
index 0000000..d53b4d8
--- /dev/null
@@ -0,0 +1,20 @@
+from enum import Enum
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+class Tags(Enum):
+    items = "items"
+    users = "users"
+
+
+@app.get("/items/", tags=[Tags.items])
+async def get_items():
+    return ["Portal gun", "Plumbus"]
+
+
+@app.get("/users/", tags=[Tags.users])
+async def read_users():
+    return ["Rick", "Morty"]
diff --git a/docs_src/path_operation_configuration/tutorial003_py39.py b/docs_src/path_operation_configuration/tutorial003_py39.py
deleted file mode 100644 (file)
index a77fb34..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-
-
-@app.post(
-    "/items/",
-    summary="Create an item",
-    description="Create an item with all the information, name, description, price, tax and a set of unique tags",
-)
-async def create_item(item: Item) -> Item:
-    return item
diff --git a/docs_src/path_operation_configuration/tutorial004_py39.py b/docs_src/path_operation_configuration/tutorial004_py39.py
deleted file mode 100644 (file)
index 31dfbff..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-
-
-@app.post("/items/", summary="Create an item")
-async def create_item(item: Item) -> Item:
-    """
-    Create an item with all the information:
-
-    - **name**: each item must have a name
-    - **description**: a long description
-    - **price**: required
-    - **tax**: if the item doesn't have tax, you can omit this
-    - **tags**: a set of unique tag strings for this item
-    """
-    return item
diff --git a/docs_src/path_operation_configuration/tutorial005_py39.py b/docs_src/path_operation_configuration/tutorial005_py39.py
deleted file mode 100644 (file)
index 0a53a8f..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: set[str] = set()
-
-
-@app.post(
-    "/items/",
-    summary="Create an item",
-    response_description="The created item",
-)
-async def create_item(item: Item) -> Item:
-    """
-    Create an item with all the information:
-
-    - **name**: each item must have a name
-    - **description**: a long description
-    - **price**: required
-    - **tax**: if the item doesn't have tax, you can omit this
-    - **tags**: a set of unique tag strings for this item
-    """
-    return item
diff --git a/docs_src/path_operation_configuration/tutorial006_py310.py b/docs_src/path_operation_configuration/tutorial006_py310.py
new file mode 100644 (file)
index 0000000..7c1aa9b
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/", tags=["items"])
+async def read_items():
+    return [{"name": "Foo", "price": 42}]
+
+
+@app.get("/users/", tags=["users"])
+async def read_users():
+    return [{"username": "johndoe"}]
+
+
+@app.get("/elements/", tags=["items"], deprecated=True)
+async def read_elements():
+    return [{"item_id": "Foo"}]
diff --git a/docs_src/path_params/tutorial001_py310.py b/docs_src/path_params/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..7bbf70e
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id):
+    return {"item_id": item_id}
diff --git a/docs_src/path_params/tutorial002_py310.py b/docs_src/path_params/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..8272ad7
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_item(item_id: int):
+    return {"item_id": item_id}
diff --git a/docs_src/path_params/tutorial003_py310.py b/docs_src/path_params/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..5f0aa09
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/users/me")
+async def read_user_me():
+    return {"user_id": "the current user"}
+
+
+@app.get("/users/{user_id}")
+async def read_user(user_id: str):
+    return {"user_id": user_id}
diff --git a/docs_src/path_params/tutorial003b_py310.py b/docs_src/path_params/tutorial003b_py310.py
new file mode 100644 (file)
index 0000000..822d373
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/users")
+async def read_users():
+    return ["Rick", "Morty"]
+
+
+@app.get("/users")
+async def read_users2():
+    return ["Bean", "Elfo"]
diff --git a/docs_src/path_params/tutorial004_py310.py b/docs_src/path_params/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..2961e61
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/files/{file_path:path}")
+async def read_file(file_path: str):
+    return {"file_path": file_path}
diff --git a/docs_src/path_params/tutorial005_py310.py b/docs_src/path_params/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..9a24a49
--- /dev/null
@@ -0,0 +1,23 @@
+from enum import Enum
+
+from fastapi import FastAPI
+
+
+class ModelName(str, Enum):
+    alexnet = "alexnet"
+    resnet = "resnet"
+    lenet = "lenet"
+
+
+app = FastAPI()
+
+
+@app.get("/models/{model_name}")
+async def get_model(model_name: ModelName):
+    if model_name is ModelName.alexnet:
+        return {"model_name": model_name, "message": "Deep Learning FTW!"}
+
+    if model_name.value == "lenet":
+        return {"model_name": model_name, "message": "LeCNN all the images"}
+
+    return {"model_name": model_name, "message": "Have some residuals"}
diff --git a/docs_src/path_params_numeric_validations/tutorial002_an_py310.py b/docs_src/path_params_numeric_validations/tutorial002_an_py310.py
new file mode 100644 (file)
index 0000000..cd882ab
--- /dev/null
@@ -0,0 +1,15 @@
+from typing import Annotated
+
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    q: str, item_id: Annotated[int, Path(title="The ID of the item to get")]
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial002_py310.py b/docs_src/path_params_numeric_validations/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..63ac691
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(q: str, item_id: int = Path(title="The ID of the item to get")):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial003_an_py310.py b/docs_src/path_params_numeric_validations/tutorial003_an_py310.py
new file mode 100644 (file)
index 0000000..1588556
--- /dev/null
@@ -0,0 +1,15 @@
+from typing import Annotated
+
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    item_id: Annotated[int, Path(title="The ID of the item to get")], q: str
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial003_py310.py b/docs_src/path_params_numeric_validations/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..8df0ffc
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(*, item_id: int = Path(title="The ID of the item to get"), q: str):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial004_an_py310.py b/docs_src/path_params_numeric_validations/tutorial004_an_py310.py
new file mode 100644 (file)
index 0000000..f67f645
--- /dev/null
@@ -0,0 +1,15 @@
+from typing import Annotated
+
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    item_id: Annotated[int, Path(title="The ID of the item to get", ge=1)], q: str
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial004_py310.py b/docs_src/path_params_numeric_validations/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..86651d4
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    *, item_id: int = Path(title="The ID of the item to get", ge=1), q: str
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial005_an_py310.py b/docs_src/path_params_numeric_validations/tutorial005_an_py310.py
new file mode 100644 (file)
index 0000000..571dd58
--- /dev/null
@@ -0,0 +1,16 @@
+from typing import Annotated
+
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    item_id: Annotated[int, Path(title="The ID of the item to get", gt=0, le=1000)],
+    q: str,
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial005_py310.py b/docs_src/path_params_numeric_validations/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..8f12f2d
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, Path
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_items(
+    *,
+    item_id: int = Path(title="The ID of the item to get", gt=0, le=1000),
+    q: str,
+):
+    results = {"item_id": item_id}
+    if q:
+        results.update({"q": q})
+    return results
similarity index 61%
rename from docs_src/path_params_numeric_validations/tutorial001_an_py39.py
rename to docs_src/path_params_numeric_validations/tutorial006_an_py310.py
index b36315a46dd8ee3bd5b75269ccec6e9bf897adae..426ec3776446bb49092be1e511833cd6162b017a 100644 (file)
@@ -1,4 +1,4 @@
-from typing import Annotated, Union
+from typing import Annotated
 
 from fastapi import FastAPI, Path, Query
 
@@ -7,10 +7,14 @@ app = FastAPI()
 
 @app.get("/items/{item_id}")
 async def read_items(
-    item_id: Annotated[int, Path(title="The ID of the item to get")],
-    q: Annotated[Union[str, None], Query(alias="item-query")] = None,
+    *,
+    item_id: Annotated[int, Path(title="The ID of the item to get", ge=0, le=1000)],
+    q: str,
+    size: Annotated[float, Query(gt=0, lt=10.5)],
 ):
     results = {"item_id": item_id}
     if q:
         results.update({"q": q})
+    if size:
+        results.update({"size": size})
     return results
similarity index 53%
rename from docs_src/path_params_numeric_validations/tutorial001_py39.py
rename to docs_src/path_params_numeric_validations/tutorial006_py310.py
index 53014702826e37b3450ec180daef58953a658a4e..f07629aa0ae03577d8b25c5f82d308b272c31b51 100644 (file)
@@ -1,5 +1,3 @@
-from typing import Union
-
 from fastapi import FastAPI, Path, Query
 
 app = FastAPI()
@@ -7,10 +5,14 @@ app = FastAPI()
 
 @app.get("/items/{item_id}")
 async def read_items(
-    item_id: int = Path(title="The ID of the item to get"),
-    q: Union[str, None] = Query(default=None, alias="item-query"),
+    *,
+    item_id: int = Path(title="The ID of the item to get", ge=0, le=1000),
+    q: str,
+    size: float = Query(gt=0, lt=10.5),
 ):
     results = {"item_id": item_id}
     if q:
         results.update({"q": q})
+    if size:
+        results.update({"size": size})
     return results
diff --git a/docs_src/pydantic_v1_in_v2/tutorial001_an_py39.py b/docs_src/pydantic_v1_in_v2/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 62a4b2c..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-from typing import Union
-
-from pydantic.v1 import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    size: float
diff --git a/docs_src/pydantic_v1_in_v2/tutorial002_an_py39.py b/docs_src/pydantic_v1_in_v2/tutorial002_an_py39.py
deleted file mode 100644 (file)
index 3c6a060..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic.v1 import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    size: float
-
-
-app = FastAPI()
-
-
-@app.post("/items/")
-async def create_item(item: Item) -> Item:
-    return item
diff --git a/docs_src/pydantic_v1_in_v2/tutorial003_an_py39.py b/docs_src/pydantic_v1_in_v2/tutorial003_an_py39.py
deleted file mode 100644 (file)
index 117d6f7..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel as BaseModelV2
-from pydantic.v1 import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    size: float
-
-
-class ItemV2(BaseModelV2):
-    name: str
-    description: Union[str, None] = None
-    size: float
-
-
-app = FastAPI()
-
-
-@app.post("/items/", response_model=ItemV2)
-async def create_item(item: Item):
-    return item
diff --git a/docs_src/pydantic_v1_in_v2/tutorial004_an_py39.py b/docs_src/pydantic_v1_in_v2/tutorial004_an_py39.py
deleted file mode 100644 (file)
index 150ab20..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI
-from fastapi.temp_pydantic_v1_params import Body
-from pydantic.v1 import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    size: float
-
-
-app = FastAPI()
-
-
-@app.post("/items/")
-async def create_item(item: Annotated[Item, Body(embed=True)]) -> Item:
-    return item
diff --git a/docs_src/python_types/tutorial001_py310.py b/docs_src/python_types/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..0903943
--- /dev/null
@@ -0,0 +1,6 @@
+def get_full_name(first_name, last_name):
+    full_name = first_name.title() + " " + last_name.title()
+    return full_name
+
+
+print(get_full_name("john", "doe"))
diff --git a/docs_src/python_types/tutorial002_py310.py b/docs_src/python_types/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..c0857a1
--- /dev/null
@@ -0,0 +1,6 @@
+def get_full_name(first_name: str, last_name: str):
+    full_name = first_name.title() + " " + last_name.title()
+    return full_name
+
+
+print(get_full_name("john", "doe"))
diff --git a/docs_src/python_types/tutorial003_py310.py b/docs_src/python_types/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..d021d82
--- /dev/null
@@ -0,0 +1,3 @@
+def get_name_with_age(name: str, age: int):
+    name_with_age = name + " is this old: " + age
+    return name_with_age
diff --git a/docs_src/python_types/tutorial004_py310.py b/docs_src/python_types/tutorial004_py310.py
new file mode 100644 (file)
index 0000000..9400269
--- /dev/null
@@ -0,0 +1,3 @@
+def get_name_with_age(name: str, age: int):
+    name_with_age = name + " is this old: " + str(age)
+    return name_with_age
diff --git a/docs_src/python_types/tutorial005_py310.py b/docs_src/python_types/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..6c8edb0
--- /dev/null
@@ -0,0 +1,2 @@
+def get_items(item_a: str, item_b: int, item_c: float, item_d: bool, item_e: bytes):
+    return item_a, item_b, item_c, item_d, item_e
diff --git a/docs_src/python_types/tutorial006_py310.py b/docs_src/python_types/tutorial006_py310.py
new file mode 100644 (file)
index 0000000..486b67c
--- /dev/null
@@ -0,0 +1,3 @@
+def process_items(items: list[str]):
+    for item in items:
+        print(item)
diff --git a/docs_src/python_types/tutorial007_py310.py b/docs_src/python_types/tutorial007_py310.py
new file mode 100644 (file)
index 0000000..ea96c79
--- /dev/null
@@ -0,0 +1,2 @@
+def process_items(items_t: tuple[int, int, str], items_s: set[bytes]):
+    return items_t, items_s
diff --git a/docs_src/python_types/tutorial008_py310.py b/docs_src/python_types/tutorial008_py310.py
new file mode 100644 (file)
index 0000000..a393385
--- /dev/null
@@ -0,0 +1,4 @@
+def process_items(prices: dict[str, float]):
+    for item_name, item_price in prices.items():
+        print(item_name)
+        print(item_price)
diff --git a/docs_src/python_types/tutorial010_py310.py b/docs_src/python_types/tutorial010_py310.py
new file mode 100644 (file)
index 0000000..468cffc
--- /dev/null
@@ -0,0 +1,7 @@
+class Person:
+    def __init__(self, name: str):
+        self.name = name
+
+
+def get_person_name(one_person: Person):
+    return one_person.name
diff --git a/docs_src/python_types/tutorial011_py39.py b/docs_src/python_types/tutorial011_py39.py
deleted file mode 100644 (file)
index 4eb40b4..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from datetime import datetime
-from typing import Union
-
-from pydantic import BaseModel
-
-
-class User(BaseModel):
-    id: int
-    name: str = "John Doe"
-    signup_ts: Union[datetime, None] = None
-    friends: list[int] = []
-
-
-external_data = {
-    "id": "123",
-    "signup_ts": "2017-06-01 12:22",
-    "friends": [1, "2", b"3"],
-}
-user = User(**external_data)
-print(user)
-# > User id=123 name='John Doe' signup_ts=datetime.datetime(2017, 6, 1, 12, 22) friends=[1, 2, 3]
-print(user.id)
-# > 123
diff --git a/docs_src/python_types/tutorial012_py39.py b/docs_src/python_types/tutorial012_py39.py
deleted file mode 100644 (file)
index 74fa94c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-from typing import Optional
-
-from pydantic import BaseModel
-
-
-class User(BaseModel):
-    name: str
-    age: Optional[int]
diff --git a/docs_src/python_types/tutorial013_py310.py b/docs_src/python_types/tutorial013_py310.py
new file mode 100644 (file)
index 0000000..65a0eaa
--- /dev/null
@@ -0,0 +1,5 @@
+from typing import Annotated
+
+
+def say_hello(name: Annotated[str, "this is just metadata"]) -> str:
+    return f"Hello {name}"
diff --git a/docs_src/query_param_models/tutorial001_an_py39.py b/docs_src/query_param_models/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 71427ac..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from typing import Annotated, Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: Annotated[FilterParams, Query()]):
-    return filter_query
diff --git a/docs_src/query_param_models/tutorial001_py39.py b/docs_src/query_param_models/tutorial001_py39.py
deleted file mode 100644 (file)
index 3ebf9f4..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from typing import Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: FilterParams = Query()):
-    return filter_query
diff --git a/docs_src/query_param_models/tutorial002_an_py39.py b/docs_src/query_param_models/tutorial002_an_py39.py
deleted file mode 100644 (file)
index 9759565..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Annotated, Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    model_config = {"extra": "forbid"}
-
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: Annotated[FilterParams, Query()]):
-    return filter_query
diff --git a/docs_src/query_param_models/tutorial002_py39.py b/docs_src/query_param_models/tutorial002_py39.py
deleted file mode 100644 (file)
index 6ec4184..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Literal
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    model_config = {"extra": "forbid"}
-
-    limit: int = Field(100, gt=0, le=100)
-    offset: int = Field(0, ge=0)
-    order_by: Literal["created_at", "updated_at"] = "created_at"
-    tags: list[str] = []
-
-
-@app.get("/items/")
-async def read_items(filter_query: FilterParams = Query()):
-    return filter_query
diff --git a/docs_src/query_params/tutorial001_py310.py b/docs_src/query_params/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..74e1a17
--- /dev/null
@@ -0,0 +1,10 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+fake_items_db = [{"item_name": "Foo"}, {"item_name": "Bar"}, {"item_name": "Baz"}]
+
+
+@app.get("/items/")
+async def read_item(skip: int = 0, limit: int = 10):
+    return fake_items_db[skip : skip + limit]
diff --git a/docs_src/query_params/tutorial002_py39.py b/docs_src/query_params/tutorial002_py39.py
deleted file mode 100644 (file)
index 8465f45..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/items/{item_id}")
-async def read_item(item_id: str, q: Union[str, None] = None):
-    if q:
-        return {"item_id": item_id, "q": q}
-    return {"item_id": item_id}
diff --git a/docs_src/query_params/tutorial003_py39.py b/docs_src/query_params/tutorial003_py39.py
deleted file mode 100644 (file)
index 3362715..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/items/{item_id}")
-async def read_item(item_id: str, q: Union[str, None] = None, short: bool = False):
-    item = {"item_id": item_id}
-    if q:
-        item.update({"q": q})
-    if not short:
-        item.update(
-            {"description": "This is an amazing item that has a long description"}
-        )
-    return item
diff --git a/docs_src/query_params/tutorial004_py39.py b/docs_src/query_params/tutorial004_py39.py
deleted file mode 100644 (file)
index 049c3ae..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/users/{user_id}/items/{item_id}")
-async def read_user_item(
-    user_id: int, item_id: str, q: Union[str, None] = None, short: bool = False
-):
-    item = {"item_id": item_id, "owner_id": user_id}
-    if q:
-        item.update({"q": q})
-    if not short:
-        item.update(
-            {"description": "This is an amazing item that has a long description"}
-        )
-    return item
diff --git a/docs_src/query_params/tutorial005_py310.py b/docs_src/query_params/tutorial005_py310.py
new file mode 100644 (file)
index 0000000..e16a405
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+async def read_user_item(item_id: str, needy: str):
+    item = {"item_id": item_id, "needy": needy}
+    return item
diff --git a/docs_src/query_params/tutorial006_py39.py b/docs_src/query_params/tutorial006_py39.py
deleted file mode 100644 (file)
index f0dbfe0..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/items/{item_id}")
-async def read_user_item(
-    item_id: str, needy: str, skip: int = 0, limit: Union[int, None] = None
-):
-    item = {"item_id": item_id, "needy": needy, "skip": skip, "limit": limit}
-    return item
diff --git a/docs_src/query_params_str_validations/tutorial001_py39.py b/docs_src/query_params_str_validations/tutorial001_py39.py
deleted file mode 100644 (file)
index e38326b..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(q: Union[str, None] = None):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial002_an_py39.py b/docs_src/query_params_str_validations/tutorial002_an_py39.py
deleted file mode 100644 (file)
index 2d8fc97..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(q: Annotated[Union[str, None], Query(max_length=50)] = None):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial003_an_py39.py b/docs_src/query_params_str_validations/tutorial003_an_py39.py
deleted file mode 100644 (file)
index 3d66977..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Annotated[Union[str, None], Query(min_length=3, max_length=50)] = None,
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial003_py39.py b/docs_src/query_params_str_validations/tutorial003_py39.py
deleted file mode 100644 (file)
index 7d49173..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Union[str, None] = Query(default=None, min_length=3, max_length=50),
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial004_an_py39.py b/docs_src/query_params_str_validations/tutorial004_an_py39.py
deleted file mode 100644 (file)
index de27097..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Annotated[
-        Union[str, None], Query(min_length=3, max_length=50, pattern="^fixedquery$")
-    ] = None,
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial004_py39.py b/docs_src/query_params_str_validations/tutorial004_py39.py
deleted file mode 100644 (file)
index 64a647a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Union[str, None] = Query(
-        default=None, min_length=3, max_length=50, pattern="^fixedquery$"
-    ),
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial004_regex_an_py310.py b/docs_src/query_params_str_validations/tutorial004_regex_an_py310.py
deleted file mode 100644 (file)
index 21e0d3e..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from typing import Annotated
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Annotated[
-        str | None, Query(min_length=3, max_length=50, regex="^fixedquery$")
-    ] = None,
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
similarity index 65%
rename from docs_src/query_params_str_validations/tutorial002_py39.py
rename to docs_src/query_params_str_validations/tutorial005_an_py310.py
index 17e017b7e7142b5b88ea37f1033e84f9ad7076f4..b1f6046b5084a6842acf832043372a563dbea66c 100644 (file)
@@ -1,4 +1,4 @@
-from typing import Union
+from typing import Annotated
 
 from fastapi import FastAPI, Query
 
@@ -6,7 +6,7 @@ app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Union[str, None] = Query(default=None, max_length=50)):
+async def read_items(q: Annotated[str, Query(min_length=3)] = "fixedquery"):
     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
     if q:
         results.update({"q": q})
similarity index 64%
rename from docs_src/query_params_str_validations/tutorial009_py39.py
rename to docs_src/query_params_str_validations/tutorial005_py310.py
index 8a6bfe2d93fb34ee005b18c6c7623c58c8168a02..8ab42869e6140140ec6bc4c71a6c37fe119caabb 100644 (file)
@@ -1,12 +1,10 @@
-from typing import Union
-
 from fastapi import FastAPI, Query
 
 app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Union[str, None] = Query(default=None, alias="item-query")):
+async def read_items(q: str = Query(default="fixedquery", min_length=3)):
     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
     if q:
         results.update({"q": q})
similarity index 69%
rename from docs_src/query_params_str_validations/tutorial006c_py39.py
rename to docs_src/query_params_str_validations/tutorial006_an_py310.py
index 0a0e820da34ca31378963e337169305d30cdfa38..3b4a676d2e388df2f7d8ae5e9db7e5a77abc4927 100644 (file)
@@ -1,4 +1,4 @@
-from typing import Union
+from typing import Annotated
 
 from fastapi import FastAPI, Query
 
@@ -6,7 +6,7 @@ app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Union[str, None] = Query(min_length=3)):
+async def read_items(q: Annotated[str, Query(min_length=3)]):
     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
     if q:
         results.update({"q": q})
similarity index 64%
rename from docs_src/query_params_str_validations/tutorial006c_an_py39.py
rename to docs_src/query_params_str_validations/tutorial006_py310.py
index 76a1cd49ac9622349c3368eb153091c2ffa8daa2..9a90eb64efafa641ff78d95a00ddea8763f91418 100644 (file)
@@ -1,12 +1,10 @@
-from typing import Annotated, Union
-
 from fastapi import FastAPI, Query
 
 app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Annotated[Union[str, None], Query(min_length=3)]):
+async def read_items(q: str = Query(min_length=3)):
     results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
     if q:
         results.update({"q": q})
diff --git a/docs_src/query_params_str_validations/tutorial007_an_py39.py b/docs_src/query_params_str_validations/tutorial007_an_py39.py
deleted file mode 100644 (file)
index 8d7a82c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Annotated[Union[str, None], Query(title="Query string", min_length=3)] = None,
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial007_py39.py b/docs_src/query_params_str_validations/tutorial007_py39.py
deleted file mode 100644 (file)
index 27b649e..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Union[str, None] = Query(default=None, title="Query string", min_length=3),
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial008_an_py39.py b/docs_src/query_params_str_validations/tutorial008_an_py39.py
deleted file mode 100644 (file)
index f3f2f2c..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Annotated[
-        Union[str, None],
-        Query(
-            title="Query string",
-            description="Query string for the items to search in the database that have a good match",
-            min_length=3,
-        ),
-    ] = None,
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial008_py39.py b/docs_src/query_params_str_validations/tutorial008_py39.py
deleted file mode 100644 (file)
index e3e0b50..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Union[str, None] = Query(
-        default=None,
-        title="Query string",
-        description="Query string for the items to search in the database that have a good match",
-        min_length=3,
-    ),
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial009_an_py39.py b/docs_src/query_params_str_validations/tutorial009_an_py39.py
deleted file mode 100644 (file)
index 70a89e6..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(q: Annotated[Union[str, None], Query(alias="item-query")] = None):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial010_an_py39.py b/docs_src/query_params_str_validations/tutorial010_an_py39.py
deleted file mode 100644 (file)
index b126c11..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Annotated[
-        Union[str, None],
-        Query(
-            alias="item-query",
-            title="Query string",
-            description="Query string for the items to search in the database that have a good match",
-            min_length=3,
-            max_length=50,
-            pattern="^fixedquery$",
-            deprecated=True,
-        ),
-    ] = None,
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial010_py39.py b/docs_src/query_params_str_validations/tutorial010_py39.py
deleted file mode 100644 (file)
index ff29176..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    q: Union[str, None] = Query(
-        default=None,
-        alias="item-query",
-        title="Query string",
-        description="Query string for the items to search in the database that have a good match",
-        min_length=3,
-        max_length=50,
-        pattern="^fixedquery$",
-        deprecated=True,
-    ),
-):
-    results = {"items": [{"item_id": "Foo"}, {"item_id": "Bar"}]}
-    if q:
-        results.update({"q": q})
-    return results
similarity index 52%
rename from docs_src/query_params_str_validations/tutorial011_an_py39.py
rename to docs_src/query_params_str_validations/tutorial012_an_py310.py
index 416e3990dc544686a381616398641d16cadb4e85..9b5a9c2fb2394f7c110e8d6dc194ffd63e2b82c9 100644 (file)
@@ -1,4 +1,4 @@
-from typing import Annotated, Union
+from typing import Annotated
 
 from fastapi import FastAPI, Query
 
@@ -6,6 +6,6 @@ app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Annotated[Union[list[str], None], Query()] = None):
+async def read_items(q: Annotated[list[str], Query()] = ["foo", "bar"]):
     query_items = {"q": q}
     return query_items
diff --git a/docs_src/query_params_str_validations/tutorial012_py310.py b/docs_src/query_params_str_validations/tutorial012_py310.py
new file mode 100644 (file)
index 0000000..070d0b0
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: list[str] = Query(default=["foo", "bar"])):
+    query_items = {"q": q}
+    return query_items
similarity index 56%
rename from docs_src/query_params_str_validations/tutorial011_py39.py
rename to docs_src/query_params_str_validations/tutorial013_an_py310.py
index 878f95c7984cf8515321b71e555299db6f072ae6..602734145d4a6f1086a6be5728c21cc63d827630 100644 (file)
@@ -1,4 +1,4 @@
-from typing import Union
+from typing import Annotated
 
 from fastapi import FastAPI, Query
 
@@ -6,6 +6,6 @@ app = FastAPI()
 
 
 @app.get("/items/")
-async def read_items(q: Union[list[str], None] = Query(default=None)):
+async def read_items(q: Annotated[list, Query()] = []):
     query_items = {"q": q}
     return query_items
diff --git a/docs_src/query_params_str_validations/tutorial013_py310.py b/docs_src/query_params_str_validations/tutorial013_py310.py
new file mode 100644 (file)
index 0000000..0b0f448
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI, Query
+
+app = FastAPI()
+
+
+@app.get("/items/")
+async def read_items(q: list = Query(default=[])):
+    query_items = {"q": q}
+    return query_items
diff --git a/docs_src/query_params_str_validations/tutorial014_an_py39.py b/docs_src/query_params_str_validations/tutorial014_an_py39.py
deleted file mode 100644 (file)
index aaf7703..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    hidden_query: Annotated[Union[str, None], Query(include_in_schema=False)] = None,
-):
-    if hidden_query:
-        return {"hidden_query": hidden_query}
-    else:
-        return {"hidden_query": "Not found"}
diff --git a/docs_src/query_params_str_validations/tutorial014_py39.py b/docs_src/query_params_str_validations/tutorial014_py39.py
deleted file mode 100644 (file)
index 779db1c..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(
-    hidden_query: Union[str, None] = Query(default=None, include_in_schema=False),
-):
-    if hidden_query:
-        return {"hidden_query": hidden_query}
-    else:
-        return {"hidden_query": "Not found"}
diff --git a/docs_src/query_params_str_validations/tutorial015_an_py39.py b/docs_src/query_params_str_validations/tutorial015_an_py39.py
deleted file mode 100644 (file)
index 989b6d2..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-import random
-from typing import Annotated, Union
-
-from fastapi import FastAPI
-from pydantic import AfterValidator
-
-app = FastAPI()
-
-data = {
-    "isbn-9781529046137": "The Hitchhiker's Guide to the Galaxy",
-    "imdb-tt0371724": "The Hitchhiker's Guide to the Galaxy",
-    "isbn-9781439512982": "Isaac Asimov: The Complete Stories, Vol. 2",
-}
-
-
-def check_valid_id(id: str):
-    if not id.startswith(("isbn-", "imdb-")):
-        raise ValueError('Invalid ID format, it must start with "isbn-" or "imdb-"')
-    return id
-
-
-@app.get("/items/")
-async def read_items(
-    id: Annotated[Union[str, None], AfterValidator(check_valid_id)] = None,
-):
-    if id:
-        item = data.get(id)
-    else:
-        id, item = random.choice(list(data.items()))
-    return {"id": id, "name": item}
diff --git a/docs_src/request_files/tutorial001_02_an_py39.py b/docs_src/request_files/tutorial001_02_an_py39.py
deleted file mode 100644 (file)
index bb090ff..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import FastAPI, File, UploadFile
-
-app = FastAPI()
-
-
-@app.post("/files/")
-async def create_file(file: Annotated[Union[bytes, None], File()] = None):
-    if not file:
-        return {"message": "No file sent"}
-    else:
-        return {"file_size": len(file)}
-
-
-@app.post("/uploadfile/")
-async def create_upload_file(file: Union[UploadFile, None] = None):
-    if not file:
-        return {"message": "No upload file sent"}
-    else:
-        return {"filename": file.filename}
diff --git a/docs_src/request_files/tutorial001_02_py39.py b/docs_src/request_files/tutorial001_02_py39.py
deleted file mode 100644 (file)
index ac30be2..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, File, UploadFile
-
-app = FastAPI()
-
-
-@app.post("/files/")
-async def create_file(file: Union[bytes, None] = File(default=None)):
-    if not file:
-        return {"message": "No file sent"}
-    else:
-        return {"file_size": len(file)}
-
-
-@app.post("/uploadfile/")
-async def create_upload_file(file: Union[UploadFile, None] = None):
-    if not file:
-        return {"message": "No upload file sent"}
-    else:
-        return {"filename": file.filename}
diff --git a/docs_src/request_files/tutorial001_03_an_py310.py b/docs_src/request_files/tutorial001_03_an_py310.py
new file mode 100644 (file)
index 0000000..93098a6
--- /dev/null
@@ -0,0 +1,17 @@
+from typing import Annotated
+
+from fastapi import FastAPI, File, UploadFile
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(file: Annotated[bytes, File(description="A file read as bytes")]):
+    return {"file_size": len(file)}
+
+
+@app.post("/uploadfile/")
+async def create_upload_file(
+    file: Annotated[UploadFile, File(description="A file read as UploadFile")],
+):
+    return {"filename": file.filename}
diff --git a/docs_src/request_files/tutorial001_03_py310.py b/docs_src/request_files/tutorial001_03_py310.py
new file mode 100644 (file)
index 0000000..d8005cc
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, File, UploadFile
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(file: bytes = File(description="A file read as bytes")):
+    return {"file_size": len(file)}
+
+
+@app.post("/uploadfile/")
+async def create_upload_file(
+    file: UploadFile = File(description="A file read as UploadFile"),
+):
+    return {"filename": file.filename}
diff --git a/docs_src/request_files/tutorial001_an_py310.py b/docs_src/request_files/tutorial001_an_py310.py
new file mode 100644 (file)
index 0000000..26a7672
--- /dev/null
@@ -0,0 +1,15 @@
+from typing import Annotated
+
+from fastapi import FastAPI, File, UploadFile
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(file: Annotated[bytes, File()]):
+    return {"file_size": len(file)}
+
+
+@app.post("/uploadfile/")
+async def create_upload_file(file: UploadFile):
+    return {"filename": file.filename}
diff --git a/docs_src/request_files/tutorial001_py310.py b/docs_src/request_files/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..2e0ea63
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI, File, UploadFile
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(file: bytes = File()):
+    return {"file_size": len(file)}
+
+
+@app.post("/uploadfile/")
+async def create_upload_file(file: UploadFile):
+    return {"filename": file.filename}
diff --git a/docs_src/request_files/tutorial002_an_py310.py b/docs_src/request_files/tutorial002_an_py310.py
new file mode 100644 (file)
index 0000000..db524ce
--- /dev/null
@@ -0,0 +1,33 @@
+from typing import Annotated
+
+from fastapi import FastAPI, File, UploadFile
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_files(files: Annotated[list[bytes], File()]):
+    return {"file_sizes": [len(file) for file in files]}
+
+
+@app.post("/uploadfiles/")
+async def create_upload_files(files: list[UploadFile]):
+    return {"filenames": [file.filename for file in files]}
+
+
+@app.get("/")
+async def main():
+    content = """
+<body>
+<form action="/files/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+</body>
+    """
+    return HTMLResponse(content=content)
diff --git a/docs_src/request_files/tutorial002_py310.py b/docs_src/request_files/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..b64cf55
--- /dev/null
@@ -0,0 +1,31 @@
+from fastapi import FastAPI, File, UploadFile
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_files(files: list[bytes] = File()):
+    return {"file_sizes": [len(file) for file in files]}
+
+
+@app.post("/uploadfiles/")
+async def create_upload_files(files: list[UploadFile]):
+    return {"filenames": [file.filename for file in files]}
+
+
+@app.get("/")
+async def main():
+    content = """
+<body>
+<form action="/files/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+</body>
+    """
+    return HTMLResponse(content=content)
diff --git a/docs_src/request_files/tutorial003_an_py310.py b/docs_src/request_files/tutorial003_an_py310.py
new file mode 100644 (file)
index 0000000..5a8c5da
--- /dev/null
@@ -0,0 +1,39 @@
+from typing import Annotated
+
+from fastapi import FastAPI, File, UploadFile
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_files(
+    files: Annotated[list[bytes], File(description="Multiple files as bytes")],
+):
+    return {"file_sizes": [len(file) for file in files]}
+
+
+@app.post("/uploadfiles/")
+async def create_upload_files(
+    files: Annotated[
+        list[UploadFile], File(description="Multiple files as UploadFile")
+    ],
+):
+    return {"filenames": [file.filename for file in files]}
+
+
+@app.get("/")
+async def main():
+    content = """
+<body>
+<form action="/files/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+</body>
+    """
+    return HTMLResponse(content=content)
diff --git a/docs_src/request_files/tutorial003_py310.py b/docs_src/request_files/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..96f5e87
--- /dev/null
@@ -0,0 +1,35 @@
+from fastapi import FastAPI, File, UploadFile
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_files(
+    files: list[bytes] = File(description="Multiple files as bytes"),
+):
+    return {"file_sizes": [len(file) for file in files]}
+
+
+@app.post("/uploadfiles/")
+async def create_upload_files(
+    files: list[UploadFile] = File(description="Multiple files as UploadFile"),
+):
+    return {"filenames": [file.filename for file in files]}
+
+
+@app.get("/")
+async def main():
+    content = """
+<body>
+<form action="/files/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+<form action="/uploadfiles/" enctype="multipart/form-data" method="post">
+<input name="files" type="file" multiple>
+<input type="submit">
+</form>
+</body>
+    """
+    return HTMLResponse(content=content)
diff --git a/docs_src/request_form_models/tutorial001_an_py310.py b/docs_src/request_form_models/tutorial001_an_py310.py
new file mode 100644 (file)
index 0000000..7cc81aa
--- /dev/null
@@ -0,0 +1,16 @@
+from typing import Annotated
+
+from fastapi import FastAPI, Form
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class FormData(BaseModel):
+    username: str
+    password: str
+
+
+@app.post("/login/")
+async def login(data: Annotated[FormData, Form()]):
+    return data
diff --git a/docs_src/request_form_models/tutorial001_py310.py b/docs_src/request_form_models/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..98feff0
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI, Form
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class FormData(BaseModel):
+    username: str
+    password: str
+
+
+@app.post("/login/")
+async def login(data: FormData = Form()):
+    return data
diff --git a/docs_src/request_form_models/tutorial002_an_py310.py b/docs_src/request_form_models/tutorial002_an_py310.py
new file mode 100644 (file)
index 0000000..3004e08
--- /dev/null
@@ -0,0 +1,17 @@
+from typing import Annotated
+
+from fastapi import FastAPI, Form
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class FormData(BaseModel):
+    username: str
+    password: str
+    model_config = {"extra": "forbid"}
+
+
+@app.post("/login/")
+async def login(data: Annotated[FormData, Form()]):
+    return data
diff --git a/docs_src/request_form_models/tutorial002_py310.py b/docs_src/request_form_models/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..59b329e
--- /dev/null
@@ -0,0 +1,15 @@
+from fastapi import FastAPI, Form
+from pydantic import BaseModel
+
+app = FastAPI()
+
+
+class FormData(BaseModel):
+    username: str
+    password: str
+    model_config = {"extra": "forbid"}
+
+
+@app.post("/login/")
+async def login(data: FormData = Form()):
+    return data
diff --git a/docs_src/request_forms/tutorial001_an_py310.py b/docs_src/request_forms/tutorial001_an_py310.py
new file mode 100644 (file)
index 0000000..8e9d2ea
--- /dev/null
@@ -0,0 +1,10 @@
+from typing import Annotated
+
+from fastapi import FastAPI, Form
+
+app = FastAPI()
+
+
+@app.post("/login/")
+async def login(username: Annotated[str, Form()], password: Annotated[str, Form()]):
+    return {"username": username}
diff --git a/docs_src/request_forms/tutorial001_py310.py b/docs_src/request_forms/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..a537700
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI, Form
+
+app = FastAPI()
+
+
+@app.post("/login/")
+async def login(username: str = Form(), password: str = Form()):
+    return {"username": username}
diff --git a/docs_src/request_forms_and_files/tutorial001_an_py310.py b/docs_src/request_forms_and_files/tutorial001_an_py310.py
new file mode 100644 (file)
index 0000000..12cc43e
--- /dev/null
@@ -0,0 +1,18 @@
+from typing import Annotated
+
+from fastapi import FastAPI, File, Form, UploadFile
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(
+    file: Annotated[bytes, File()],
+    fileb: Annotated[UploadFile, File()],
+    token: Annotated[str, Form()],
+):
+    return {
+        "file_size": len(file),
+        "token": token,
+        "fileb_content_type": fileb.content_type,
+    }
diff --git a/docs_src/request_forms_and_files/tutorial001_py310.py b/docs_src/request_forms_and_files/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..7b5224c
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI, File, Form, UploadFile
+
+app = FastAPI()
+
+
+@app.post("/files/")
+async def create_file(
+    file: bytes = File(), fileb: UploadFile = File(), token: str = Form()
+):
+    return {
+        "file_size": len(file),
+        "token": token,
+        "fileb_content_type": fileb.content_type,
+    }
diff --git a/docs_src/response_change_status_code/tutorial001_py310.py b/docs_src/response_change_status_code/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..197decb
--- /dev/null
@@ -0,0 +1,13 @@
+from fastapi import FastAPI, Response, status
+
+app = FastAPI()
+
+tasks = {"foo": "Listen to the Bar Fighters"}
+
+
+@app.put("/get-or-create-task/{task_id}", status_code=200)
+def get_or_create_task(task_id: str, response: Response):
+    if task_id not in tasks:
+        tasks[task_id] = "This didn't exist before"
+        response.status_code = status.HTTP_201_CREATED
+    return tasks[task_id]
diff --git a/docs_src/response_cookies/tutorial001_py310.py b/docs_src/response_cookies/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..33f8e8f
--- /dev/null
@@ -0,0 +1,12 @@
+from fastapi import FastAPI
+from fastapi.responses import JSONResponse
+
+app = FastAPI()
+
+
+@app.post("/cookie/")
+def create_cookie():
+    content = {"message": "Come to the dark side, we have cookies"}
+    response = JSONResponse(content=content)
+    response.set_cookie(key="fakesession", value="fake-cookie-session-value")
+    return response
diff --git a/docs_src/response_cookies/tutorial002_py310.py b/docs_src/response_cookies/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..76c06fd
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI, Response
+
+app = FastAPI()
+
+
+@app.post("/cookie-and-object/")
+def create_cookie(response: Response):
+    response.set_cookie(key="fakesession", value="fake-cookie-session-value")
+    return {"message": "Come to the dark side, we have cookies"}
diff --git a/docs_src/response_directly/tutorial001_py39.py b/docs_src/response_directly/tutorial001_py39.py
deleted file mode 100644 (file)
index 5ab655a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from datetime import datetime
-from typing import Union
-
-from fastapi import FastAPI
-from fastapi.encoders import jsonable_encoder
-from fastapi.responses import JSONResponse
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    title: str
-    timestamp: datetime
-    description: Union[str, None] = None
-
-
-app = FastAPI()
-
-
-@app.put("/items/{id}")
-def update_item(id: str, item: Item):
-    json_compatible_item_data = jsonable_encoder(item)
-    return JSONResponse(content=json_compatible_item_data)
diff --git a/docs_src/response_directly/tutorial002_py310.py b/docs_src/response_directly/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..6643da6
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI, Response
+
+app = FastAPI()
+
+
+@app.get("/legacy/")
+def get_legacy_data():
+    data = """<?xml version="1.0"?>
+    <shampoo>
+    <Header>
+        Apply shampoo here.
+    </Header>
+    <Body>
+        You'll have to use soap here.
+    </Body>
+    </shampoo>
+    """
+    return Response(content=data, media_type="application/xml")
diff --git a/docs_src/response_headers/tutorial001_py310.py b/docs_src/response_headers/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..2da02a4
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI
+from fastapi.responses import JSONResponse
+
+app = FastAPI()
+
+
+@app.get("/headers/")
+def get_headers():
+    content = {"message": "Hello World"}
+    headers = {"X-Cat-Dog": "alone in the world", "Content-Language": "en-US"}
+    return JSONResponse(content=content, headers=headers)
diff --git a/docs_src/response_headers/tutorial002_py310.py b/docs_src/response_headers/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..d2c4983
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI, Response
+
+app = FastAPI()
+
+
+@app.get("/headers-and-object/")
+def get_headers(response: Response):
+    response.headers["X-Cat-Dog"] = "alone in the world"
+    return {"message": "Hello World"}
diff --git a/docs_src/response_model/tutorial001_01_py39.py b/docs_src/response_model/tutorial001_01_py39.py
deleted file mode 100644 (file)
index 16c78aa..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: list[str] = []
-
-
-@app.post("/items/")
-async def create_item(item: Item) -> Item:
-    return item
-
-
-@app.get("/items/")
-async def read_items() -> list[Item]:
-    return [
-        Item(name="Portal Gun", price=42.0),
-        Item(name="Plumbus", price=32.0),
-    ]
diff --git a/docs_src/response_model/tutorial001_py39.py b/docs_src/response_model/tutorial001_py39.py
deleted file mode 100644 (file)
index 261e252..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Any, Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-    tags: list[str] = []
-
-
-@app.post("/items/", response_model=Item)
-async def create_item(item: Item) -> Any:
-    return item
-
-
-@app.get("/items/", response_model=list[Item])
-async def read_items() -> Any:
-    return [
-        {"name": "Portal Gun", "price": 42.0},
-        {"name": "Plumbus", "price": 32.0},
-    ]
diff --git a/docs_src/response_model/tutorial002_py39.py b/docs_src/response_model/tutorial002_py39.py
deleted file mode 100644 (file)
index a58668f..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, EmailStr
-
-app = FastAPI()
-
-
-class UserIn(BaseModel):
-    username: str
-    password: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-# Don't do this in production!
-@app.post("/user/")
-async def create_user(user: UserIn) -> UserIn:
-    return user
diff --git a/docs_src/response_model/tutorial003_01_py39.py b/docs_src/response_model/tutorial003_01_py39.py
deleted file mode 100644 (file)
index 52694b5..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, EmailStr
-
-app = FastAPI()
-
-
-class BaseUser(BaseModel):
-    username: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-class UserIn(BaseUser):
-    password: str
-
-
-@app.post("/user/")
-async def create_user(user: UserIn) -> BaseUser:
-    return user
diff --git a/docs_src/response_model/tutorial003_02_py310.py b/docs_src/response_model/tutorial003_02_py310.py
new file mode 100644 (file)
index 0000000..df6a096
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import FastAPI, Response
+from fastapi.responses import JSONResponse, RedirectResponse
+
+app = FastAPI()
+
+
+@app.get("/portal")
+async def get_portal(teleport: bool = False) -> Response:
+    if teleport:
+        return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
+    return JSONResponse(content={"message": "Here's your interdimensional portal."})
diff --git a/docs_src/response_model/tutorial003_03_py310.py b/docs_src/response_model/tutorial003_03_py310.py
new file mode 100644 (file)
index 0000000..0d4bd8d
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI
+from fastapi.responses import RedirectResponse
+
+app = FastAPI()
+
+
+@app.get("/teleport")
+async def get_teleport() -> RedirectResponse:
+    return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
diff --git a/docs_src/response_model/tutorial003_04_py39.py b/docs_src/response_model/tutorial003_04_py39.py
deleted file mode 100644 (file)
index b13a926..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Response
-from fastapi.responses import RedirectResponse
-
-app = FastAPI()
-
-
-@app.get("/portal")
-async def get_portal(teleport: bool = False) -> Union[Response, dict]:
-    if teleport:
-        return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
-    return {"message": "Here's your interdimensional portal."}
diff --git a/docs_src/response_model/tutorial003_05_py39.py b/docs_src/response_model/tutorial003_05_py39.py
deleted file mode 100644 (file)
index 0962061..0000000
+++ /dev/null
@@ -1,13 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Response
-from fastapi.responses import RedirectResponse
-
-app = FastAPI()
-
-
-@app.get("/portal", response_model=None)
-async def get_portal(teleport: bool = False) -> Union[Response, dict]:
-    if teleport:
-        return RedirectResponse(url="https://www.youtube.com/watch?v=dQw4w9WgXcQ")
-    return {"message": "Here's your interdimensional portal."}
diff --git a/docs_src/response_model/tutorial003_py39.py b/docs_src/response_model/tutorial003_py39.py
deleted file mode 100644 (file)
index c42dbc7..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from typing import Any, Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, EmailStr
-
-app = FastAPI()
-
-
-class UserIn(BaseModel):
-    username: str
-    password: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-class UserOut(BaseModel):
-    username: str
-    email: EmailStr
-    full_name: Union[str, None] = None
-
-
-@app.post("/user/", response_model=UserOut)
-async def create_user(user: UserIn) -> Any:
-    return user
diff --git a/docs_src/response_model/tutorial004_py39.py b/docs_src/response_model/tutorial004_py39.py
deleted file mode 100644 (file)
index 9463b45..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: float = 10.5
-    tags: list[str] = []
-
-
-items = {
-    "foo": {"name": "Foo", "price": 50.2},
-    "bar": {"name": "Bar", "description": "The bartenders", "price": 62, "tax": 20.2},
-    "baz": {"name": "Baz", "description": None, "price": 50.2, "tax": 10.5, "tags": []},
-}
-
-
-@app.get("/items/{item_id}", response_model=Item, response_model_exclude_unset=True)
-async def read_item(item_id: str):
-    return items[item_id]
diff --git a/docs_src/response_model/tutorial005_py39.py b/docs_src/response_model/tutorial005_py39.py
deleted file mode 100644 (file)
index 30eb9f8..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: float = 10.5
-
-
-items = {
-    "foo": {"name": "Foo", "price": 50.2},
-    "bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2},
-    "baz": {
-        "name": "Baz",
-        "description": "There goes my baz",
-        "price": 50.2,
-        "tax": 10.5,
-    },
-}
-
-
-@app.get(
-    "/items/{item_id}/name",
-    response_model=Item,
-    response_model_include={"name", "description"},
-)
-async def read_item_name(item_id: str):
-    return items[item_id]
-
-
-@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude={"tax"})
-async def read_item_public_data(item_id: str):
-    return items[item_id]
diff --git a/docs_src/response_model/tutorial006_py39.py b/docs_src/response_model/tutorial006_py39.py
deleted file mode 100644 (file)
index 3ffdb51..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: float = 10.5
-
-
-items = {
-    "foo": {"name": "Foo", "price": 50.2},
-    "bar": {"name": "Bar", "description": "The Bar fighters", "price": 62, "tax": 20.2},
-    "baz": {
-        "name": "Baz",
-        "description": "There goes my baz",
-        "price": 50.2,
-        "tax": 10.5,
-    },
-}
-
-
-@app.get(
-    "/items/{item_id}/name",
-    response_model=Item,
-    response_model_include=["name", "description"],
-)
-async def read_item_name(item_id: str):
-    return items[item_id]
-
-
-@app.get("/items/{item_id}/public", response_model=Item, response_model_exclude=["tax"])
-async def read_item_public_data(item_id: str):
-    return items[item_id]
diff --git a/docs_src/response_status_code/tutorial001_py310.py b/docs_src/response_status_code/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..14b6d6e
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.post("/items/", status_code=201)
+async def create_item(name: str):
+    return {"name": name}
diff --git a/docs_src/response_status_code/tutorial002_py310.py b/docs_src/response_status_code/tutorial002_py310.py
new file mode 100644 (file)
index 0000000..4fcc982
--- /dev/null
@@ -0,0 +1,8 @@
+from fastapi import FastAPI, status
+
+app = FastAPI()
+
+
+@app.post("/items/", status_code=status.HTTP_201_CREATED)
+async def create_item(name: str):
+    return {"name": name}
diff --git a/docs_src/schema_extra_example/tutorial001_pv1_py310.py b/docs_src/schema_extra_example/tutorial001_pv1_py310.py
deleted file mode 100644 (file)
index b13b8a8..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from fastapi import FastAPI
-from pydantic.v1 import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: str | None = None
-    price: float
-    tax: float | None = None
-
-    class Config:
-        schema_extra = {
-            "examples": [
-                {
-                    "name": "Foo",
-                    "description": "A very nice Item",
-                    "price": 35.4,
-                    "tax": 3.2,
-                }
-            ]
-        }
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial001_pv1_py39.py b/docs_src/schema_extra_example/tutorial001_pv1_py39.py
deleted file mode 100644 (file)
index 3240b35..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic.v1 import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-    class Config:
-        schema_extra = {
-            "examples": [
-                {
-                    "name": "Foo",
-                    "description": "A very nice Item",
-                    "price": 35.4,
-                    "tax": 3.2,
-                }
-            ]
-        }
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial001_py39.py b/docs_src/schema_extra_example/tutorial001_py39.py
deleted file mode 100644 (file)
index 32a66db..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-    model_config = {
-        "json_schema_extra": {
-            "examples": [
-                {
-                    "name": "Foo",
-                    "description": "A very nice Item",
-                    "price": 35.4,
-                    "tax": 3.2,
-                }
-            ]
-        }
-    }
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial002_py39.py b/docs_src/schema_extra_example/tutorial002_py39.py
deleted file mode 100644 (file)
index 70f0656..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel, Field
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str = Field(examples=["Foo"])
-    description: Union[str, None] = Field(default=None, examples=["A very nice Item"])
-    price: float = Field(examples=[35.4])
-    tax: Union[float, None] = Field(default=None, examples=[3.2])
-
-
-@app.put("/items/{item_id}")
-async def update_item(item_id: int, item: Item):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial003_an_py39.py b/docs_src/schema_extra_example/tutorial003_an_py39.py
deleted file mode 100644 (file)
index 4728085..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    item_id: int,
-    item: Annotated[
-        Item,
-        Body(
-            examples=[
-                {
-                    "name": "Foo",
-                    "description": "A very nice Item",
-                    "price": 35.4,
-                    "tax": 3.2,
-                }
-            ],
-        ),
-    ],
-):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial003_py39.py b/docs_src/schema_extra_example/tutorial003_py39.py
deleted file mode 100644 (file)
index 385f3de..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    item_id: int,
-    item: Item = Body(
-        examples=[
-            {
-                "name": "Foo",
-                "description": "A very nice Item",
-                "price": 35.4,
-                "tax": 3.2,
-            }
-        ],
-    ),
-):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial004_an_py39.py b/docs_src/schema_extra_example/tutorial004_an_py39.py
deleted file mode 100644 (file)
index dc5a8fe..0000000
+++ /dev/null
@@ -1,43 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    *,
-    item_id: int,
-    item: Annotated[
-        Item,
-        Body(
-            examples=[
-                {
-                    "name": "Foo",
-                    "description": "A very nice Item",
-                    "price": 35.4,
-                    "tax": 3.2,
-                },
-                {
-                    "name": "Bar",
-                    "price": "35.4",
-                },
-                {
-                    "name": "Baz",
-                    "price": "thirty five point four",
-                },
-            ],
-        ),
-    ],
-):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial004_py39.py b/docs_src/schema_extra_example/tutorial004_py39.py
deleted file mode 100644 (file)
index 75514a3..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    *,
-    item_id: int,
-    item: Item = Body(
-        examples=[
-            {
-                "name": "Foo",
-                "description": "A very nice Item",
-                "price": 35.4,
-                "tax": 3.2,
-            },
-            {
-                "name": "Bar",
-                "price": "35.4",
-            },
-            {
-                "name": "Baz",
-                "price": "thirty five point four",
-            },
-        ],
-    ),
-):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial005_an_py39.py b/docs_src/schema_extra_example/tutorial005_an_py39.py
deleted file mode 100644 (file)
index edeb1af..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    *,
-    item_id: int,
-    item: Annotated[
-        Item,
-        Body(
-            openapi_examples={
-                "normal": {
-                    "summary": "A normal example",
-                    "description": "A **normal** item works correctly.",
-                    "value": {
-                        "name": "Foo",
-                        "description": "A very nice Item",
-                        "price": 35.4,
-                        "tax": 3.2,
-                    },
-                },
-                "converted": {
-                    "summary": "An example with converted data",
-                    "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
-                    "value": {
-                        "name": "Bar",
-                        "price": "35.4",
-                    },
-                },
-                "invalid": {
-                    "summary": "Invalid data is rejected with an error",
-                    "value": {
-                        "name": "Baz",
-                        "price": "thirty five point four",
-                    },
-                },
-            },
-        ),
-    ],
-):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/schema_extra_example/tutorial005_py39.py b/docs_src/schema_extra_example/tutorial005_py39.py
deleted file mode 100644 (file)
index b8217c2..0000000
+++ /dev/null
@@ -1,51 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = None
-    price: float
-    tax: Union[float, None] = None
-
-
-@app.put("/items/{item_id}")
-async def update_item(
-    *,
-    item_id: int,
-    item: Item = Body(
-        openapi_examples={
-            "normal": {
-                "summary": "A normal example",
-                "description": "A **normal** item works correctly.",
-                "value": {
-                    "name": "Foo",
-                    "description": "A very nice Item",
-                    "price": 35.4,
-                    "tax": 3.2,
-                },
-            },
-            "converted": {
-                "summary": "An example with converted data",
-                "description": "FastAPI can convert price `strings` to actual `numbers` automatically",
-                "value": {
-                    "name": "Bar",
-                    "price": "35.4",
-                },
-            },
-            "invalid": {
-                "summary": "Invalid data is rejected with an error",
-                "value": {
-                    "name": "Baz",
-                    "price": "thirty five point four",
-                },
-            },
-        },
-    ),
-):
-    results = {"item_id": item_id, "item": item}
-    return results
diff --git a/docs_src/security/tutorial001_an_py310.py b/docs_src/security/tutorial001_an_py310.py
new file mode 100644 (file)
index 0000000..de11040
--- /dev/null
@@ -0,0 +1,13 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI
+from fastapi.security import OAuth2PasswordBearer
+
+app = FastAPI()
+
+oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
+
+
+@app.get("/items/")
+async def read_items(token: Annotated[str, Depends(oauth2_scheme)]):
+    return {"token": token}
diff --git a/docs_src/security/tutorial001_py310.py b/docs_src/security/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..224e596
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import Depends, FastAPI
+from fastapi.security import OAuth2PasswordBearer
+
+app = FastAPI()
+
+oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
+
+
+@app.get("/items/")
+async def read_items(token: str = Depends(oauth2_scheme)):
+    return {"token": token}
diff --git a/docs_src/security/tutorial002_an_py39.py b/docs_src/security/tutorial002_an_py39.py
deleted file mode 100644 (file)
index 7ff1c47..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI
-from fastapi.security import OAuth2PasswordBearer
-from pydantic import BaseModel
-
-app = FastAPI()
-
-oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-def fake_decode_token(token):
-    return User(
-        username=token + "fakedecoded", email="john@example.com", full_name="John Doe"
-    )
-
-
-async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
-    user = fake_decode_token(token)
-    return user
-
-
-@app.get("/users/me")
-async def read_users_me(current_user: Annotated[User, Depends(get_current_user)]):
-    return current_user
diff --git a/docs_src/security/tutorial002_py39.py b/docs_src/security/tutorial002_py39.py
deleted file mode 100644 (file)
index bfd0352..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from fastapi.security import OAuth2PasswordBearer
-from pydantic import BaseModel
-
-app = FastAPI()
-
-oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-def fake_decode_token(token):
-    return User(
-        username=token + "fakedecoded", email="john@example.com", full_name="John Doe"
-    )
-
-
-async def get_current_user(token: str = Depends(oauth2_scheme)):
-    user = fake_decode_token(token)
-    return user
-
-
-@app.get("/users/me")
-async def read_users_me(current_user: User = Depends(get_current_user)):
-    return current_user
diff --git a/docs_src/security/tutorial003_an_py39.py b/docs_src/security/tutorial003_an_py39.py
deleted file mode 100644 (file)
index b396210..0000000
+++ /dev/null
@@ -1,94 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI, HTTPException, status
-from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
-from pydantic import BaseModel
-
-fake_users_db = {
-    "johndoe": {
-        "username": "johndoe",
-        "full_name": "John Doe",
-        "email": "johndoe@example.com",
-        "hashed_password": "fakehashedsecret",
-        "disabled": False,
-    },
-    "alice": {
-        "username": "alice",
-        "full_name": "Alice Wonderson",
-        "email": "alice@example.com",
-        "hashed_password": "fakehashedsecret2",
-        "disabled": True,
-    },
-}
-
-app = FastAPI()
-
-
-def fake_hash_password(password: str):
-    return "fakehashed" + password
-
-
-oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-class UserInDB(User):
-    hashed_password: str
-
-
-def get_user(db, username: str):
-    if username in db:
-        user_dict = db[username]
-        return UserInDB(**user_dict)
-
-
-def fake_decode_token(token):
-    # This doesn't provide any security at all
-    # Check the next version
-    user = get_user(fake_users_db, token)
-    return user
-
-
-async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
-    user = fake_decode_token(token)
-    if not user:
-        raise HTTPException(
-            status_code=status.HTTP_401_UNAUTHORIZED,
-            detail="Not authenticated",
-            headers={"WWW-Authenticate": "Bearer"},
-        )
-    return user
-
-
-async def get_current_active_user(
-    current_user: Annotated[User, Depends(get_current_user)],
-):
-    if current_user.disabled:
-        raise HTTPException(status_code=400, detail="Inactive user")
-    return current_user
-
-
-@app.post("/token")
-async def login(form_data: Annotated[OAuth2PasswordRequestForm, Depends()]):
-    user_dict = fake_users_db.get(form_data.username)
-    if not user_dict:
-        raise HTTPException(status_code=400, detail="Incorrect username or password")
-    user = UserInDB(**user_dict)
-    hashed_password = fake_hash_password(form_data.password)
-    if not hashed_password == user.hashed_password:
-        raise HTTPException(status_code=400, detail="Incorrect username or password")
-
-    return {"access_token": user.username, "token_type": "bearer"}
-
-
-@app.get("/users/me")
-async def read_users_me(
-    current_user: Annotated[User, Depends(get_current_active_user)],
-):
-    return current_user
diff --git a/docs_src/security/tutorial003_py39.py b/docs_src/security/tutorial003_py39.py
deleted file mode 100644 (file)
index ce7a71b..0000000
+++ /dev/null
@@ -1,90 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI, HTTPException, status
-from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
-from pydantic import BaseModel
-
-fake_users_db = {
-    "johndoe": {
-        "username": "johndoe",
-        "full_name": "John Doe",
-        "email": "johndoe@example.com",
-        "hashed_password": "fakehashedsecret",
-        "disabled": False,
-    },
-    "alice": {
-        "username": "alice",
-        "full_name": "Alice Wonderson",
-        "email": "alice@example.com",
-        "hashed_password": "fakehashedsecret2",
-        "disabled": True,
-    },
-}
-
-app = FastAPI()
-
-
-def fake_hash_password(password: str):
-    return "fakehashed" + password
-
-
-oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-class UserInDB(User):
-    hashed_password: str
-
-
-def get_user(db, username: str):
-    if username in db:
-        user_dict = db[username]
-        return UserInDB(**user_dict)
-
-
-def fake_decode_token(token):
-    # This doesn't provide any security at all
-    # Check the next version
-    user = get_user(fake_users_db, token)
-    return user
-
-
-async def get_current_user(token: str = Depends(oauth2_scheme)):
-    user = fake_decode_token(token)
-    if not user:
-        raise HTTPException(
-            status_code=status.HTTP_401_UNAUTHORIZED,
-            detail="Not authenticated",
-            headers={"WWW-Authenticate": "Bearer"},
-        )
-    return user
-
-
-async def get_current_active_user(current_user: User = Depends(get_current_user)):
-    if current_user.disabled:
-        raise HTTPException(status_code=400, detail="Inactive user")
-    return current_user
-
-
-@app.post("/token")
-async def login(form_data: OAuth2PasswordRequestForm = Depends()):
-    user_dict = fake_users_db.get(form_data.username)
-    if not user_dict:
-        raise HTTPException(status_code=400, detail="Incorrect username or password")
-    user = UserInDB(**user_dict)
-    hashed_password = fake_hash_password(form_data.password)
-    if not hashed_password == user.hashed_password:
-        raise HTTPException(status_code=400, detail="Incorrect username or password")
-
-    return {"access_token": user.username, "token_type": "bearer"}
-
-
-@app.get("/users/me")
-async def read_users_me(current_user: User = Depends(get_current_active_user)):
-    return current_user
diff --git a/docs_src/security/tutorial004_an_py39.py b/docs_src/security/tutorial004_an_py39.py
deleted file mode 100644 (file)
index 73b3d45..0000000
+++ /dev/null
@@ -1,147 +0,0 @@
-from datetime import datetime, timedelta, timezone
-from typing import Annotated, Union
-
-import jwt
-from fastapi import Depends, FastAPI, HTTPException, status
-from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
-from jwt.exceptions import InvalidTokenError
-from pwdlib import PasswordHash
-from pydantic import BaseModel
-
-# to get a string like this run:
-# openssl rand -hex 32
-SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
-ALGORITHM = "HS256"
-ACCESS_TOKEN_EXPIRE_MINUTES = 30
-
-
-fake_users_db = {
-    "johndoe": {
-        "username": "johndoe",
-        "full_name": "John Doe",
-        "email": "johndoe@example.com",
-        "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc",
-        "disabled": False,
-    }
-}
-
-
-class Token(BaseModel):
-    access_token: str
-    token_type: str
-
-
-class TokenData(BaseModel):
-    username: Union[str, None] = None
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-class UserInDB(User):
-    hashed_password: str
-
-
-password_hash = PasswordHash.recommended()
-
-oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
-
-app = FastAPI()
-
-
-def verify_password(plain_password, hashed_password):
-    return password_hash.verify(plain_password, hashed_password)
-
-
-def get_password_hash(password):
-    return password_hash.hash(password)
-
-
-def get_user(db, username: str):
-    if username in db:
-        user_dict = db[username]
-        return UserInDB(**user_dict)
-
-
-def authenticate_user(fake_db, username: str, password: str):
-    user = get_user(fake_db, username)
-    if not user:
-        return False
-    if not verify_password(password, user.hashed_password):
-        return False
-    return user
-
-
-def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None):
-    to_encode = data.copy()
-    if expires_delta:
-        expire = datetime.now(timezone.utc) + expires_delta
-    else:
-        expire = datetime.now(timezone.utc) + timedelta(minutes=15)
-    to_encode.update({"exp": expire})
-    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
-    return encoded_jwt
-
-
-async def get_current_user(token: Annotated[str, Depends(oauth2_scheme)]):
-    credentials_exception = HTTPException(
-        status_code=status.HTTP_401_UNAUTHORIZED,
-        detail="Could not validate credentials",
-        headers={"WWW-Authenticate": "Bearer"},
-    )
-    try:
-        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
-        username = payload.get("sub")
-        if username is None:
-            raise credentials_exception
-        token_data = TokenData(username=username)
-    except InvalidTokenError:
-        raise credentials_exception
-    user = get_user(fake_users_db, username=token_data.username)
-    if user is None:
-        raise credentials_exception
-    return user
-
-
-async def get_current_active_user(
-    current_user: Annotated[User, Depends(get_current_user)],
-):
-    if current_user.disabled:
-        raise HTTPException(status_code=400, detail="Inactive user")
-    return current_user
-
-
-@app.post("/token")
-async def login_for_access_token(
-    form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
-) -> Token:
-    user = authenticate_user(fake_users_db, form_data.username, form_data.password)
-    if not user:
-        raise HTTPException(
-            status_code=status.HTTP_401_UNAUTHORIZED,
-            detail="Incorrect username or password",
-            headers={"WWW-Authenticate": "Bearer"},
-        )
-    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
-    access_token = create_access_token(
-        data={"sub": user.username}, expires_delta=access_token_expires
-    )
-    return Token(access_token=access_token, token_type="bearer")
-
-
-@app.get("/users/me/")
-async def read_users_me(
-    current_user: Annotated[User, Depends(get_current_active_user)],
-) -> User:
-    return current_user
-
-
-@app.get("/users/me/items/")
-async def read_own_items(
-    current_user: Annotated[User, Depends(get_current_active_user)],
-):
-    return [{"item_id": "Foo", "owner": current_user.username}]
diff --git a/docs_src/security/tutorial004_py39.py b/docs_src/security/tutorial004_py39.py
deleted file mode 100644 (file)
index e67403d..0000000
+++ /dev/null
@@ -1,141 +0,0 @@
-from datetime import datetime, timedelta, timezone
-from typing import Union
-
-import jwt
-from fastapi import Depends, FastAPI, HTTPException, status
-from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
-from jwt.exceptions import InvalidTokenError
-from pwdlib import PasswordHash
-from pydantic import BaseModel
-
-# to get a string like this run:
-# openssl rand -hex 32
-SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
-ALGORITHM = "HS256"
-ACCESS_TOKEN_EXPIRE_MINUTES = 30
-
-
-fake_users_db = {
-    "johndoe": {
-        "username": "johndoe",
-        "full_name": "John Doe",
-        "email": "johndoe@example.com",
-        "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc",
-        "disabled": False,
-    }
-}
-
-
-class Token(BaseModel):
-    access_token: str
-    token_type: str
-
-
-class TokenData(BaseModel):
-    username: Union[str, None] = None
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-class UserInDB(User):
-    hashed_password: str
-
-
-password_hash = PasswordHash.recommended()
-
-oauth2_scheme = OAuth2PasswordBearer(tokenUrl="token")
-
-app = FastAPI()
-
-
-def verify_password(plain_password, hashed_password):
-    return password_hash.verify(plain_password, hashed_password)
-
-
-def get_password_hash(password):
-    return password_hash.hash(password)
-
-
-def get_user(db, username: str):
-    if username in db:
-        user_dict = db[username]
-        return UserInDB(**user_dict)
-
-
-def authenticate_user(fake_db, username: str, password: str):
-    user = get_user(fake_db, username)
-    if not user:
-        return False
-    if not verify_password(password, user.hashed_password):
-        return False
-    return user
-
-
-def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None):
-    to_encode = data.copy()
-    if expires_delta:
-        expire = datetime.now(timezone.utc) + expires_delta
-    else:
-        expire = datetime.now(timezone.utc) + timedelta(minutes=15)
-    to_encode.update({"exp": expire})
-    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
-    return encoded_jwt
-
-
-async def get_current_user(token: str = Depends(oauth2_scheme)):
-    credentials_exception = HTTPException(
-        status_code=status.HTTP_401_UNAUTHORIZED,
-        detail="Could not validate credentials",
-        headers={"WWW-Authenticate": "Bearer"},
-    )
-    try:
-        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
-        username = payload.get("sub")
-        if username is None:
-            raise credentials_exception
-        token_data = TokenData(username=username)
-    except InvalidTokenError:
-        raise credentials_exception
-    user = get_user(fake_users_db, username=token_data.username)
-    if user is None:
-        raise credentials_exception
-    return user
-
-
-async def get_current_active_user(current_user: User = Depends(get_current_user)):
-    if current_user.disabled:
-        raise HTTPException(status_code=400, detail="Inactive user")
-    return current_user
-
-
-@app.post("/token")
-async def login_for_access_token(
-    form_data: OAuth2PasswordRequestForm = Depends(),
-) -> Token:
-    user = authenticate_user(fake_users_db, form_data.username, form_data.password)
-    if not user:
-        raise HTTPException(
-            status_code=status.HTTP_401_UNAUTHORIZED,
-            detail="Incorrect username or password",
-            headers={"WWW-Authenticate": "Bearer"},
-        )
-    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
-    access_token = create_access_token(
-        data={"sub": user.username}, expires_delta=access_token_expires
-    )
-    return Token(access_token=access_token, token_type="bearer")
-
-
-@app.get("/users/me/")
-async def read_users_me(current_user: User = Depends(get_current_active_user)) -> User:
-    return current_user
-
-
-@app.get("/users/me/items/")
-async def read_own_items(current_user: User = Depends(get_current_active_user)):
-    return [{"item_id": "Foo", "owner": current_user.username}]
diff --git a/docs_src/security/tutorial005_an_py39.py b/docs_src/security/tutorial005_an_py39.py
deleted file mode 100644 (file)
index 1aeba68..0000000
+++ /dev/null
@@ -1,179 +0,0 @@
-from datetime import datetime, timedelta, timezone
-from typing import Annotated, Union
-
-import jwt
-from fastapi import Depends, FastAPI, HTTPException, Security, status
-from fastapi.security import (
-    OAuth2PasswordBearer,
-    OAuth2PasswordRequestForm,
-    SecurityScopes,
-)
-from jwt.exceptions import InvalidTokenError
-from pwdlib import PasswordHash
-from pydantic import BaseModel, ValidationError
-
-# to get a string like this run:
-# openssl rand -hex 32
-SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
-ALGORITHM = "HS256"
-ACCESS_TOKEN_EXPIRE_MINUTES = 30
-
-
-fake_users_db = {
-    "johndoe": {
-        "username": "johndoe",
-        "full_name": "John Doe",
-        "email": "johndoe@example.com",
-        "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc",
-        "disabled": False,
-    },
-    "alice": {
-        "username": "alice",
-        "full_name": "Alice Chains",
-        "email": "alicechains@example.com",
-        "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE",
-        "disabled": True,
-    },
-}
-
-
-class Token(BaseModel):
-    access_token: str
-    token_type: str
-
-
-class TokenData(BaseModel):
-    username: Union[str, None] = None
-    scopes: list[str] = []
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-class UserInDB(User):
-    hashed_password: str
-
-
-password_hash = PasswordHash.recommended()
-
-oauth2_scheme = OAuth2PasswordBearer(
-    tokenUrl="token",
-    scopes={"me": "Read information about the current user.", "items": "Read items."},
-)
-
-app = FastAPI()
-
-
-def verify_password(plain_password, hashed_password):
-    return password_hash.verify(plain_password, hashed_password)
-
-
-def get_password_hash(password):
-    return password_hash.hash(password)
-
-
-def get_user(db, username: str):
-    if username in db:
-        user_dict = db[username]
-        return UserInDB(**user_dict)
-
-
-def authenticate_user(fake_db, username: str, password: str):
-    user = get_user(fake_db, username)
-    if not user:
-        return False
-    if not verify_password(password, user.hashed_password):
-        return False
-    return user
-
-
-def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None):
-    to_encode = data.copy()
-    if expires_delta:
-        expire = datetime.now(timezone.utc) + expires_delta
-    else:
-        expire = datetime.now(timezone.utc) + timedelta(minutes=15)
-    to_encode.update({"exp": expire})
-    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
-    return encoded_jwt
-
-
-async def get_current_user(
-    security_scopes: SecurityScopes, token: Annotated[str, Depends(oauth2_scheme)]
-):
-    if security_scopes.scopes:
-        authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
-    else:
-        authenticate_value = "Bearer"
-    credentials_exception = HTTPException(
-        status_code=status.HTTP_401_UNAUTHORIZED,
-        detail="Could not validate credentials",
-        headers={"WWW-Authenticate": authenticate_value},
-    )
-    try:
-        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
-        username = payload.get("sub")
-        if username is None:
-            raise credentials_exception
-        scope: str = payload.get("scope", "")
-        token_scopes = scope.split(" ")
-        token_data = TokenData(scopes=token_scopes, username=username)
-    except (InvalidTokenError, ValidationError):
-        raise credentials_exception
-    user = get_user(fake_users_db, username=token_data.username)
-    if user is None:
-        raise credentials_exception
-    for scope in security_scopes.scopes:
-        if scope not in token_data.scopes:
-            raise HTTPException(
-                status_code=status.HTTP_401_UNAUTHORIZED,
-                detail="Not enough permissions",
-                headers={"WWW-Authenticate": authenticate_value},
-            )
-    return user
-
-
-async def get_current_active_user(
-    current_user: Annotated[User, Security(get_current_user, scopes=["me"])],
-):
-    if current_user.disabled:
-        raise HTTPException(status_code=400, detail="Inactive user")
-    return current_user
-
-
-@app.post("/token")
-async def login_for_access_token(
-    form_data: Annotated[OAuth2PasswordRequestForm, Depends()],
-) -> Token:
-    user = authenticate_user(fake_users_db, form_data.username, form_data.password)
-    if not user:
-        raise HTTPException(status_code=400, detail="Incorrect username or password")
-    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
-    access_token = create_access_token(
-        data={"sub": user.username, "scope": " ".join(form_data.scopes)},
-        expires_delta=access_token_expires,
-    )
-    return Token(access_token=access_token, token_type="bearer")
-
-
-@app.get("/users/me/")
-async def read_users_me(
-    current_user: Annotated[User, Depends(get_current_active_user)],
-) -> User:
-    return current_user
-
-
-@app.get("/users/me/items/")
-async def read_own_items(
-    current_user: Annotated[User, Security(get_current_active_user, scopes=["items"])],
-):
-    return [{"item_id": "Foo", "owner": current_user.username}]
-
-
-@app.get("/status/")
-async def read_system_status(current_user: Annotated[User, Depends(get_current_user)]):
-    return {"status": "ok"}
diff --git a/docs_src/security/tutorial005_py39.py b/docs_src/security/tutorial005_py39.py
deleted file mode 100644 (file)
index 32280aa..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-from datetime import datetime, timedelta, timezone
-from typing import Union
-
-import jwt
-from fastapi import Depends, FastAPI, HTTPException, Security, status
-from fastapi.security import (
-    OAuth2PasswordBearer,
-    OAuth2PasswordRequestForm,
-    SecurityScopes,
-)
-from jwt.exceptions import InvalidTokenError
-from pwdlib import PasswordHash
-from pydantic import BaseModel, ValidationError
-
-# to get a string like this run:
-# openssl rand -hex 32
-SECRET_KEY = "09d25e094faa6ca2556c818166b7a9563b93f7099f6f0f4caa6cf63b88e8d3e7"
-ALGORITHM = "HS256"
-ACCESS_TOKEN_EXPIRE_MINUTES = 30
-
-
-fake_users_db = {
-    "johndoe": {
-        "username": "johndoe",
-        "full_name": "John Doe",
-        "email": "johndoe@example.com",
-        "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$wagCPXjifgvUFBzq4hqe3w$CYaIb8sB+wtD+Vu/P4uod1+Qof8h+1g7bbDlBID48Rc",
-        "disabled": False,
-    },
-    "alice": {
-        "username": "alice",
-        "full_name": "Alice Chains",
-        "email": "alicechains@example.com",
-        "hashed_password": "$argon2id$v=19$m=65536,t=3,p=4$g2/AV1zwopqUntPKJavBFw$BwpRGDCyUHLvHICnwijyX8ROGoiUPwNKZ7915MeYfCE",
-        "disabled": True,
-    },
-}
-
-
-class Token(BaseModel):
-    access_token: str
-    token_type: str
-
-
-class TokenData(BaseModel):
-    username: Union[str, None] = None
-    scopes: list[str] = []
-
-
-class User(BaseModel):
-    username: str
-    email: Union[str, None] = None
-    full_name: Union[str, None] = None
-    disabled: Union[bool, None] = None
-
-
-class UserInDB(User):
-    hashed_password: str
-
-
-password_hash = PasswordHash.recommended()
-
-oauth2_scheme = OAuth2PasswordBearer(
-    tokenUrl="token",
-    scopes={"me": "Read information about the current user.", "items": "Read items."},
-)
-
-app = FastAPI()
-
-
-def verify_password(plain_password, hashed_password):
-    return password_hash.verify(plain_password, hashed_password)
-
-
-def get_password_hash(password):
-    return password_hash.hash(password)
-
-
-def get_user(db, username: str):
-    if username in db:
-        user_dict = db[username]
-        return UserInDB(**user_dict)
-
-
-def authenticate_user(fake_db, username: str, password: str):
-    user = get_user(fake_db, username)
-    if not user:
-        return False
-    if not verify_password(password, user.hashed_password):
-        return False
-    return user
-
-
-def create_access_token(data: dict, expires_delta: Union[timedelta, None] = None):
-    to_encode = data.copy()
-    if expires_delta:
-        expire = datetime.now(timezone.utc) + expires_delta
-    else:
-        expire = datetime.now(timezone.utc) + timedelta(minutes=15)
-    to_encode.update({"exp": expire})
-    encoded_jwt = jwt.encode(to_encode, SECRET_KEY, algorithm=ALGORITHM)
-    return encoded_jwt
-
-
-async def get_current_user(
-    security_scopes: SecurityScopes, token: str = Depends(oauth2_scheme)
-):
-    if security_scopes.scopes:
-        authenticate_value = f'Bearer scope="{security_scopes.scope_str}"'
-    else:
-        authenticate_value = "Bearer"
-    credentials_exception = HTTPException(
-        status_code=status.HTTP_401_UNAUTHORIZED,
-        detail="Could not validate credentials",
-        headers={"WWW-Authenticate": authenticate_value},
-    )
-    try:
-        payload = jwt.decode(token, SECRET_KEY, algorithms=[ALGORITHM])
-        username: str = payload.get("sub")
-        if username is None:
-            raise credentials_exception
-        scope: str = payload.get("scope", "")
-        token_scopes = scope.split(" ")
-        token_data = TokenData(scopes=token_scopes, username=username)
-    except (InvalidTokenError, ValidationError):
-        raise credentials_exception
-    user = get_user(fake_users_db, username=token_data.username)
-    if user is None:
-        raise credentials_exception
-    for scope in security_scopes.scopes:
-        if scope not in token_data.scopes:
-            raise HTTPException(
-                status_code=status.HTTP_401_UNAUTHORIZED,
-                detail="Not enough permissions",
-                headers={"WWW-Authenticate": authenticate_value},
-            )
-    return user
-
-
-async def get_current_active_user(
-    current_user: User = Security(get_current_user, scopes=["me"]),
-):
-    if current_user.disabled:
-        raise HTTPException(status_code=400, detail="Inactive user")
-    return current_user
-
-
-@app.post("/token")
-async def login_for_access_token(
-    form_data: OAuth2PasswordRequestForm = Depends(),
-) -> Token:
-    user = authenticate_user(fake_users_db, form_data.username, form_data.password)
-    if not user:
-        raise HTTPException(status_code=400, detail="Incorrect username or password")
-    access_token_expires = timedelta(minutes=ACCESS_TOKEN_EXPIRE_MINUTES)
-    access_token = create_access_token(
-        data={"sub": user.username, "scope": " ".join(form_data.scopes)},
-        expires_delta=access_token_expires,
-    )
-    return Token(access_token=access_token, token_type="bearer")
-
-
-@app.get("/users/me/")
-async def read_users_me(current_user: User = Depends(get_current_active_user)) -> User:
-    return current_user
-
-
-@app.get("/users/me/items/")
-async def read_own_items(
-    current_user: User = Security(get_current_active_user, scopes=["items"]),
-):
-    return [{"item_id": "Foo", "owner": current_user.username}]
-
-
-@app.get("/status/")
-async def read_system_status(current_user: User = Depends(get_current_user)):
-    return {"status": "ok"}
diff --git a/docs_src/security/tutorial006_an_py310.py b/docs_src/security/tutorial006_an_py310.py
new file mode 100644 (file)
index 0000000..03c696a
--- /dev/null
@@ -0,0 +1,13 @@
+from typing import Annotated
+
+from fastapi import Depends, FastAPI
+from fastapi.security import HTTPBasic, HTTPBasicCredentials
+
+app = FastAPI()
+
+security = HTTPBasic()
+
+
+@app.get("/users/me")
+def read_current_user(credentials: Annotated[HTTPBasicCredentials, Depends(security)]):
+    return {"username": credentials.username, "password": credentials.password}
diff --git a/docs_src/security/tutorial006_py310.py b/docs_src/security/tutorial006_py310.py
new file mode 100644 (file)
index 0000000..29121ff
--- /dev/null
@@ -0,0 +1,11 @@
+from fastapi import Depends, FastAPI
+from fastapi.security import HTTPBasic, HTTPBasicCredentials
+
+app = FastAPI()
+
+security = HTTPBasic()
+
+
+@app.get("/users/me")
+def read_current_user(credentials: HTTPBasicCredentials = Depends(security)):
+    return {"username": credentials.username, "password": credentials.password}
diff --git a/docs_src/security/tutorial007_an_py310.py b/docs_src/security/tutorial007_an_py310.py
new file mode 100644 (file)
index 0000000..87ef986
--- /dev/null
@@ -0,0 +1,36 @@
+import secrets
+from typing import Annotated
+
+from fastapi import Depends, FastAPI, HTTPException, status
+from fastapi.security import HTTPBasic, HTTPBasicCredentials
+
+app = FastAPI()
+
+security = HTTPBasic()
+
+
+def get_current_username(
+    credentials: Annotated[HTTPBasicCredentials, Depends(security)],
+):
+    current_username_bytes = credentials.username.encode("utf8")
+    correct_username_bytes = b"stanleyjobson"
+    is_correct_username = secrets.compare_digest(
+        current_username_bytes, correct_username_bytes
+    )
+    current_password_bytes = credentials.password.encode("utf8")
+    correct_password_bytes = b"swordfish"
+    is_correct_password = secrets.compare_digest(
+        current_password_bytes, correct_password_bytes
+    )
+    if not (is_correct_username and is_correct_password):
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail="Incorrect username or password",
+            headers={"WWW-Authenticate": "Basic"},
+        )
+    return credentials.username
+
+
+@app.get("/users/me")
+def read_current_user(username: Annotated[str, Depends(get_current_username)]):
+    return {"username": username}
diff --git a/docs_src/security/tutorial007_py310.py b/docs_src/security/tutorial007_py310.py
new file mode 100644 (file)
index 0000000..ac816eb
--- /dev/null
@@ -0,0 +1,33 @@
+import secrets
+
+from fastapi import Depends, FastAPI, HTTPException, status
+from fastapi.security import HTTPBasic, HTTPBasicCredentials
+
+app = FastAPI()
+
+security = HTTPBasic()
+
+
+def get_current_username(credentials: HTTPBasicCredentials = Depends(security)):
+    current_username_bytes = credentials.username.encode("utf8")
+    correct_username_bytes = b"stanleyjobson"
+    is_correct_username = secrets.compare_digest(
+        current_username_bytes, correct_username_bytes
+    )
+    current_password_bytes = credentials.password.encode("utf8")
+    correct_password_bytes = b"swordfish"
+    is_correct_password = secrets.compare_digest(
+        current_password_bytes, correct_password_bytes
+    )
+    if not (is_correct_username and is_correct_password):
+        raise HTTPException(
+            status_code=status.HTTP_401_UNAUTHORIZED,
+            detail="Incorrect username or password",
+            headers={"WWW-Authenticate": "Basic"},
+        )
+    return credentials.username
+
+
+@app.get("/users/me")
+def read_current_user(username: str = Depends(get_current_username)):
+    return {"username": username}
diff --git a/docs_src/separate_openapi_schemas/tutorial001_py39.py b/docs_src/separate_openapi_schemas/tutorial001_py39.py
deleted file mode 100644 (file)
index 63cffd1..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import Optional
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Optional[str] = None
-
-
-app = FastAPI()
-
-
-@app.post("/items/")
-def create_item(item: Item):
-    return item
-
-
-@app.get("/items/")
-def read_items() -> list[Item]:
-    return [
-        Item(
-            name="Portal Gun",
-            description="Device to travel through the multi-rick-verse",
-        ),
-        Item(name="Plumbus"),
-    ]
diff --git a/docs_src/separate_openapi_schemas/tutorial002_py39.py b/docs_src/separate_openapi_schemas/tutorial002_py39.py
deleted file mode 100644 (file)
index 50d997d..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import Optional
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Optional[str] = None
-
-
-app = FastAPI(separate_input_output_schemas=False)
-
-
-@app.post("/items/")
-def create_item(item: Item):
-    return item
-
-
-@app.get("/items/")
-def read_items() -> list[Item]:
-    return [
-        Item(
-            name="Portal Gun",
-            description="Device to travel through the multi-rick-verse",
-        ),
-        Item(name="Plumbus"),
-    ]
diff --git a/docs_src/settings/app01_py310/__init__.py b/docs_src/settings/app01_py310/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 59%
rename from docs_src/settings/app03_an_py39/config_pv1.py
rename to docs_src/settings/app01_py310/config.py
index 7ae66ef77c9dcfc33242c7cd921af8efb89e037c..b31b8811d6539ac1d8e09872ab1cb7772673db61 100644 (file)
@@ -1,4 +1,4 @@
-from pydantic.v1 import BaseSettings
+from pydantic_settings import BaseSettings
 
 
 class Settings(BaseSettings):
@@ -6,5 +6,5 @@ class Settings(BaseSettings):
     admin_email: str
     items_per_user: int = 50
 
-    class Config:
-        env_file = ".env"
+
+settings = Settings()
diff --git a/docs_src/settings/app01_py310/main.py b/docs_src/settings/app01_py310/main.py
new file mode 100644 (file)
index 0000000..4a3a86c
--- /dev/null
@@ -0,0 +1,14 @@
+from fastapi import FastAPI
+
+from .config import settings
+
+app = FastAPI()
+
+
+@app.get("/info")
+async def info():
+    return {
+        "app_name": settings.app_name,
+        "admin_email": settings.admin_email,
+        "items_per_user": settings.items_per_user,
+    }
diff --git a/docs_src/settings/app02_an_py310/__init__.py b/docs_src/settings/app02_an_py310/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
similarity index 58%
rename from docs_src/settings/app03_py39/config_pv1.py
rename to docs_src/settings/app02_an_py310/config.py
index 7ae66ef77c9dcfc33242c7cd921af8efb89e037c..e17b5035dcc77f53a3c87213eed9f77a44506440 100644 (file)
@@ -1,10 +1,7 @@
-from pydantic.v1 import BaseSettings
+from pydantic_settings import BaseSettings
 
 
 class Settings(BaseSettings):
     app_name: str = "Awesome API"
     admin_email: str
     items_per_user: int = 50
-
-    class Config:
-        env_file = ".env"
diff --git a/docs_src/settings/app02_an_py310/main.py b/docs_src/settings/app02_an_py310/main.py
new file mode 100644 (file)
index 0000000..6d5db12
--- /dev/null
@@ -0,0 +1,22 @@
+from functools import lru_cache
+from typing import Annotated
+
+from fastapi import Depends, FastAPI
+
+from .config import Settings
+
+app = FastAPI()
+
+
+@lru_cache
+def get_settings():
+    return Settings()
+
+
+@app.get("/info")
+async def info(settings: Annotated[Settings, Depends(get_settings)]):
+    return {
+        "app_name": settings.app_name,
+        "admin_email": settings.admin_email,
+        "items_per_user": settings.items_per_user,
+    }
diff --git a/docs_src/settings/app02_an_py310/test_main.py b/docs_src/settings/app02_an_py310/test_main.py
new file mode 100644 (file)
index 0000000..7a04d7e
--- /dev/null
@@ -0,0 +1,23 @@
+from fastapi.testclient import TestClient
+
+from .config import Settings
+from .main import app, get_settings
+
+client = TestClient(app)
+
+
+def get_settings_override():
+    return Settings(admin_email="testing_admin@example.com")
+
+
+app.dependency_overrides[get_settings] = get_settings_override
+
+
+def test_app():
+    response = client.get("/info")
+    data = response.json()
+    assert data == {
+        "app_name": "Awesome API",
+        "admin_email": "testing_admin@example.com",
+        "items_per_user": 50,
+    }
diff --git a/docs_src/settings/app02_py310/__init__.py b/docs_src/settings/app02_py310/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/settings/app02_py310/config.py b/docs_src/settings/app02_py310/config.py
new file mode 100644 (file)
index 0000000..e17b503
--- /dev/null
@@ -0,0 +1,7 @@
+from pydantic_settings import BaseSettings
+
+
+class Settings(BaseSettings):
+    app_name: str = "Awesome API"
+    admin_email: str
+    items_per_user: int = 50
diff --git a/docs_src/settings/app02_py310/main.py b/docs_src/settings/app02_py310/main.py
new file mode 100644 (file)
index 0000000..941f82e
--- /dev/null
@@ -0,0 +1,21 @@
+from functools import lru_cache
+
+from fastapi import Depends, FastAPI
+
+from .config import Settings
+
+app = FastAPI()
+
+
+@lru_cache
+def get_settings():
+    return Settings()
+
+
+@app.get("/info")
+async def info(settings: Settings = Depends(get_settings)):
+    return {
+        "app_name": settings.app_name,
+        "admin_email": settings.admin_email,
+        "items_per_user": settings.items_per_user,
+    }
diff --git a/docs_src/settings/app02_py310/test_main.py b/docs_src/settings/app02_py310/test_main.py
new file mode 100644 (file)
index 0000000..7a04d7e
--- /dev/null
@@ -0,0 +1,23 @@
+from fastapi.testclient import TestClient
+
+from .config import Settings
+from .main import app, get_settings
+
+client = TestClient(app)
+
+
+def get_settings_override():
+    return Settings(admin_email="testing_admin@example.com")
+
+
+app.dependency_overrides[get_settings] = get_settings_override
+
+
+def test_app():
+    response = client.get("/info")
+    data = response.json()
+    assert data == {
+        "app_name": "Awesome API",
+        "admin_email": "testing_admin@example.com",
+        "items_per_user": 50,
+    }
diff --git a/docs_src/settings/app03_an_py310/__init__.py b/docs_src/settings/app03_an_py310/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/settings/app03_an_py310/config.py b/docs_src/settings/app03_an_py310/config.py
new file mode 100644 (file)
index 0000000..08f8f88
--- /dev/null
@@ -0,0 +1,9 @@
+from pydantic_settings import BaseSettings, SettingsConfigDict
+
+
+class Settings(BaseSettings):
+    app_name: str = "Awesome API"
+    admin_email: str
+    items_per_user: int = 50
+
+    model_config = SettingsConfigDict(env_file=".env")
diff --git a/docs_src/settings/app03_an_py310/main.py b/docs_src/settings/app03_an_py310/main.py
new file mode 100644 (file)
index 0000000..2f64b9c
--- /dev/null
@@ -0,0 +1,22 @@
+from functools import lru_cache
+from typing import Annotated
+
+from fastapi import Depends, FastAPI
+
+from . import config
+
+app = FastAPI()
+
+
+@lru_cache
+def get_settings():
+    return config.Settings()
+
+
+@app.get("/info")
+async def info(settings: Annotated[config.Settings, Depends(get_settings)]):
+    return {
+        "app_name": settings.app_name,
+        "admin_email": settings.admin_email,
+        "items_per_user": settings.items_per_user,
+    }
diff --git a/docs_src/settings/app03_py310/__init__.py b/docs_src/settings/app03_py310/__init__.py
new file mode 100644 (file)
index 0000000..e69de29
diff --git a/docs_src/settings/app03_py310/config.py b/docs_src/settings/app03_py310/config.py
new file mode 100644 (file)
index 0000000..08f8f88
--- /dev/null
@@ -0,0 +1,9 @@
+from pydantic_settings import BaseSettings, SettingsConfigDict
+
+
+class Settings(BaseSettings):
+    app_name: str = "Awesome API"
+    admin_email: str
+    items_per_user: int = 50
+
+    model_config = SettingsConfigDict(env_file=".env")
diff --git a/docs_src/settings/app03_py310/main.py b/docs_src/settings/app03_py310/main.py
new file mode 100644 (file)
index 0000000..ea64a57
--- /dev/null
@@ -0,0 +1,21 @@
+from functools import lru_cache
+
+from fastapi import Depends, FastAPI
+
+from . import config
+
+app = FastAPI()
+
+
+@lru_cache
+def get_settings():
+    return config.Settings()
+
+
+@app.get("/info")
+async def info(settings: config.Settings = Depends(get_settings)):
+    return {
+        "app_name": settings.app_name,
+        "admin_email": settings.admin_email,
+        "items_per_user": settings.items_per_user,
+    }
similarity index 89%
rename from docs_src/settings/tutorial001_pv1_py39.py
rename to docs_src/settings/tutorial001_py310.py
index 20ad2bbf624e0441080267ef4ee096b213bde1dd..d48c4c060cfd1f70dba25f69aee6f2ba0cf3448c 100644 (file)
@@ -1,5 +1,5 @@
 from fastapi import FastAPI
-from pydantic.v1 import BaseSettings
+from pydantic_settings import BaseSettings
 
 
 class Settings(BaseSettings):
diff --git a/docs_src/sql_databases/tutorial001_an_py39.py b/docs_src/sql_databases/tutorial001_an_py39.py
deleted file mode 100644 (file)
index 5958927..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI, HTTPException, Query
-from sqlmodel import Field, Session, SQLModel, create_engine, select
-
-
-class Hero(SQLModel, table=True):
-    id: Union[int, None] = Field(default=None, primary_key=True)
-    name: str = Field(index=True)
-    age: Union[int, None] = Field(default=None, index=True)
-    secret_name: str
-
-
-sqlite_file_name = "database.db"
-sqlite_url = f"sqlite:///{sqlite_file_name}"
-
-connect_args = {"check_same_thread": False}
-engine = create_engine(sqlite_url, connect_args=connect_args)
-
-
-def create_db_and_tables():
-    SQLModel.metadata.create_all(engine)
-
-
-def get_session():
-    with Session(engine) as session:
-        yield session
-
-
-SessionDep = Annotated[Session, Depends(get_session)]
-
-app = FastAPI()
-
-
-@app.on_event("startup")
-def on_startup():
-    create_db_and_tables()
-
-
-@app.post("/heroes/")
-def create_hero(hero: Hero, session: SessionDep) -> Hero:
-    session.add(hero)
-    session.commit()
-    session.refresh(hero)
-    return hero
-
-
-@app.get("/heroes/")
-def read_heroes(
-    session: SessionDep,
-    offset: int = 0,
-    limit: Annotated[int, Query(le=100)] = 100,
-) -> list[Hero]:
-    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
-    return heroes
-
-
-@app.get("/heroes/{hero_id}")
-def read_hero(hero_id: int, session: SessionDep) -> Hero:
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    return hero
-
-
-@app.delete("/heroes/{hero_id}")
-def delete_hero(hero_id: int, session: SessionDep):
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    session.delete(hero)
-    session.commit()
-    return {"ok": True}
diff --git a/docs_src/sql_databases/tutorial001_py39.py b/docs_src/sql_databases/tutorial001_py39.py
deleted file mode 100644 (file)
index 410a52d..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI, HTTPException, Query
-from sqlmodel import Field, Session, SQLModel, create_engine, select
-
-
-class Hero(SQLModel, table=True):
-    id: Union[int, None] = Field(default=None, primary_key=True)
-    name: str = Field(index=True)
-    age: Union[int, None] = Field(default=None, index=True)
-    secret_name: str
-
-
-sqlite_file_name = "database.db"
-sqlite_url = f"sqlite:///{sqlite_file_name}"
-
-connect_args = {"check_same_thread": False}
-engine = create_engine(sqlite_url, connect_args=connect_args)
-
-
-def create_db_and_tables():
-    SQLModel.metadata.create_all(engine)
-
-
-def get_session():
-    with Session(engine) as session:
-        yield session
-
-
-app = FastAPI()
-
-
-@app.on_event("startup")
-def on_startup():
-    create_db_and_tables()
-
-
-@app.post("/heroes/")
-def create_hero(hero: Hero, session: Session = Depends(get_session)) -> Hero:
-    session.add(hero)
-    session.commit()
-    session.refresh(hero)
-    return hero
-
-
-@app.get("/heroes/")
-def read_heroes(
-    session: Session = Depends(get_session),
-    offset: int = 0,
-    limit: int = Query(default=100, le=100),
-) -> list[Hero]:
-    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
-    return heroes
-
-
-@app.get("/heroes/{hero_id}")
-def read_hero(hero_id: int, session: Session = Depends(get_session)) -> Hero:
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    return hero
-
-
-@app.delete("/heroes/{hero_id}")
-def delete_hero(hero_id: int, session: Session = Depends(get_session)):
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    session.delete(hero)
-    session.commit()
-    return {"ok": True}
diff --git a/docs_src/sql_databases/tutorial002_an_py39.py b/docs_src/sql_databases/tutorial002_an_py39.py
deleted file mode 100644 (file)
index a8a0721..0000000
+++ /dev/null
@@ -1,103 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import Depends, FastAPI, HTTPException, Query
-from sqlmodel import Field, Session, SQLModel, create_engine, select
-
-
-class HeroBase(SQLModel):
-    name: str = Field(index=True)
-    age: Union[int, None] = Field(default=None, index=True)
-
-
-class Hero(HeroBase, table=True):
-    id: Union[int, None] = Field(default=None, primary_key=True)
-    secret_name: str
-
-
-class HeroPublic(HeroBase):
-    id: int
-
-
-class HeroCreate(HeroBase):
-    secret_name: str
-
-
-class HeroUpdate(HeroBase):
-    name: Union[str, None] = None
-    age: Union[int, None] = None
-    secret_name: Union[str, None] = None
-
-
-sqlite_file_name = "database.db"
-sqlite_url = f"sqlite:///{sqlite_file_name}"
-
-connect_args = {"check_same_thread": False}
-engine = create_engine(sqlite_url, connect_args=connect_args)
-
-
-def create_db_and_tables():
-    SQLModel.metadata.create_all(engine)
-
-
-def get_session():
-    with Session(engine) as session:
-        yield session
-
-
-SessionDep = Annotated[Session, Depends(get_session)]
-app = FastAPI()
-
-
-@app.on_event("startup")
-def on_startup():
-    create_db_and_tables()
-
-
-@app.post("/heroes/", response_model=HeroPublic)
-def create_hero(hero: HeroCreate, session: SessionDep):
-    db_hero = Hero.model_validate(hero)
-    session.add(db_hero)
-    session.commit()
-    session.refresh(db_hero)
-    return db_hero
-
-
-@app.get("/heroes/", response_model=list[HeroPublic])
-def read_heroes(
-    session: SessionDep,
-    offset: int = 0,
-    limit: Annotated[int, Query(le=100)] = 100,
-):
-    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
-    return heroes
-
-
-@app.get("/heroes/{hero_id}", response_model=HeroPublic)
-def read_hero(hero_id: int, session: SessionDep):
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    return hero
-
-
-@app.patch("/heroes/{hero_id}", response_model=HeroPublic)
-def update_hero(hero_id: int, hero: HeroUpdate, session: SessionDep):
-    hero_db = session.get(Hero, hero_id)
-    if not hero_db:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    hero_data = hero.model_dump(exclude_unset=True)
-    hero_db.sqlmodel_update(hero_data)
-    session.add(hero_db)
-    session.commit()
-    session.refresh(hero_db)
-    return hero_db
-
-
-@app.delete("/heroes/{hero_id}")
-def delete_hero(hero_id: int, session: SessionDep):
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    session.delete(hero)
-    session.commit()
-    return {"ok": True}
diff --git a/docs_src/sql_databases/tutorial002_py39.py b/docs_src/sql_databases/tutorial002_py39.py
deleted file mode 100644 (file)
index d8f5dd0..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI, HTTPException, Query
-from sqlmodel import Field, Session, SQLModel, create_engine, select
-
-
-class HeroBase(SQLModel):
-    name: str = Field(index=True)
-    age: Union[int, None] = Field(default=None, index=True)
-
-
-class Hero(HeroBase, table=True):
-    id: Union[int, None] = Field(default=None, primary_key=True)
-    secret_name: str
-
-
-class HeroPublic(HeroBase):
-    id: int
-
-
-class HeroCreate(HeroBase):
-    secret_name: str
-
-
-class HeroUpdate(HeroBase):
-    name: Union[str, None] = None
-    age: Union[int, None] = None
-    secret_name: Union[str, None] = None
-
-
-sqlite_file_name = "database.db"
-sqlite_url = f"sqlite:///{sqlite_file_name}"
-
-connect_args = {"check_same_thread": False}
-engine = create_engine(sqlite_url, connect_args=connect_args)
-
-
-def create_db_and_tables():
-    SQLModel.metadata.create_all(engine)
-
-
-def get_session():
-    with Session(engine) as session:
-        yield session
-
-
-app = FastAPI()
-
-
-@app.on_event("startup")
-def on_startup():
-    create_db_and_tables()
-
-
-@app.post("/heroes/", response_model=HeroPublic)
-def create_hero(hero: HeroCreate, session: Session = Depends(get_session)):
-    db_hero = Hero.model_validate(hero)
-    session.add(db_hero)
-    session.commit()
-    session.refresh(db_hero)
-    return db_hero
-
-
-@app.get("/heroes/", response_model=list[HeroPublic])
-def read_heroes(
-    session: Session = Depends(get_session),
-    offset: int = 0,
-    limit: int = Query(default=100, le=100),
-):
-    heroes = session.exec(select(Hero).offset(offset).limit(limit)).all()
-    return heroes
-
-
-@app.get("/heroes/{hero_id}", response_model=HeroPublic)
-def read_hero(hero_id: int, session: Session = Depends(get_session)):
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    return hero
-
-
-@app.patch("/heroes/{hero_id}", response_model=HeroPublic)
-def update_hero(
-    hero_id: int, hero: HeroUpdate, session: Session = Depends(get_session)
-):
-    hero_db = session.get(Hero, hero_id)
-    if not hero_db:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    hero_data = hero.model_dump(exclude_unset=True)
-    hero_db.sqlmodel_update(hero_data)
-    session.add(hero_db)
-    session.commit()
-    session.refresh(hero_db)
-    return hero_db
-
-
-@app.delete("/heroes/{hero_id}")
-def delete_hero(hero_id: int, session: Session = Depends(get_session)):
-    hero = session.get(Hero, hero_id)
-    if not hero:
-        raise HTTPException(status_code=404, detail="Hero not found")
-    session.delete(hero)
-    session.commit()
-    return {"ok": True}
diff --git a/docs_src/static_files/tutorial001_py310.py b/docs_src/static_files/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..460352c
--- /dev/null
@@ -0,0 +1,6 @@
+from fastapi import FastAPI
+from fastapi.staticfiles import StaticFiles
+
+app = FastAPI()
+
+app.mount("/static", StaticFiles(directory="static"), name="static")
diff --git a/docs_src/sub_applications/tutorial001_py310.py b/docs_src/sub_applications/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..57e627e
--- /dev/null
@@ -0,0 +1,19 @@
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+@app.get("/app")
+def read_main():
+    return {"message": "Hello World from main app"}
+
+
+subapi = FastAPI()
+
+
+@subapi.get("/sub")
+def read_sub():
+    return {"message": "Hello World from sub API"}
+
+
+app.mount("/subapi", subapi)
diff --git a/docs_src/templates/tutorial001_py310.py b/docs_src/templates/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..81ccc8d
--- /dev/null
@@ -0,0 +1,18 @@
+from fastapi import FastAPI, Request
+from fastapi.responses import HTMLResponse
+from fastapi.staticfiles import StaticFiles
+from fastapi.templating import Jinja2Templates
+
+app = FastAPI()
+
+app.mount("/static", StaticFiles(directory="static"), name="static")
+
+
+templates = Jinja2Templates(directory="templates")
+
+
+@app.get("/items/{id}", response_class=HTMLResponse)
+async def read_item(request: Request, id: str):
+    return templates.TemplateResponse(
+        request=request, name="item.html", context={"id": id}
+    )
diff --git a/docs_src/using_request_directly/tutorial001_py310.py b/docs_src/using_request_directly/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..2d7288b
--- /dev/null
@@ -0,0 +1,9 @@
+from fastapi import FastAPI, Request
+
+app = FastAPI()
+
+
+@app.get("/items/{item_id}")
+def read_root(item_id: str, request: Request):
+    client_host = request.client.host
+    return {"client_host": client_host, "item_id": item_id}
diff --git a/docs_src/websockets/tutorial001_py310.py b/docs_src/websockets/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..a43a2be
--- /dev/null
@@ -0,0 +1,51 @@
+from fastapi import FastAPI, WebSocket
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+html = """
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Chat</title>
+    </head>
+    <body>
+        <h1>WebSocket Chat</h1>
+        <form action="" onsubmit="sendMessage(event)">
+            <input type="text" id="messageText" autocomplete="off"/>
+            <button>Send</button>
+        </form>
+        <ul id='messages'>
+        </ul>
+        <script>
+            var ws = new WebSocket("ws://localhost:8000/ws");
+            ws.onmessage = function(event) {
+                var messages = document.getElementById('messages')
+                var message = document.createElement('li')
+                var content = document.createTextNode(event.data)
+                message.appendChild(content)
+                messages.appendChild(message)
+            };
+            function sendMessage(event) {
+                var input = document.getElementById("messageText")
+                ws.send(input.value)
+                input.value = ''
+                event.preventDefault()
+            }
+        </script>
+    </body>
+</html>
+"""
+
+
+@app.get("/")
+async def get():
+    return HTMLResponse(html)
+
+
+@app.websocket("/ws")
+async def websocket_endpoint(websocket: WebSocket):
+    await websocket.accept()
+    while True:
+        data = await websocket.receive_text()
+        await websocket.send_text(f"Message text was: {data}")
diff --git a/docs_src/websockets/tutorial002_an_py39.py b/docs_src/websockets/tutorial002_an_py39.py
deleted file mode 100644 (file)
index 606d355..0000000
+++ /dev/null
@@ -1,92 +0,0 @@
-from typing import Annotated, Union
-
-from fastapi import (
-    Cookie,
-    Depends,
-    FastAPI,
-    Query,
-    WebSocket,
-    WebSocketException,
-    status,
-)
-from fastapi.responses import HTMLResponse
-
-app = FastAPI()
-
-html = """
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>Chat</title>
-    </head>
-    <body>
-        <h1>WebSocket Chat</h1>
-        <form action="" onsubmit="sendMessage(event)">
-            <label>Item ID: <input type="text" id="itemId" autocomplete="off" value="foo"/></label>
-            <label>Token: <input type="text" id="token" autocomplete="off" value="some-key-token"/></label>
-            <button onclick="connect(event)">Connect</button>
-            <hr>
-            <label>Message: <input type="text" id="messageText" autocomplete="off"/></label>
-            <button>Send</button>
-        </form>
-        <ul id='messages'>
-        </ul>
-        <script>
-        var ws = null;
-            function connect(event) {
-                var itemId = document.getElementById("itemId")
-                var token = document.getElementById("token")
-                ws = new WebSocket("ws://localhost:8000/items/" + itemId.value + "/ws?token=" + token.value);
-                ws.onmessage = function(event) {
-                    var messages = document.getElementById('messages')
-                    var message = document.createElement('li')
-                    var content = document.createTextNode(event.data)
-                    message.appendChild(content)
-                    messages.appendChild(message)
-                };
-                event.preventDefault()
-            }
-            function sendMessage(event) {
-                var input = document.getElementById("messageText")
-                ws.send(input.value)
-                input.value = ''
-                event.preventDefault()
-            }
-        </script>
-    </body>
-</html>
-"""
-
-
-@app.get("/")
-async def get():
-    return HTMLResponse(html)
-
-
-async def get_cookie_or_token(
-    websocket: WebSocket,
-    session: Annotated[Union[str, None], Cookie()] = None,
-    token: Annotated[Union[str, None], Query()] = None,
-):
-    if session is None and token is None:
-        raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
-    return session or token
-
-
-@app.websocket("/items/{item_id}/ws")
-async def websocket_endpoint(
-    *,
-    websocket: WebSocket,
-    item_id: str,
-    q: Union[int, None] = None,
-    cookie_or_token: Annotated[str, Depends(get_cookie_or_token)],
-):
-    await websocket.accept()
-    while True:
-        data = await websocket.receive_text()
-        await websocket.send_text(
-            f"Session cookie or query token value is: {cookie_or_token}"
-        )
-        if q is not None:
-            await websocket.send_text(f"Query parameter q is: {q}")
-        await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}")
diff --git a/docs_src/websockets/tutorial002_py39.py b/docs_src/websockets/tutorial002_py39.py
deleted file mode 100644 (file)
index cab749e..0000000
+++ /dev/null
@@ -1,91 +0,0 @@
-from typing import Union
-
-from fastapi import (
-    Cookie,
-    Depends,
-    FastAPI,
-    Query,
-    WebSocket,
-    WebSocketException,
-    status,
-)
-from fastapi.responses import HTMLResponse
-
-app = FastAPI()
-
-html = """
-<!DOCTYPE html>
-<html>
-    <head>
-        <title>Chat</title>
-    </head>
-    <body>
-        <h1>WebSocket Chat</h1>
-        <form action="" onsubmit="sendMessage(event)">
-            <label>Item ID: <input type="text" id="itemId" autocomplete="off" value="foo"/></label>
-            <label>Token: <input type="text" id="token" autocomplete="off" value="some-key-token"/></label>
-            <button onclick="connect(event)">Connect</button>
-            <hr>
-            <label>Message: <input type="text" id="messageText" autocomplete="off"/></label>
-            <button>Send</button>
-        </form>
-        <ul id='messages'>
-        </ul>
-        <script>
-        var ws = null;
-            function connect(event) {
-                var itemId = document.getElementById("itemId")
-                var token = document.getElementById("token")
-                ws = new WebSocket("ws://localhost:8000/items/" + itemId.value + "/ws?token=" + token.value);
-                ws.onmessage = function(event) {
-                    var messages = document.getElementById('messages')
-                    var message = document.createElement('li')
-                    var content = document.createTextNode(event.data)
-                    message.appendChild(content)
-                    messages.appendChild(message)
-                };
-                event.preventDefault()
-            }
-            function sendMessage(event) {
-                var input = document.getElementById("messageText")
-                ws.send(input.value)
-                input.value = ''
-                event.preventDefault()
-            }
-        </script>
-    </body>
-</html>
-"""
-
-
-@app.get("/")
-async def get():
-    return HTMLResponse(html)
-
-
-async def get_cookie_or_token(
-    websocket: WebSocket,
-    session: Union[str, None] = Cookie(default=None),
-    token: Union[str, None] = Query(default=None),
-):
-    if session is None and token is None:
-        raise WebSocketException(code=status.WS_1008_POLICY_VIOLATION)
-    return session or token
-
-
-@app.websocket("/items/{item_id}/ws")
-async def websocket_endpoint(
-    websocket: WebSocket,
-    item_id: str,
-    q: Union[int, None] = None,
-    cookie_or_token: str = Depends(get_cookie_or_token),
-):
-    await websocket.accept()
-    while True:
-        data = await websocket.receive_text()
-        await websocket.send_text(
-            f"Session cookie or query token value is: {cookie_or_token}"
-        )
-        if q is not None:
-            await websocket.send_text(f"Query parameter q is: {q}")
-        await websocket.send_text(f"Message text was: {data}, for item ID: {item_id}")
diff --git a/docs_src/websockets/tutorial003_py310.py b/docs_src/websockets/tutorial003_py310.py
new file mode 100644 (file)
index 0000000..3162180
--- /dev/null
@@ -0,0 +1,81 @@
+from fastapi import FastAPI, WebSocket, WebSocketDisconnect
+from fastapi.responses import HTMLResponse
+
+app = FastAPI()
+
+html = """
+<!DOCTYPE html>
+<html>
+    <head>
+        <title>Chat</title>
+    </head>
+    <body>
+        <h1>WebSocket Chat</h1>
+        <h2>Your ID: <span id="ws-id"></span></h2>
+        <form action="" onsubmit="sendMessage(event)">
+            <input type="text" id="messageText" autocomplete="off"/>
+            <button>Send</button>
+        </form>
+        <ul id='messages'>
+        </ul>
+        <script>
+            var client_id = Date.now()
+            document.querySelector("#ws-id").textContent = client_id;
+            var ws = new WebSocket(`ws://localhost:8000/ws/${client_id}`);
+            ws.onmessage = function(event) {
+                var messages = document.getElementById('messages')
+                var message = document.createElement('li')
+                var content = document.createTextNode(event.data)
+                message.appendChild(content)
+                messages.appendChild(message)
+            };
+            function sendMessage(event) {
+                var input = document.getElementById("messageText")
+                ws.send(input.value)
+                input.value = ''
+                event.preventDefault()
+            }
+        </script>
+    </body>
+</html>
+"""
+
+
+class ConnectionManager:
+    def __init__(self):
+        self.active_connections: list[WebSocket] = []
+
+    async def connect(self, websocket: WebSocket):
+        await websocket.accept()
+        self.active_connections.append(websocket)
+
+    def disconnect(self, websocket: WebSocket):
+        self.active_connections.remove(websocket)
+
+    async def send_personal_message(self, message: str, websocket: WebSocket):
+        await websocket.send_text(message)
+
+    async def broadcast(self, message: str):
+        for connection in self.active_connections:
+            await connection.send_text(message)
+
+
+manager = ConnectionManager()
+
+
+@app.get("/")
+async def get():
+    return HTMLResponse(html)
+
+
+@app.websocket("/ws/{client_id}")
+async def websocket_endpoint(websocket: WebSocket, client_id: int):
+    await manager.connect(websocket)
+    try:
+        while True:
+            data = await websocket.receive_text()
+            await manager.send_personal_message(f"You wrote: {data}", websocket)
+            await manager.broadcast(f"Client #{client_id} says: {data}")
+    except WebSocketDisconnect:
+        manager.disconnect(websocket)
+        await manager.broadcast(f"Client #{client_id} left the chat")
diff --git a/docs_src/wsgi/tutorial001_py310.py b/docs_src/wsgi/tutorial001_py310.py
new file mode 100644 (file)
index 0000000..8eeceb8
--- /dev/null
@@ -0,0 +1,23 @@
+from a2wsgi import WSGIMiddleware
+from fastapi import FastAPI
+from flask import Flask, request
+from markupsafe import escape
+
+flask_app = Flask(__name__)
+
+
+@flask_app.route("/")
+def flask_main():
+    name = request.args.get("name", "World")
+    return f"Hello, {escape(name)} from Flask!"
+
+
+app = FastAPI()
+
+
+@app.get("/v2")
+def read_main():
+    return {"message": "Hello World"}
+
+
+app.mount("/v1", WSGIMiddleware(flask_app))
index e1ce30507a7090a8faa3a777cf4d9734649d3298..1e6fda3b1c57aac7c816bb61b287ab890f9224e3 100644 (file)
@@ -285,20 +285,205 @@ omit = [
     "docs_src/dependencies/tutorial014_an_py310.py",  # temporary code example?
     # Pydantic v1 migration, no longer tested
     "docs_src/pydantic_v1_in_v2/tutorial001_an_py310.py",
-    "docs_src/pydantic_v1_in_v2/tutorial001_an_py39.py",
     "docs_src/pydantic_v1_in_v2/tutorial002_an_py310.py",
-    "docs_src/pydantic_v1_in_v2/tutorial002_an_py39.py",
     "docs_src/pydantic_v1_in_v2/tutorial003_an_py310.py",
-    "docs_src/pydantic_v1_in_v2/tutorial003_an_py39.py",
     "docs_src/pydantic_v1_in_v2/tutorial004_an_py310.py",
-    "docs_src/pydantic_v1_in_v2/tutorial004_an_py39.py",
-    # TODO: remove when removing this file, after updating translations, Pydantic v1
-    "docs_src/schema_extra_example/tutorial001_pv1_py310.py",
-    "docs_src/schema_extra_example/tutorial001_pv1_py39.py",
-    "docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py",
-    "docs_src/settings/app03_py39/config_pv1.py",
-    "docs_src/settings/app03_an_py39/config_pv1.py",
-    "docs_src/settings/tutorial001_pv1_py39.py",
+    # TODO: remove all the ignores below when all translations use the new Python 3.10 files
+    "docs_src/additional_responses/tutorial001_py39.py",
+    "docs_src/additional_responses/tutorial003_py39.py",
+    "docs_src/advanced_middleware/tutorial001_py39.py",
+    "docs_src/advanced_middleware/tutorial002_py39.py",
+    "docs_src/advanced_middleware/tutorial003_py39.py",
+    "docs_src/app_testing/app_a_py39/main.py",
+    "docs_src/app_testing/app_a_py39/test_main.py",
+    "docs_src/app_testing/tutorial001_py39.py",
+    "docs_src/app_testing/tutorial002_py39.py",
+    "docs_src/app_testing/tutorial003_py39.py",
+    "docs_src/app_testing/tutorial004_py39.py",
+    "docs_src/async_tests/app_a_py39/main.py",
+    "docs_src/async_tests/app_a_py39/test_main.py",
+    "docs_src/authentication_error_status_code/tutorial001_an_py39.py",
+    "docs_src/background_tasks/tutorial001_py39.py",
+    "docs_src/behind_a_proxy/tutorial001_01_py39.py",
+    "docs_src/behind_a_proxy/tutorial001_py39.py",
+    "docs_src/behind_a_proxy/tutorial002_py39.py",
+    "docs_src/behind_a_proxy/tutorial003_py39.py",
+    "docs_src/behind_a_proxy/tutorial004_py39.py",
+    "docs_src/bigger_applications/app_an_py39/dependencies.py",
+    "docs_src/bigger_applications/app_an_py39/internal/admin.py",
+    "docs_src/bigger_applications/app_an_py39/main.py",
+    "docs_src/bigger_applications/app_an_py39/routers/items.py",
+    "docs_src/bigger_applications/app_an_py39/routers/users.py",
+    "docs_src/bigger_applications/app_py39/dependencies.py",
+    "docs_src/bigger_applications/app_py39/main.py",
+    "docs_src/body_nested_models/tutorial008_py39.py",
+    "docs_src/body_nested_models/tutorial009_py39.py",
+    "docs_src/conditional_openapi/tutorial001_py39.py",
+    "docs_src/configure_swagger_ui/tutorial001_py39.py",
+    "docs_src/configure_swagger_ui/tutorial002_py39.py",
+    "docs_src/configure_swagger_ui/tutorial003_py39.py",
+    "docs_src/cors/tutorial001_py39.py",
+    "docs_src/custom_docs_ui/tutorial001_py39.py",
+    "docs_src/custom_docs_ui/tutorial002_py39.py",
+    "docs_src/custom_response/tutorial001_py39.py",
+    "docs_src/custom_response/tutorial001b_py39.py",
+    "docs_src/custom_response/tutorial002_py39.py",
+    "docs_src/custom_response/tutorial003_py39.py",
+    "docs_src/custom_response/tutorial004_py39.py",
+    "docs_src/custom_response/tutorial005_py39.py",
+    "docs_src/custom_response/tutorial006_py39.py",
+    "docs_src/custom_response/tutorial006b_py39.py",
+    "docs_src/custom_response/tutorial006c_py39.py",
+    "docs_src/custom_response/tutorial007_py39.py",
+    "docs_src/custom_response/tutorial008_py39.py",
+    "docs_src/custom_response/tutorial009_py39.py",
+    "docs_src/custom_response/tutorial009b_py39.py",
+    "docs_src/custom_response/tutorial009c_py39.py",
+    "docs_src/custom_response/tutorial010_py39.py",
+    "docs_src/debugging/tutorial001_py39.py",
+    "docs_src/dependencies/tutorial006_an_py39.py",
+    "docs_src/dependencies/tutorial006_py39.py",
+    "docs_src/dependencies/tutorial007_py39.py",
+    "docs_src/dependencies/tutorial008_py39.py",
+    "docs_src/dependencies/tutorial008b_an_py39.py",
+    "docs_src/dependencies/tutorial008b_py39.py",
+    "docs_src/dependencies/tutorial008c_an_py39.py",
+    "docs_src/dependencies/tutorial008c_py39.py",
+    "docs_src/dependencies/tutorial008d_an_py39.py",
+    "docs_src/dependencies/tutorial008d_py39.py",
+    "docs_src/dependencies/tutorial008e_an_py39.py",
+    "docs_src/dependencies/tutorial008e_py39.py",
+    "docs_src/dependencies/tutorial010_py39.py",
+    "docs_src/dependencies/tutorial011_an_py39.py",
+    "docs_src/dependencies/tutorial011_py39.py",
+    "docs_src/dependencies/tutorial012_an_py39.py",
+    "docs_src/dependencies/tutorial012_py39.py",
+    "docs_src/events/tutorial001_py39.py",
+    "docs_src/events/tutorial002_py39.py",
+    "docs_src/events/tutorial003_py39.py",
+    "docs_src/extending_openapi/tutorial001_py39.py",
+    "docs_src/extra_models/tutorial004_py39.py",
+    "docs_src/extra_models/tutorial005_py39.py",
+    "docs_src/first_steps/tutorial001_py39.py",
+    "docs_src/first_steps/tutorial003_py39.py",
+    "docs_src/generate_clients/tutorial001_py39.py",
+    "docs_src/generate_clients/tutorial002_py39.py",
+    "docs_src/generate_clients/tutorial003_py39.py",
+    "docs_src/generate_clients/tutorial004_py39.py",
+    "docs_src/graphql_/tutorial001_py39.py",
+    "docs_src/handling_errors/tutorial001_py39.py",
+    "docs_src/handling_errors/tutorial002_py39.py",
+    "docs_src/handling_errors/tutorial003_py39.py",
+    "docs_src/handling_errors/tutorial004_py39.py",
+    "docs_src/handling_errors/tutorial005_py39.py",
+    "docs_src/handling_errors/tutorial006_py39.py",
+    "docs_src/metadata/tutorial001_1_py39.py",
+    "docs_src/metadata/tutorial001_py39.py",
+    "docs_src/metadata/tutorial002_py39.py",
+    "docs_src/metadata/tutorial003_py39.py",
+    "docs_src/metadata/tutorial004_py39.py",
+    "docs_src/middleware/tutorial001_py39.py",
+    "docs_src/openapi_webhooks/tutorial001_py39.py",
+    "docs_src/path_operation_advanced_configuration/tutorial001_py39.py",
+    "docs_src/path_operation_advanced_configuration/tutorial002_py39.py",
+    "docs_src/path_operation_advanced_configuration/tutorial003_py39.py",
+    "docs_src/path_operation_advanced_configuration/tutorial005_py39.py",
+    "docs_src/path_operation_advanced_configuration/tutorial006_py39.py",
+    "docs_src/path_operation_advanced_configuration/tutorial007_py39.py",
+    "docs_src/path_operation_configuration/tutorial002b_py39.py",
+    "docs_src/path_operation_configuration/tutorial006_py39.py",
+    "docs_src/path_params/tutorial001_py39.py",
+    "docs_src/path_params/tutorial002_py39.py",
+    "docs_src/path_params/tutorial003_py39.py",
+    "docs_src/path_params/tutorial003b_py39.py",
+    "docs_src/path_params/tutorial004_py39.py",
+    "docs_src/path_params/tutorial005_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial002_an_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial002_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial003_an_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial003_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial004_an_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial004_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial005_an_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial005_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial006_an_py39.py",
+    "docs_src/path_params_numeric_validations/tutorial006_py39.py",
+    "docs_src/python_types/tutorial001_py39.py",
+    "docs_src/python_types/tutorial002_py39.py",
+    "docs_src/python_types/tutorial003_py39.py",
+    "docs_src/python_types/tutorial004_py39.py",
+    "docs_src/python_types/tutorial005_py39.py",
+    "docs_src/python_types/tutorial006_py39.py",
+    "docs_src/python_types/tutorial007_py39.py",
+    "docs_src/python_types/tutorial008_py39.py",
+    "docs_src/python_types/tutorial008b_py39.py",
+    "docs_src/python_types/tutorial009_py39.py",
+    "docs_src/python_types/tutorial009b_py39.py",
+    "docs_src/python_types/tutorial009c_py39.py",
+    "docs_src/python_types/tutorial010_py39.py",
+    "docs_src/python_types/tutorial013_py39.py",
+    "docs_src/query_params/tutorial001_py39.py",
+    "docs_src/query_params/tutorial005_py39.py",
+    "docs_src/query_params_str_validations/tutorial005_an_py39.py",
+    "docs_src/query_params_str_validations/tutorial005_py39.py",
+    "docs_src/query_params_str_validations/tutorial006_an_py39.py",
+    "docs_src/query_params_str_validations/tutorial006_py39.py",
+    "docs_src/query_params_str_validations/tutorial012_an_py39.py",
+    "docs_src/query_params_str_validations/tutorial012_py39.py",
+    "docs_src/query_params_str_validations/tutorial013_an_py39.py",
+    "docs_src/query_params_str_validations/tutorial013_py39.py",
+    "docs_src/request_files/tutorial001_03_an_py39.py",
+    "docs_src/request_files/tutorial001_03_py39.py",
+    "docs_src/request_files/tutorial001_an_py39.py",
+    "docs_src/request_files/tutorial001_py39.py",
+    "docs_src/request_files/tutorial002_an_py39.py",
+    "docs_src/request_files/tutorial002_py39.py",
+    "docs_src/request_files/tutorial003_an_py39.py",
+    "docs_src/request_files/tutorial003_py39.py",
+    "docs_src/request_form_models/tutorial001_an_py39.py",
+    "docs_src/request_form_models/tutorial001_py39.py",
+    "docs_src/request_form_models/tutorial002_an_py39.py",
+    "docs_src/request_form_models/tutorial002_py39.py",
+    "docs_src/request_forms/tutorial001_an_py39.py",
+    "docs_src/request_forms/tutorial001_py39.py",
+    "docs_src/request_forms_and_files/tutorial001_an_py39.py",
+    "docs_src/request_forms_and_files/tutorial001_py39.py",
+    "docs_src/response_change_status_code/tutorial001_py39.py",
+    "docs_src/response_cookies/tutorial001_py39.py",
+    "docs_src/response_cookies/tutorial002_py39.py",
+    "docs_src/response_directly/tutorial002_py39.py",
+    "docs_src/response_headers/tutorial001_py39.py",
+    "docs_src/response_headers/tutorial002_py39.py",
+    "docs_src/response_model/tutorial003_02_py39.py",
+    "docs_src/response_model/tutorial003_03_py39.py",
+    "docs_src/response_status_code/tutorial001_py39.py",
+    "docs_src/response_status_code/tutorial002_py39.py",
+    "docs_src/security/tutorial001_an_py39.py",
+    "docs_src/security/tutorial001_py39.py",
+    "docs_src/security/tutorial006_an_py39.py",
+    "docs_src/security/tutorial006_py39.py",
+    "docs_src/security/tutorial007_an_py39.py",
+    "docs_src/security/tutorial007_py39.py",
+    "docs_src/settings/app01_py39/config.py",
+    "docs_src/settings/app01_py39/main.py",
+    "docs_src/settings/app02_an_py39/config.py",
+    "docs_src/settings/app02_an_py39/main.py",
+    "docs_src/settings/app02_an_py39/test_main.py",
+    "docs_src/settings/app02_py39/config.py",
+    "docs_src/settings/app02_py39/main.py",
+    "docs_src/settings/app02_py39/test_main.py",
+    "docs_src/settings/app03_an_py39/config.py",
+    "docs_src/settings/app03_an_py39/main.py",
+    "docs_src/settings/app03_py39/config.py",
+    "docs_src/settings/app03_py39/main.py",
+    "docs_src/settings/tutorial001_py39.py",
+    "docs_src/static_files/tutorial001_py39.py",
+    "docs_src/sub_applications/tutorial001_py39.py",
+    "docs_src/templates/tutorial001_py39.py",
+    "docs_src/using_request_directly/tutorial001_py39.py",
+    "docs_src/websockets/tutorial001_py39.py",
+    "docs_src/websockets/tutorial003_py39.py",
+    "docs_src/wsgi/tutorial001_py39.py",
 ]
 
 [tool.coverage.report]
@@ -327,32 +512,42 @@ ignore = [
 
 [tool.ruff.lint.per-file-ignores]
 "__init__.py" = ["F401"]
+"docs_src/custom_request_and_route/tutorial002_an_py310.py" = ["B904"]
+"docs_src/custom_request_and_route/tutorial002_an_py39.py" = ["B904"]
+"docs_src/custom_request_and_route/tutorial002_py310.py" = ["B904"]
+"docs_src/custom_request_and_route/tutorial002_py39.py" = ["B904"]
+"docs_src/custom_response/tutorial007_py310.py" = ["B007"]
+"docs_src/custom_response/tutorial007_py39.py" = ["B007"]
+"docs_src/dataclasses/tutorial003_py39.py" = ["I001"]
+"docs_src/dependencies/tutorial007_py310.py" = ["F821"]
 "docs_src/dependencies/tutorial007_py39.py" = ["F821"]
+"docs_src/dependencies/tutorial008_an_py310.py" = ["F821"]
+"docs_src/dependencies/tutorial008_an_py39.py" = ["F821"]
+"docs_src/dependencies/tutorial008_py310.py" = ["F821"]
 "docs_src/dependencies/tutorial008_py39.py" = ["F821"]
+"docs_src/dependencies/tutorial008b_an_py310.py" = ["B904"]
+"docs_src/dependencies/tutorial008b_an_py39.py" = ["B904"]
+"docs_src/dependencies/tutorial008b_py310.py" = ["B904"]
+"docs_src/dependencies/tutorial008b_py39.py" = ["B904"]
+"docs_src/dependencies/tutorial009_py310.py" = ["F821"]
 "docs_src/dependencies/tutorial009_py39.py" = ["F821"]
+"docs_src/dependencies/tutorial010_py310.py" = ["F821"]
 "docs_src/dependencies/tutorial010_py39.py" = ["F821"]
-"docs_src/custom_response/tutorial007_py39.py" = ["B007"]
-"docs_src/dataclasses/tutorial003_py39.py" = ["I001"]
-"docs_src/path_operation_advanced_configuration/tutorial007_py39.py" = ["B904"]
 "docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py" = ["B904"]
-"docs_src/custom_request_and_route/tutorial002_py39.py" = ["B904"]
-"docs_src/custom_request_and_route/tutorial002_py310.py" = ["B904"]
-"docs_src/custom_request_and_route/tutorial002_an_py39.py" = ["B904"]
-"docs_src/custom_request_and_route/tutorial002_an_py310.py" = ["B904"]
-"docs_src/dependencies/tutorial008_an_py39.py" = ["F821"]
+"docs_src/path_operation_advanced_configuration/tutorial007_py310.py" = ["B904"]
+"docs_src/path_operation_advanced_configuration/tutorial007_py39.py" = ["B904"]
+"docs_src/query_params_str_validations/tutorial012_an_py310.py" = ["B006"]
 "docs_src/query_params_str_validations/tutorial012_an_py39.py" = ["B006"]
+"docs_src/query_params_str_validations/tutorial013_an_py310.py" = ["B006"]
 "docs_src/query_params_str_validations/tutorial013_an_py39.py" = ["B006"]
-"docs_src/security/tutorial004_py39.py" = ["B904"]
-"docs_src/security/tutorial004_an_py39.py" = ["B904"]
 "docs_src/security/tutorial004_an_py310.py" = ["B904"]
+"docs_src/security/tutorial004_an_py39.py" = ["B904"]
 "docs_src/security/tutorial004_py310.py" = ["B904"]
+"docs_src/security/tutorial004_py39.py" = ["B904"]
 "docs_src/security/tutorial005_an_py310.py" = ["B904"]
 "docs_src/security/tutorial005_an_py39.py" = ["B904"]
 "docs_src/security/tutorial005_py310.py" = ["B904"]
 "docs_src/security/tutorial005_py39.py" = ["B904"]
-"docs_src/dependencies/tutorial008b_py39.py" = ["B904"]
-"docs_src/dependencies/tutorial008b_an_py39.py" = ["B904"]
-
 
 [tool.ruff.lint.isort]
 known-third-party = ["fastapi", "pydantic", "starlette"]
index d8d9d4130b3e229804e828bd0097ba7845a25037..456070c9c3edc60b8871c837bae6ef90a74951db 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.additional_responses.tutorial001_py39 import app
+from docs_src.additional_responses.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 4fae59d22295ff868cd48397884031f22f6478be..586779e44f6e4265b6508548647364394d9650e7 100644 (file)
@@ -12,7 +12,6 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index e888819dfe677f206327bfb8d6f54d78d3a796a4..56eeacb605104db853a64b6f4b20030f434c6eb6 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.additional_responses.tutorial003_py39 import app
+from docs_src.additional_responses.tutorial003_py310 import app
 
 client = TestClient(app)
 
index 9df326a5ced77b5789facb6bc3cccd9e2c9ef1a9..fe56fbb8b5bb2ff5f30f0e15582fcb07e7f4cbc6 100644 (file)
@@ -12,7 +12,6 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index bced1f6dfe29a0cad73dfa944d861eadeb4b198e..f57ea2bcf2eddd645a6ecbfb92109d919888ebf3 100644 (file)
@@ -9,9 +9,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index f17391956eb92bbd5923e1ade0af134f6832b49f..6231cf4cb1852490091defb53b5693c0acf84e22 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.advanced_middleware.tutorial001_py39 import app
+from docs_src.advanced_middleware.tutorial001_py310 import app
 
 
 def test_middleware():
index bae915406e72c8f1a48577685883de9417658942..fa8ac41d790176649f2dcf44f58b7618b2231549 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.advanced_middleware.tutorial002_py39 import app
+from docs_src.advanced_middleware.tutorial002_py310 import app
 
 
 def test_middleware():
index 66697997c8459b2c58f9ca13746dff27d235f5a1..8602e1569774c983ec6c96cb6ed6001d81255e19 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.responses import PlainTextResponse
 from fastapi.testclient import TestClient
 
-from docs_src.advanced_middleware.tutorial003_py39 import app
+from docs_src.advanced_middleware.tutorial003_py310 import app
 
 
 @app.get("/large")
index f29acaa9a0a8def7906cf5ed30d14c3c50f7b0be..4e33692d0c86e641f4b4e35f3f96d4d421a7d8da 100644 (file)
@@ -1,6 +1,6 @@
 import pytest
 
-from docs_src.async_tests.app_a_py39.test_main import test_root
+from docs_src.async_tests.app_a_py310.test_main import test_root
 
 
 @pytest.mark.anyio
index 6f58116313c557a6cd32454076307b0919df00cf..7e1588d676e114c451fc47ecd83ed476d6671302 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_an_py39",
+        "tutorial001_an_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index c0ad27a6f566c2b4570479f7a6320b1dd4cc66a5..100583f77aa615847c8f524a4781c8517df57e7d 100644 (file)
@@ -3,7 +3,7 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.background_tasks.tutorial001_py39 import app
+from docs_src.background_tasks.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 288a1c244e22f1dd80a741bfaaeb1f2bc613b7a9..f29402c8334f69a1c12355a71b9ffa25c0545e6b 100644 (file)
@@ -11,9 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002_py39",
         pytest.param("tutorial002_py310", marks=needs_py310),
-        "tutorial002_an_py39",
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 31adaa56a62c9881650cc7b2fdd5d564b781ea0b..38ae460fbe256edac98864d43ba16c84593c0951 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.behind_a_proxy.tutorial001_py39 import app
+from docs_src.behind_a_proxy.tutorial001_py310 import app
 
 client = TestClient(app, root_path="/api/v1")
 
index da4acb28cc6cac721939f657c354d098f332981a..190b33c50f8bc6fac37c92deca5a64d20e375655 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.behind_a_proxy.tutorial001_01_py39 import app
+from docs_src.behind_a_proxy.tutorial001_01_py310 import app
 
 client = TestClient(
     app,
index 56e6f2f9d269b56d92755c62a65e8d88d0f85013..c9356a51303117ce0b3a57c9ea4838e5407cd59b 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.behind_a_proxy.tutorial002_py39 import app
+from docs_src.behind_a_proxy.tutorial002_py310 import app
 
 client = TestClient(app)
 
index a164bb80b556b30984e45de4ab3d81f7f3c44687..d74da5b73eb305a11a40ba70b7a9c03b81be1786 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.behind_a_proxy.tutorial003_py39 import app
+from docs_src.behind_a_proxy.tutorial003_py310 import app
 
 client = TestClient(app)
 
index 01bba9feddaeebff2e9759d9286fcfae31fe7ab8..f5e27c1183edc062f750784c35a09fd066353be7 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.behind_a_proxy.tutorial004_py39 import app
+from docs_src.behind_a_proxy.tutorial004_py310 import app
 
 client = TestClient(app)
 
index 18845e4702098852475c549d4fc4ac4266af2565..abe008d9e223e3bfc8c85b2a3819278769fb2b6d 100644 (file)
@@ -8,8 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "app_py39.main",
-        "app_an_py39.main",
+        "app_an_py310.main",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index c1877a72ef5b9f8b8cea4987532166c9163f8b0e..bdabf8d68b3c35df6a625ab02fcedbc9b799427b 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 94bf213e3fd6bd0952c06d9eb45d564705a474f9..f1e1236c99d53297f1ab77ae8e46b8b04d468bca 100644 (file)
@@ -1,5 +1,4 @@
 import importlib
-from typing import Union
 
 import pytest
 from fastapi.testclient import TestClient
@@ -11,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
@@ -23,7 +21,7 @@ def get_client(request: pytest.FixtureRequest):
 
 
 @pytest.mark.parametrize("price", ["50.5", 50.5])
-def test_post_with_tax(client: TestClient, price: Union[str, float]):
+def test_post_with_tax(client: TestClient, price: str | float):
     response = client.post(
         "/items/",
         json={"name": "Foo", "price": price, "description": "Some Foo", "tax": 0.3},
@@ -39,7 +37,7 @@ def test_post_with_tax(client: TestClient, price: Union[str, float]):
 
 
 @pytest.mark.parametrize("price", ["50.5", 50.5])
-def test_post_without_tax(client: TestClient, price: Union[str, float]):
+def test_post_without_tax(client: TestClient, price: str | float):
     response = client.post(
         "/items/", json={"name": "Foo", "price": price, "description": "Some Foo"}
     )
index 832c211f6694a84032bc609eed3a905e72994377..b4767cf28566bb0d58a7f8de3fd2a2e7431bb37f 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index 1019a168cff965eb707b38fd816b20f3777b0122..f0a50a64c66bb150e32a93a3d3fd1d6fa9cde7ff 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index 0116dcb09c9db76461a5661b63404f4f5a5aa7c3..eb94d24cdaef14eeafc5c7fdd1d8d964ee568bd5 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 2e8ba457bed1018f61ec941840ceb624bf90c8df..f510f1c1563846fddb4f1ee46ef53de990b9395d 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 0c94e9dd1ebc7a9793757d6aeff295ec46bdac77..b23402c3cbe53a0b3bc0e741620cdd06f4a3c031 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index c27f3d5ba8fafe9ffd16df81e161c711b1db8555..89fabd3ba25e99786a044c9d5493989fc33ee102 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003_py39",
         pytest.param("tutorial003_py310", marks=needs_py310),
-        "tutorial003_an_py39",
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index 2a39f3d7136e326be1781c91f5468d0d502cbbf3..c5b4b452d55cdbfc61497e90a11cf5e9b371df8a 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
-        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
     ],
 )
index d600e0767ddef5ac1ade772aa3035137361430b6..b8fc98cd7e092cd8618009af7b820f34970b43dc 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
-        pytest.param("tutorial005_an_py39"),
         pytest.param("tutorial005_an_py310", marks=needs_py310),
     ],
 )
index 18bce279b9d310a6cee51d6eb000da2ac3c31178..2e2f329f7937af7b048c787bc9de55447c5e91c8 100644 (file)
@@ -17,11 +17,8 @@ SET_OF_STR_SCHEMA = {"type": "array", "items": {"type": "string"}, "uniqueItems"
 @pytest.fixture(
     name="mod_name",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index 6a70779b6834d607662c9045b984254b4b3be0e6..4605a757d4a17bb0f099d6b4479e3ccd129035ef 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index 2ff3d4f220fc3aa7d6270d30a84f5a7f84076382..ffa02cd65f3cf8969baa08cd64f5fba61699353c 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
     ],
 )
index 229216fc58b996653dcb0676c9596388410a7ed5..4551a72b316806c66e96d0883ebda54dacfedc91 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006_py39"),
         pytest.param("tutorial006_py310", marks=needs_py310),
     ],
 )
index 5a7763f598ff27d3086f77ad2537d1d2a6b3e316..5b99b41b6a85ce75d851b2971799f2bc706a941d 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial007_py39"),
         pytest.param("tutorial007_py310", marks=needs_py310),
     ],
 )
index 26f48f1d5fb0cacb7833a0b2313d9a4e75a8e8b3..d038805bd74c77559967a999f6c84677baa21ff9 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial008_py39"),
+        pytest.param("tutorial008_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 492dcecd2b603b1faba51fea7d5f5a5278cb7aee..a747e2a64c5b03ff1a6da47ad3c56dd3c6d72740 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial009_py39",
+        "tutorial009_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index feb07b85959818c18d37751c370a744f09d7c1c7..ba8d7baf3301fffd7338968bf5af657bb7a28182 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index a34d08b52bce3c2e9681d4185beca09c7f61d2c2..cf0ee7ada462d4052e228a8d77d11892327973c1 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index 644b82ad9a9e04f79c8687a303d6c52cf2cd82f6..a7aa9dbe27ea435fbff46c3c012c6374734660d6 100644 (file)
@@ -5,11 +5,11 @@ from inline_snapshot import snapshot
 
 
 def get_client() -> TestClient:
-    from docs_src.conditional_openapi import tutorial001_py39
+    from docs_src.conditional_openapi import tutorial001_py310
 
-    importlib.reload(tutorial001_py39)
+    importlib.reload(tutorial001_py310)
 
-    client = TestClient(tutorial001_py39.app)
+    client = TestClient(tutorial001_py310.app)
     return client
 
 
index 1fa9419a7670f4435d865190352ab9319b4ef482..e2f1fbf907556a81b653facf4f435a3b29959175 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.configure_swagger_ui.tutorial001_py39 import app
+from docs_src.configure_swagger_ui.tutorial001_py310 import app
 
 client = TestClient(app)
 
index c218cc858cac57bd013f940780ac134881fb3729..ce1cb4bace1b3622b56cffe65620591263794757 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.configure_swagger_ui.tutorial002_py39 import app
+from docs_src.configure_swagger_ui.tutorial002_py310 import app
 
 client = TestClient(app)
 
index 8b73685499a5a8a351509afc4efee839216a3b6c..6f28e77341c0b4e3109e8069596657d22b4867cb 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.configure_swagger_ui.tutorial003_py39 import app
+from docs_src.configure_swagger_ui.tutorial003_py310 import app
 
 client = TestClient(app)
 
index f391c569a84ac220fb4f4c0110067eb3d80f7f74..c4de7ad450b871ba0126dd3d63e6dadbbad470f2 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 6583045dc8ef902b594802b915e4565c0ee26c50..37be0f1ddbc07e3b24af6419c9079739eb731af2 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=[needs_py310]),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=[needs_py310]),
     ],
 )
index 4d7adf0d608bc928016722188f6c8427d3329804..db0765ea51fa082ab8b2c6da312c741f4473c917 100644 (file)
@@ -11,9 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="mod",
     params=[
-        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 6a733693aed4eb3aa44dbc34b789c33c96813b22..428378cd44331fbf741129b0c4d567f5b0da929d 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.cors.tutorial001_py39 import app
+from docs_src.cors.tutorial001_py310 import app
 
 
 def test_cors():
index 1816e5d975f6d788392c1cdad0f691920ae56122..f7eb7fd97dbbf1f571d270cba07754e3390bca78 100644 (file)
@@ -10,7 +10,7 @@ def client():
     static_dir: Path = Path(os.getcwd()) / "static"
     print(static_dir)
     static_dir.mkdir(exist_ok=True)
-    from docs_src.custom_docs_ui.tutorial001_py39 import app
+    from docs_src.custom_docs_ui.tutorial001_py310 import app
 
     with TestClient(app) as client:
         yield client
index e8b7eb7aa32b8fd9c74bce4df125f508eb63909f..28945d8387f9ff9fccece03c1fc01e9b9a123ecd 100644 (file)
@@ -10,7 +10,7 @@ def client():
     static_dir: Path = Path(os.getcwd()) / "static"
     print(static_dir)
     static_dir.mkdir(exist_ok=True)
-    from docs_src.custom_docs_ui.tutorial002_py39 import app
+    from docs_src.custom_docs_ui.tutorial002_py310 import app
 
     with TestClient(app) as client:
         yield client
index b4ea537846c717efbe0523cb734f7ccab2f47a41..39d3bd40653f7bfe80ae034480df21d224f8b6e9 100644 (file)
@@ -12,9 +12,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index a9c7ae638be50827f478fb960da59b4ebc515acb..746d6c9d2fbb5a65e544c81e35699392a6dd31a1 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 6cad7bd3f0287d6bb73bbc030092906dc614af3c..c11ea12590ed3e8cbc34feb23c12c931d6fe2b38 100644 (file)
@@ -9,7 +9,6 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index 20244bef450b4b27cce61f6600478019fae1b4ae..a5fe4c8f4c014b2d4ca12cc068f684dd6099046d 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
-        pytest.param("tutorial010_py39"),
+        pytest.param("tutorial001_py310"),
+        pytest.param("tutorial010_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 746801df16ac138024d648a7909caa10e70cfc06..32437db86b757f558dad2ee7cfc807e6d4adcad2 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.custom_response.tutorial001b_py39 import app
+from docs_src.custom_response.tutorial001b_py310 import app
 
 client = TestClient(app)
 
index 68e046ac5aea84a991996ee5a611ea10fbf413a9..42fd85583c76373f334119e7733452c9441a92b0 100644 (file)
@@ -8,9 +8,9 @@ from inline_snapshot import Is, snapshot
 @pytest.fixture(
     name="mod_name",
     params=[
-        pytest.param("tutorial002_py39"),
-        pytest.param("tutorial003_py39"),
-        pytest.param("tutorial004_py39"),
+        pytest.param("tutorial002_py310"),
+        pytest.param("tutorial003_py310"),
+        pytest.param("tutorial004_py310"),
     ],
 )
 def get_mod_name(request: pytest.FixtureRequest) -> str:
index b4919af6c3372a4ecfd00fcc3a2e3eb3f682e00d..297e4882255e7e6359d10ee9aeeb132ccbea36c7 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.custom_response.tutorial005_py39 import app
+from docs_src.custom_response.tutorial005_py310 import app
 
 client = TestClient(app)
 
index ea2d366aa06d0ff71b00220434fc071789ec242f..4365090c27a565650a2b661c28bb458733a7f105 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.custom_response.tutorial006_py39 import app
+from docs_src.custom_response.tutorial006_py310 import app
 
 client = TestClient(app)
 
index 133a591b16df21975444db99d22286ce1fb034df..a776188471172420b833fb9b715f51c42f20002a 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.custom_response.tutorial006b_py39 import app
+from docs_src.custom_response.tutorial006b_py310 import app
 
 client = TestClient(app)
 
index 5b17d815d0ce577490c49c7500b25ffc16208084..f29bda2c298f18bca4e62f90b82ea14df532cb8f 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.custom_response.tutorial006c_py39 import app
+from docs_src.custom_response.tutorial006c_py310 import app
 
 client = TestClient(app)
 
index a62476ec14392b61aee7b62026fe6e538a86bb62..5f2e233f8b3d6fcede5d3a517c7f15f7cd0496fa 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial007_py39 import app
+from docs_src.custom_response.tutorial007_py310 import app
 
 client = TestClient(app)
 
index d9fe61f5391973a085025a0606a81448bcb7d6af..1be7c1a622619fec96521f99466fa4639b93db4a 100644 (file)
@@ -2,15 +2,15 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response import tutorial008_py39
-from docs_src.custom_response.tutorial008_py39 import app
+from docs_src.custom_response import tutorial008_py310
+from docs_src.custom_response.tutorial008_py310 import app
 
 client = TestClient(app)
 
 
 def test_get(tmp_path: Path):
     file_path: Path = tmp_path / "large-video-file.mp4"
-    tutorial008_py39.some_file_path = str(file_path)
+    tutorial008_py310.some_file_path = str(file_path)
     test_content = b"Fake video bytes"
     file_path.write_bytes(test_content)
     response = client.get("/")
index cb6a514be6c2ea119c9731d41717c79834bc34ee..a6564d55163558657fa7ac9f83b7e473bf4f501e 100644 (file)
@@ -2,15 +2,15 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response import tutorial009_py39
-from docs_src.custom_response.tutorial009_py39 import app
+from docs_src.custom_response import tutorial009_py310
+from docs_src.custom_response.tutorial009_py310 import app
 
 client = TestClient(app)
 
 
 def test_get(tmp_path: Path):
     file_path: Path = tmp_path / "large-video-file.mp4"
-    tutorial009_py39.some_file_path = str(file_path)
+    tutorial009_py310.some_file_path = str(file_path)
     test_content = b"Fake video bytes"
     file_path.write_bytes(test_content)
     response = client.get("/")
index 9918bdb1aca0f773310b082679a11a65105df5bf..05ac62f3d0d2b09ec00580dfcd77cbcaf58ef02e 100644 (file)
@@ -2,15 +2,15 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response import tutorial009b_py39
-from docs_src.custom_response.tutorial009b_py39 import app
+from docs_src.custom_response import tutorial009b_py310
+from docs_src.custom_response.tutorial009b_py310 import app
 
 client = TestClient(app)
 
 
 def test_get(tmp_path: Path):
     file_path: Path = tmp_path / "large-video-file.mp4"
-    tutorial009b_py39.some_file_path = str(file_path)
+    tutorial009b_py310.some_file_path = str(file_path)
     test_content = b"Fake video bytes"
     file_path.write_bytes(test_content)
     response = client.get("/")
index efc3a6b4a026922011344ade12e22204a2eb37d5..7a1b713079b9e87a2b8cdae093912b87e92535e4 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial009c_py39 import app
+from docs_src.custom_response.tutorial009c_py310 import app
 
 client = TestClient(app)
 
index a3d2cf515279f070f12b3a7f5b131a3a460f7256..62de135dcd5f83060c2b6caf7a128d87ac42bb5b 100644 (file)
@@ -10,7 +10,6 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 210d743bb861fbe35ce416e4829433b5532d90e6..f6607c8e02107ec8c024d946809ec760907afae5 100644 (file)
@@ -10,7 +10,6 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index e023271bc3b55f38d395282734141ef0250b9e92..5a35e5c4a8dc969c22039297fa830d56f5af866f 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index 1a0ca6cad7b1ceb6e793f89d638d300aef439cb3..fbf2bfa025560b9618d5cce720204393f9c71faa 100644 (file)
@@ -7,7 +7,7 @@ import pytest
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-MOD_NAME = "docs_src.debugging.tutorial001_py39"
+MOD_NAME = "docs_src.debugging.tutorial001_py310"
 
 
 @pytest.fixture(name="client")
index 74f4a8f3a2f2159f2416ebb5baefbdf79e84741a..11e732e6deb5aeb84a7d9f3871d110231c988f1f 100644 (file)
@@ -10,11 +10,8 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
-        pytest.param("tutorial001_02_an_py39"),
         pytest.param("tutorial001_02_an_py310", marks=needs_py310),
     ],
 )
index 6e1cea5a0838ff58f4a65e36474dea0a9f43aa52..a9ddf8a52161439e817a899d9336eb863b205ab8 100644 (file)
@@ -10,17 +10,11 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
-        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
     ],
 )
index 31054744a1adc8130d299f95d02919404b902f03..3cd083b351e164cbc4fea378020d4aeabe5b5b27 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
-        pytest.param("tutorial005_an_py39"),
         pytest.param("tutorial005_an_py310", marks=needs_py310),
     ],
 )
index 8d6cfa2d651aae2ca67c77fd51a026f53f390d7e..f6e6f8368573ec79a379bea1a04a8dd59c33a038 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006_py39"),
-        pytest.param("tutorial006_an_py39"),
+        pytest.param("tutorial006_py310"),
+        pytest.param("tutorial006_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 3e188abcf68a39bc02464eefb4f86c351a8cd4d9..c9848561170282048cb124b3df16063d8b95422d 100644 (file)
@@ -2,7 +2,7 @@ import asyncio
 from contextlib import asynccontextmanager
 from unittest.mock import Mock, patch
 
-from docs_src.dependencies.tutorial007_py39 import get_db
+from docs_src.dependencies.tutorial007_py310 import get_db
 
 
 def test_get_db():  # Just for coverage
@@ -14,7 +14,7 @@ def test_get_db():  # Just for coverage
     dbsession_moock = Mock()
 
     with patch(
-        "docs_src.dependencies.tutorial007_py39.DBSession",
+        "docs_src.dependencies.tutorial007_py310.DBSession",
         return_value=dbsession_moock,
         create=True,
     ):
index 5a2d226bffb557e61ddb36af0977dde677d5f983..e23ac0ac5185d56b49d40cd85788b8c87f3e7b1c 100644 (file)
@@ -12,9 +12,9 @@ from fastapi.testclient import TestClient
 @pytest.fixture(
     name="module",
     params=[
-        "tutorial008_py39",
+        "tutorial008_py310",
         pytest.param(
-            "tutorial008_an_py39",
+            "tutorial008_an_py310",
             marks=pytest.mark.xfail(
                 sys.version_info < (3, 14),
                 reason="Fails with `NameError: name 'DepA' is not defined`",
index 91e00b37055f7e89e9d21ac34ad3eddf0a95d35b..d2493d0cce2da61c3685bb0a697b62056a1248bf 100644 (file)
@@ -7,8 +7,8 @@ from fastapi.testclient import TestClient
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial008b_py39"),
-        pytest.param("tutorial008b_an_py39"),
+        pytest.param("tutorial008b_py310"),
+        pytest.param("tutorial008b_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index aede6f8d25c4e11d8d1a05889d3e4b8114d883e9..b7713c73b5cda2b8f0b7d0fdc331e3e9acad9be0 100644 (file)
@@ -9,8 +9,8 @@ from fastapi.testclient import TestClient
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial008c_py39"),
-        pytest.param("tutorial008c_an_py39"),
+        pytest.param("tutorial008c_py310"),
+        pytest.param("tutorial008c_an_py310"),
     ],
 )
 def get_mod(request: pytest.FixtureRequest):
index 5477f8b95316048f2b1613194b6e11e455c06519..e831c055ecc2f4ba727bc2ce3cfe9142d4ab46ca 100644 (file)
@@ -8,8 +8,8 @@ from fastapi.testclient import TestClient
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial008d_py39"),
-        pytest.param("tutorial008d_an_py39"),
+        pytest.param("tutorial008d_py310"),
+        pytest.param("tutorial008d_an_py310"),
     ],
 )
 def get_mod(request: pytest.FixtureRequest):
index c433157ea1768e45aa4e999c49a1496b796997eb..18eba9f7756df772be4d29b184580106a22dd6e9 100644 (file)
@@ -7,8 +7,8 @@ from fastapi.testclient import TestClient
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial008e_py39"),
-        pytest.param("tutorial008e_an_py39"),
+        pytest.param("tutorial008e_py310"),
+        pytest.param("tutorial008e_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 6d3815ada2d83622948ef0ebc206a6f45886c101..954d09f20d4d829e1c7e92ec4f8a33f20ea357d4 100644 (file)
@@ -4,7 +4,7 @@ from unittest.mock import Mock, patch
 from fastapi import Depends, FastAPI
 from fastapi.testclient import TestClient
 
-from docs_src.dependencies.tutorial010_py39 import get_db
+from docs_src.dependencies.tutorial010_py310 import get_db
 
 
 def test_get_db():
@@ -19,7 +19,7 @@ def test_get_db():
     dbsession_mock = Mock()
 
     with patch(
-        "docs_src.dependencies.tutorial010_py39.DBSession",
+        "docs_src.dependencies.tutorial010_py310.DBSession",
         return_value=dbsession_mock,
         create=True,
     ):
index 383422a7e62c35fcdc9e0435b1a276630ffc09b2..16167fd2e0d0880d11a36c939701942e86912ad5 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial011_py39",
-        pytest.param("tutorial011_an_py39"),
+        "tutorial011_py310",
+        pytest.param("tutorial011_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index a15688924572c366b886abec783ced72219e4247..e0148e05214b76364f396f5a2b4c0325042a85df 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial012_py39"),
-        pytest.param("tutorial012_an_py39"),
+        pytest.param("tutorial012_py310"),
+        pytest.param("tutorial012_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index a3d67233366816201b486ad51b701883c37a1799..e8c1f3c73f98f832ab530b45878556d849fa81ce 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 63215c00dbacf1ac48a7b4cfa7b0e1fa6262d197..e392cdcc909001f54404434101a87abee45dc518 100644 (file)
@@ -7,7 +7,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(name="app", scope="module")
 def get_app():
     with pytest.warns(DeprecationWarning):
-        from docs_src.events.tutorial001_py39 import app
+        from docs_src.events.tutorial001_py310 import app
     yield app
 
 
index f98d8921f763d919ade1689df89ca9a89b688df4..47af7a9527b59a0ded0edf245739a8940ca30896 100644 (file)
@@ -7,7 +7,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(name="app", scope="module")
 def get_app():
     with pytest.warns(DeprecationWarning):
-        from docs_src.events.tutorial002_py39 import app
+        from docs_src.events.tutorial002_py310 import app
     yield app
 
 
index 4fc848e1166a1311b337ec5d47ad6656bcf5b5f1..3da0b2ca526373522899a4af3c118d42e7c66a7e 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.events.tutorial003_py39 import (
+from docs_src.events.tutorial003_py310 import (
     app,
     fake_answer_to_everything_ml_model,
     ml_models,
index bc10c888c14ef7d9e048643d9557761981d19297..06c56565f66937bca6d7c83376637e7ba8a76d4d 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.extending_openapi.tutorial001_py39 import app
+from docs_src.extending_openapi.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 28fe68f285fa90fec9ee1209a56f9857c0f8d1f4..2e7f0e522e0a6a565c3869cc8fda4a24dcc75956 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 4248878b5a25e6ca7dea0e2725c8e6935793d97d..4fcb7ff78b1f79809a9402e2959af549726df3fc 100644 (file)
@@ -11,9 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index 38e87415822c77b305836839d61a03bef18b6f31..2a2cf8afaebacf935af53a37d96cac7a0799b6de 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index c64371e3bee8067d93b7abaca72e2bf6772e6bbf..3ded20959ac3c6bfa7e470ba9406450f1b31dfab 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
+        pytest.param("tutorial004_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 43b8bae8e543b6cfd7b82179ca8636d69ff7e6ea..265b768326209f275a987f160ad0fb94ecff026c 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
+        pytest.param("tutorial005_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 5457ad132a3028e69e02edecc7fd677bf6673e91..30eab21e933703d743f363dfc190b4900411b1b5 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
-        "tutorial003_py39",
+        "tutorial001_py310",
+        "tutorial003_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 62799d259b50df7a6bb831c897fd05536b99b014..40ed3eeea22c5f0f3228b6718ef0de2ba6c551e8 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
+        pytest.param("tutorial001_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index f64f5f8666ec3ca96674eb2422a3d2684ee3cf78..6557b8c2754c90ce8af4cca17f486e35f6b28f34 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.generate_clients.tutorial002_py39 import app
+from docs_src.generate_clients.tutorial002_py310 import app
 
 client = TestClient(app)
 
index 34ede61946f1e5caa66ae07b458176ad37dc252f..cded241ae1179da5b75abdf7997a76121c658344 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.generate_clients.tutorial003_py39 import app
+from docs_src.generate_clients.tutorial003_py310 import app
 
 client = TestClient(app)
 
index d04bfbfe877f60bc5f8a220a6ff4364b8979fced..1d71de869f1667bbb0a6659c1f0e02ed8d26e064 100644 (file)
@@ -5,16 +5,16 @@ from unittest.mock import patch
 
 from inline_snapshot import snapshot
 
-from docs_src.generate_clients import tutorial003_py39
+from docs_src.generate_clients import tutorial003_py310
 
 
 def test_remove_tags(tmp_path: pathlib.Path):
     tmp_file = tmp_path / "openapi.json"
-    openapi_json = tutorial003_py39.app.openapi()
+    openapi_json = tutorial003_py310.app.openapi()
     tmp_file.write_text(json.dumps(openapi_json))
 
     with patch("pathlib.Path", return_value=tmp_file):
-        importlib.import_module("docs_src.generate_clients.tutorial004_py39")
+        importlib.import_module("docs_src.generate_clients.tutorial004_py310")
 
     modified_openapi = json.loads(tmp_file.read_text())
     assert modified_openapi == snapshot(
index cc3be6a1905b0b1afb56ee4a1082b310ac78db22..c9334708140f3589e7d873d6f3c5868d416e5fab 100644 (file)
@@ -10,7 +10,7 @@ warnings.filterwarnings(
     category=DeprecationWarning,
 )
 
-from docs_src.graphql_.tutorial001_py39 import app  # noqa: E402
+from docs_src.graphql_.tutorial001_py310 import app  # noqa: E402
 
 
 @pytest.fixture(name="client")
index 8283cdc73ed17276dc3da7d2d8fc608bc2d1536d..001a02a0fde649f01ec6f87c224ac615bb4eba0a 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.handling_errors.tutorial001_py39 import app
+from docs_src.handling_errors.tutorial001_py310 import app
 
 client = TestClient(app)
 
index c437693d3d1ea0da928a2a4a77f4271b869dd947..0e7321ee7ced6c7ac94daee5dc09c14660217237 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.handling_errors.tutorial002_py39 import app
+from docs_src.handling_errors.tutorial002_py310 import app
 
 client = TestClient(app)
 
index 959729e53f804cc45e03d4f0f53d30c27c75a574..cc11985be18afeefcf296212862799e35ead220f 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.handling_errors.tutorial003_py39 import app
+from docs_src.handling_errors.tutorial003_py310 import app
 
 client = TestClient(app)
 
index 16165bb3d35aae7a8e744acbc9b939f8c164541e..5471cb0d82b208aff4282e2ba450a70375bbb2e6 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.handling_errors.tutorial004_py39 import app
+from docs_src.handling_errors.tutorial004_py310 import app
 
 client = TestClient(app)
 
index af924a9f76d858fd4fa771aedcd84ad6ce4aa064..c04b510c39cec0c5d03aa89e9e7770cbf287903e 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.handling_errors.tutorial005_py39 import app
+from docs_src.handling_errors.tutorial005_py310 import app
 
 client = TestClient(app)
 
index 4c069d81e23903de4ad8b4c4d4481e4d38d5c732..666e44f3a83e5b483662b0844de76e77a2b6fbfd 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.handling_errors.tutorial006_py39 import app
+from docs_src.handling_errors.tutorial006_py310 import app
 
 client = TestClient(app)
 
index 2d14c698e0f1d3b4b31148d5d5ea6e6c1db7771e..8391bd1197da8fb29fb86a5f4ef5b44bdb428519 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 478ac8408777fead460fd516558ecaeb4a21909f..3d66dca08d33a14370773fcca59ddc06b0bad487 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=[needs_py310]),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=[needs_py310]),
     ],
 )
index 00636c2b533792acef3f2b2a9e660261d733109f..7d0da24fd57912eb7e4e5103805a7d2870933a0e 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index 2e97a832217a95a1846f632c2a8ef236d00c3e48..900d35adc5fe021e15aab86048c7d74ec2f4d21e 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index ba86c55bf693abb81a1ea3eec5d2c8fbf621e0a6..c756eae71f81f2d98495cf7866403fb4812e830f 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 30e5133c01d0bb00b082865094939cd33420d183..1f71322b697eb86f07a8bddc058bf4e07e82a07c 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index ba3c09ce4cea071cf0a9923158d7f71e087e4483..ce0c1643a9dd539308ba0a02544783570935511a 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.metadata.tutorial001_py39 import app
+from docs_src.metadata.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 9339549731055da700e3195ce65c012f01b43ce1..ba9ba9dcbc51b209014d7fff0756befd09096d7e 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.metadata.tutorial001_1_py39 import app
+from docs_src.metadata.tutorial001_1_py310 import app
 
 client = TestClient(app)
 
index 5a252475eb49c213fd129180ff9f2ad973aed0e8..979a6a7b84a87a14176796127c6aea79c330c826 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.metadata.tutorial002_py39 import app
+from docs_src.metadata.tutorial002_py310 import app
 
 client = TestClient(app)
 
index 778781e6653d67086bc10010401b49b549901a64..ee297802889a4538b61436185c158368771cf40e 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.metadata.tutorial003_py39 import app
+from docs_src.metadata.tutorial003_py310 import app
 
 client = TestClient(app)
 
index 5c309a830ed733a1884ddcba9f9f294e55ba4fba..ef0533d50695158a6f7e3a6d1b4f7bdb4745f301 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.metadata.tutorial004_py39 import app
+from docs_src.metadata.tutorial004_py310 import app
 
 client = TestClient(app)
 
index 18047f3430ed2049e5d168a736a2d941639951df..1fa1e5a5073e2d1430665fea88f18fdbb4117137 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.middleware.tutorial001_py39 import app
+from docs_src.middleware.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 1e937d0c90517f714796ddd081e3f4557ec77f33..62374ef270bb4db61822061876f4f4e6bba0a174 100644 (file)
@@ -11,7 +11,6 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 0482c94bf96683af4698277e189f5b92e43f49a5..696a2bed535b3804b8cae52d9f54157fe8f7ffe2 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.openapi_webhooks.tutorial001_py39 import app
+from docs_src.openapi_webhooks.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 3a4f648241123c7a1de1935f862ac14a7a3ed4a5..ecda8a315313ea7b4c59cf31f0ce98c57173faf9 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_operation_advanced_configuration.tutorial001_py39 import app
+from docs_src.path_operation_advanced_configuration.tutorial001_py310 import app
 
 client = TestClient(app)
 
index c26c36030b962da40e230c899c1348f431d2d1ff..c5067e233a052e1eff95fd6df5e9d7413f9284fa 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_operation_advanced_configuration.tutorial002_py39 import app
+from docs_src.path_operation_advanced_configuration.tutorial002_py310 import app
 
 client = TestClient(app)
 
index f060647b2981579c583bfc74547fb2eb3c41a2d8..36fe21678faee7452e978a8400da0fb239170db8 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_operation_advanced_configuration.tutorial003_py39 import app
+from docs_src.path_operation_advanced_configuration.tutorial003_py310 import app
 
 client = TestClient(app)
 
index bf79345449c461cc44af40bfda4de0f1ee87d3dd..894cd9749b661f71c6621344e77cfb89a7f5026c 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index 779e54f9e75168e72c3418d1c9982a0d683a0112..f129ec6f4a4306509b2584a5e9b25dbcda56b798 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_operation_advanced_configuration.tutorial005_py39 import app
+from docs_src.path_operation_advanced_configuration.tutorial005_py310 import app
 
 client = TestClient(app)
 
index d63b5f912d2067cf90bd85a18c664aa38cbba6f4..f3bf2b5bfdfb7062a3fb269403083a8db2270241 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_operation_advanced_configuration.tutorial006_py39 import app
+from docs_src.path_operation_advanced_configuration.tutorial006_py310 import app
 
 client = TestClient(app)
 
index ec0c91bdad97b426dc31d2d6b640b837df277992..ad06e6c05f288c4a7f7d9ce28d47d131a87af0ae 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial007_py39"),
+        pytest.param("tutorial007_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 500cb057c539e2faeaaf118a68af54f553f3de1b..1b81b6f8639fe19e17a08231ea6d99f977674e9c 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 1cc560cb9a6d52ddbc089eb9eb948b47908f23e9..675f3b1aeafc74c0dc858987b2ecccff443ed993 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index 98319645c26c3250c94dd58ee0f3d7b5222610c1..f9a5ff76013d5bcfd7942e7f14093b31ea2a204b 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_operation_configuration.tutorial002b_py39 import app
+from docs_src.path_operation_configuration.tutorial002b_py310 import app
 
 client = TestClient(app)
 
index c13a3c38c834db99f839c209c177395d5fa3ec0b..6d1afecc80f550b0b6f32c037c80d606fa7f9423 100644 (file)
@@ -25,9 +25,7 @@ DESCRIPTIONS = {
 @pytest.fixture(
     name="mod_name",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index 07152755f58ab78c594046c77010146a8c05703c..b186c0a684dfa5f4a0eec22a19e8f1b5a2a1ad09 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
     ],
 )
index 5f56ab929ead9f1fa2e60cacfa6ae3ed2c31b326..27a93f563f627cb50f73c950d333e1aed576f49c 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_operation_configuration.tutorial006_py39 import app
+from docs_src.path_operation_configuration.tutorial006_py310 import app
 
 client = TestClient(app)
 
index ec598832b06b09a98d4a9a0d770c43ef65ef20b2..75c47c85537e56f574e4912a0c49d5bfa6f728c9 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_params.tutorial001_py39 import app
+from docs_src.path_params.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 8384ec8effb044b1c150ab7202a5dfacbbc1728d..416c705585a612238698a55626353fa09ccad05e 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_params.tutorial002_py39 import app
+from docs_src.path_params.tutorial002_py310 import app
 
 client = TestClient(app)
 
index 432ccde49d27316354d20af0a2d16cc39b077ac5..2c07ebbc83aba11158678d4446f5a14006882818 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_params.tutorial003_py39 import app
+from docs_src.path_params.tutorial003_py310 import app
 
 client = TestClient(app)
 
index 1cf39eca9a7ac2fb52df8cd3c19511eee851c762..debf985033d21285226f09597e0b362dfae7906f 100644 (file)
@@ -3,7 +3,7 @@ import asyncio
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_params.tutorial003b_py39 import app, read_users2
+from docs_src.path_params.tutorial003b_py310 import app, read_users2
 
 client = TestClient(app)
 
index b691e821df016bb284a8415757386fa51119ef37..2f2a72e64e2c2dc9d7eae908d3534fc5bb5b27de 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_params.tutorial004_py39 import app
+from docs_src.path_params.tutorial004_py310 import app
 
 client = TestClient(app)
 
index c60fee3f0cc515fff91d55a1007bec2059848b21..bf54b59a91b93612b0f96ec035a0151bf518f1ea 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.path_params.tutorial005_py39 import app
+from docs_src.path_params.tutorial005_py310 import app
 
 client = TestClient(app)
 
index b43de7032561f246c826ef09daa4d987ae3d6eaa..868b0ea786edb6ef6f3e880937a1d50c5c80c743 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 1bb2a3ea8e78ad3ba0133f8c7dfbd7857d7ef6bb..55d5b418cdbd7559f2bf8ae33c193c78e2f4605d 100644 (file)
@@ -8,10 +8,10 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
-        pytest.param("tutorial002_an_py39"),
-        pytest.param("tutorial003_py39"),
-        pytest.param("tutorial003_an_py39"),
+        pytest.param("tutorial002_py310"),
+        pytest.param("tutorial002_an_py310"),
+        pytest.param("tutorial003_py310"),
+        pytest.param("tutorial003_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest) -> TestClient:
index 37c16d295402f8dc10b198ca5f83660cfb50d2ec..7b1272fa10d342f806730bc3c81f0ac77fe96e4e 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
-        pytest.param("tutorial004_an_py39"),
+        pytest.param("tutorial004_py310"),
+        pytest.param("tutorial004_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest) -> TestClient:
index 0afc9dcbc926116d04bdc35c30370900e4973271..d2c9b6077d063354cf2ee973c750ef236704525a 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
-        pytest.param("tutorial005_an_py39"),
+        pytest.param("tutorial005_py310"),
+        pytest.param("tutorial005_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest) -> TestClient:
index e0a9694c12648548fac24259bf1e876ed6583f45..9fb1f8b3b598717665e4d7ae840a013028916b83 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006_py39"),
-        pytest.param("tutorial006_an_py39"),
+        pytest.param("tutorial006_py310"),
+        pytest.param("tutorial006_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest) -> TestClient:
index ccb0968576554076e5760ae7571be8cd34491ebb..d7bf599fe5b3fc1bf85e2156912bd85075f77b07 100644 (file)
@@ -7,8 +7,8 @@ import pytest
 @pytest.mark.parametrize(
     "module_name",
     [
-        "tutorial001_py39",
-        "tutorial002_py39",
+        "tutorial001_py310",
+        "tutorial002_py310",
     ],
 )
 def test_run_module(module_name: str):
index 34d26491716c159aa3af4464a7e1f264fbaf26ee..20b1e7101dc8042f2b4a2e1f2e80312488ab9fc7 100644 (file)
@@ -1,6 +1,6 @@
 import pytest
 
-from docs_src.python_types.tutorial003_py39 import get_name_with_age
+from docs_src.python_types.tutorial003_py310 import get_name_with_age
 
 
 def test_get_name_with_age_pass_int():
index 24af32883e6e1230a0a9539ae97a903fb8920da3..0b16c0cb45d17fdce5118904f815d95f02bc3605 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.python_types.tutorial004_py39 import get_name_with_age
+from docs_src.python_types.tutorial004_py310 import get_name_with_age
 
 
 def test_get_name_with_age_pass_int():
index 6d67ec4716a6919e40750c08e1d79bb30ea6b48b..b5c847523d7855a317fee862570ef33be76e45b5 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.python_types.tutorial005_py39 import get_items
+from docs_src.python_types.tutorial005_py310 import get_items
 
 
 def test_get_items():
index 50976926e7247a924b6532ceae29d5a18e9884c3..fbe929a76693fb1f0da2bf13e575456d14e8924d 100644 (file)
@@ -1,6 +1,6 @@
 from unittest.mock import patch
 
-from docs_src.python_types.tutorial006_py39 import process_items
+from docs_src.python_types.tutorial006_py310 import process_items
 
 
 def test_process_items():
index c04529465229213fcaf96b2ef08df298c3211987..b664d2784cea1d1cd33f402d056e7bd285b9002a 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.python_types.tutorial007_py39 import process_items
+from docs_src.python_types.tutorial007_py310 import process_items
 
 
 def test_process_items():
index 33cf6cbfbc69918a44644fb3b299fd6421fecdec..74a4e9cace4a37e5efc2c63cd5d5248031c1626a 100644 (file)
@@ -1,6 +1,6 @@
 from unittest.mock import patch
 
-from docs_src.python_types.tutorial008_py39 import process_items
+from docs_src.python_types.tutorial008_py310 import process_items
 
 
 def test_process_items():
index 1ef0d4ea16ef5a99878a36cfe031c32577d0168e..60d7e51c121b1ce5ac5e564183195d2c3eb5bd5d 100644 (file)
@@ -10,7 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="module",
     params=[
-        pytest.param("tutorial008b_py39"),
+        pytest.param("tutorial008b_py310"),
         pytest.param("tutorial008b_py310", marks=needs_py310),
     ],
 )
index 34046c5c48ce31a155c02db36f47a716ca0db84c..eec51b1becb57cdc540c21646401e3cf8834824d 100644 (file)
@@ -10,9 +10,8 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="module",
     params=[
-        pytest.param("tutorial009_py39"),
+        pytest.param("tutorial009_py310"),
         pytest.param("tutorial009_py310", marks=needs_py310),
-        pytest.param("tutorial009b_py39"),
     ],
 )
 def get_module(request: pytest.FixtureRequest):
index 7bd40491135ce10984f40d3147a689cf3b54cdc9..17c4b9e0c26f07593f6fdd0c6d8c05e212fff38e 100644 (file)
@@ -11,7 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="module",
     params=[
-        pytest.param("tutorial009c_py39"),
+        pytest.param("tutorial009c_py310"),
         pytest.param("tutorial009c_py310", marks=needs_py310),
     ],
 )
index 9e4d2e36bf97c9b80cc3f9b0344d03345e4d1921..8525e6d84315d037cc5215727ec3e8c9873dbd60 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.python_types.tutorial010_py39 import Person, get_person_name
+from docs_src.python_types.tutorial010_py310 import Person, get_person_name
 
 
 def test_get_person_name():
index a05751b974022d6958ba7b1115e5e2763246d62e..3761eb9243b7dc6fe1b9a012d0cd1774ea87ec68 100644 (file)
@@ -9,7 +9,6 @@ from ...utils import needs_py310
 @pytest.mark.parametrize(
     "module_name",
     [
-        pytest.param("tutorial011_py39"),
         pytest.param("tutorial011_py310", marks=needs_py310),
     ],
 )
diff --git a/tests/test_tutorial/test_python_types/test_tutorial012.py b/tests/test_tutorial/test_python_types/test_tutorial012.py
deleted file mode 100644 (file)
index e578048..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-from docs_src.python_types.tutorial012_py39 import User
-
-
-def test_user():
-    user = User(name="John Doe", age=30)
-    assert user.name == "John Doe"
-    assert user.age == 30
index 5602ef76f862e2ecd04698d590cded1a90debbe7..d8669b485cf1d0bf93bac2a0a443e85644f60af9 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.python_types.tutorial013_py39 import say_hello
+from docs_src.python_types.tutorial013_py310 import say_hello
 
 
 def test_say_hello():
index 38b767154a3e0dba2ca3e163b8a5a9320f9d557f..75d1b97622f9dfb60a74621fcde7ab3b36723ad4 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index b173a2df452c20ef11882103ec686404f7a29944..da2b6608abf1c52e680828502a0f311fd5f1fb58 100644 (file)
@@ -10,9 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=[needs_py310]),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=[needs_py310]),
     ],
 )
index 40ada0e8e4e070a38e0ec9462e69cb599cdf326d..d6870258710d99685d7a448cb2ab636f10d8a051 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
+        pytest.param("tutorial001_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 1da308a7e2f4b45c77714bf5b5e0a80a57d9fc10..9be507fba7b19266024abe5f9e27c1247632a8c4 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index 9bb58ff9fe050d72925840da66ba0cad14327e07..2951f1adf95296d6136de8bb45756b8543baa983 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index 20aadb3acd7d003cfab63d090ae50ce45c7a2ceb..9786f861f1db39f041797cd7627e3f0a0c4d22dd 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index e023fe6d806a011dfc36664088106a077572e94d..b21e97f0b3a0b64b3ef98c51599ad18c21a028e6 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.query_params.tutorial005_py39 import app
+from docs_src.query_params.tutorial005_py310 import app
 
 client = TestClient(app)
 
index b28e12655623b72ff7b47f047bcddbb91d6bda7b..a27f2bbb019dbd66145dcc9d01059a81d653f613 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006_py39"),
         pytest.param("tutorial006_py310", marks=needs_py310),
     ],
 )
index ed73b7329ef5e33c69348079004e8fd9f79d7fbf..1eb424e4fe868510ff2ce320b1adcd1015656bd6 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 3eac1f2b36e22462bc5cd6213ed5097804045042..feb59f1690404a58d775c83849a734fe3a367c2a 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 59d5160acb6ccf765638333d4de9648901c6cb6e..4e1ef1da7f68346a8498d4754811ea1d11474c41 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index abf08c93282118cc997905056d80038506be2fbc..9c2d442c8c392ce4c5ae77dee5ed18a020243f37 100644 (file)
@@ -10,19 +10,8 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
-        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
-        pytest.param(
-            "tutorial004_regex_an_py310",
-            marks=(
-                needs_py310,
-                pytest.mark.filterwarnings(
-                    "ignore:`regex` has been deprecated, please use `pattern` instead:fastapi.exceptions.FastAPIDeprecationWarning"
-                ),
-            ),
-        ),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 7b5368abc4688bc997905d624ed3f0641189fd89..61f07631b3c488caf2165401b5e5b53e2f0e5866 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
-        pytest.param("tutorial005_an_py39"),
+        pytest.param("tutorial005_py310"),
+        pytest.param("tutorial005_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 2c1df2c08fb563ceb7bd12096db8e41d324b40ab..18ee8dbdcfec726ce893513be474d162937816d6 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006_py39"),
-        pytest.param("tutorial006_an_py39"),
+        pytest.param("tutorial006_py310"),
+        pytest.param("tutorial006_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 3df9efa839d7755f3631a1445bf57549826e18c7..74c10b885d480d149193aa4f0c5be4050148b4fb 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006c_py39"),
         pytest.param("tutorial006c_py310", marks=needs_py310),
-        pytest.param("tutorial006c_an_py39"),
         pytest.param("tutorial006c_an_py310", marks=needs_py310),
     ],
 )
index 874002b1730c241eaf69006657e98a37a40a8722..3a23ce4a43431148bf6cc595e9a0b6c9612fec9e 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial007_py39"),
         pytest.param("tutorial007_py310", marks=needs_py310),
-        pytest.param("tutorial007_an_py39"),
         pytest.param("tutorial007_an_py310", marks=needs_py310),
     ],
 )
index b9613a17b8fb1915f0ff6fb52ccb0bd946e52c09..430d1bc188cd41c3e95a000dfeff1bf5df99b081 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial008_py39"),
         pytest.param("tutorial008_py310", marks=needs_py310),
-        pytest.param("tutorial008_an_py39"),
         pytest.param("tutorial008_an_py310", marks=needs_py310),
     ],
 )
index d749d85f7a693f8682404b8ee6ddb320ebb87489..a81e1c40e35738375de7ba0598d955e5ee8d0dd2 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial009_py39"),
         pytest.param("tutorial009_py310", marks=needs_py310),
-        pytest.param("tutorial009_an_py39"),
         pytest.param("tutorial009_an_py310", marks=needs_py310),
     ],
 )
index efe9f1fa6b8ba3d7ef615d395bd5771174e1e6d3..bb8fbfceecfb32de8b942edaca451af411bacad7 100644 (file)
@@ -11,9 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial010_py39"),
         pytest.param("tutorial010_py310", marks=needs_py310),
-        pytest.param("tutorial010_an_py39"),
         pytest.param("tutorial010_an_py310", marks=needs_py310),
     ],
 )
index c25357fdd1312a9e16a01a5036ac9aaa64ecf38f..8d558efec95409d1c3c8e2f54ddbc6a2a7194065 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial011_py39"),
         pytest.param("tutorial011_py310", marks=needs_py310),
-        pytest.param("tutorial011_an_py39"),
         pytest.param("tutorial011_an_py310", marks=needs_py310),
     ],
 )
index c3d01e90eae15ba63e779f0db048653029b5e503..5aae7fcc69e1abe574a3692dc66c9a07d802508c 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial012_py39"),
-        pytest.param("tutorial012_an_py39"),
+        pytest.param("tutorial012_py310"),
+        pytest.param("tutorial012_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 74efa4695856638f4d487a088c58ea107d83f6c5..29d49a5b77472e74985b34458eaf6c90298d669b 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial013_py39",
-        "tutorial013_an_py39",
+        "tutorial013_py310",
+        "tutorial013_an_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 6dff18b7877eb211d8abadae337d77640f990a05..683e39795ab2ea5888dceeff6d0664af052e0125 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial014_py39"),
         pytest.param("tutorial014_py310", marks=needs_py310),
-        pytest.param("tutorial014_an_py39"),
         pytest.param("tutorial014_an_py310", marks=needs_py310),
     ],
 )
index 32a990e74837348ef521b4c4b12ea82490f6d2fe..01d7c983a6bf2f462fab17a332edf67d9d91c04c 100644 (file)
@@ -11,7 +11,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial015_an_py39"),
         pytest.param("tutorial015_an_py310", marks=[needs_py310]),
     ],
 )
index fd5c3b0559d7a0336a12d5246772fa7562c719e0..4d3c35d65dd5360b62ffe14c2b3324c91661b2ca 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
-        "tutorial001_an_py39",
+        "tutorial001_py310",
+        "tutorial001_an_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index feeb5363ed918523d46b20d7643ade7e9c84e474..f199b992aef44be9ac7227b3a5f15252c049665f 100644 (file)
@@ -11,9 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_02_py39"),
         pytest.param("tutorial001_02_py310", marks=needs_py310),
-        pytest.param("tutorial001_02_an_py39"),
         pytest.param("tutorial001_02_an_py310", marks=needs_py310),
     ],
 )
index 5ef8df178c8c8fe42169e880082de6bf7044e9b9..ce22c1b5c449f40192c3ee394bf3e7234e581664 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_03_py39",
-        "tutorial001_03_an_py39",
+        "tutorial001_03_py310",
+        "tutorial001_03_an_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 52655fd63b38b4c4acd70ffaf696709d65592c20..ebf76b3a07965954fcb7be495adce6247c1e05f6 100644 (file)
@@ -9,8 +9,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="app",
     params=[
-        "tutorial002_py39",
-        "tutorial002_an_py39",
+        "tutorial002_py310",
+        "tutorial002_an_py310",
     ],
 )
 def get_app(request: pytest.FixtureRequest):
index a1425ba3307e77ea1a4ab1af889c7fb64447c3fa..f11658d27c72a23f790ac01c7a04a5c272e907ee 100644 (file)
@@ -9,8 +9,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="app",
     params=[
-        "tutorial003_py39",
-        "tutorial003_an_py39",
+        "tutorial003_py310",
+        "tutorial003_an_py310",
     ],
 )
 def get_app(request: pytest.FixtureRequest):
index 68fa074dc39171af6a58d21c7cbad8e246f8175f..3122e97e817b60e80db8fad7e69dee8705f7d697 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
-        "tutorial001_an_py39",
+        "tutorial001_py310",
+        "tutorial001_an_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index ed5ae109a02533131e33f95fefa7822a7a38d9a0..e5dc6e486b996a208724392f4356453869861248 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002_py39",
-        "tutorial002_an_py39",
+        "tutorial002_py310",
+        "tutorial002_an_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index d1596f137e2c40f0e2e4ac364b8835d4530385d0..ff3421aac0d7cf78f316d05491f8bc46b21edd18 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_py39",
-        "tutorial001_an_py39",
+        "tutorial001_py310",
+        "tutorial001_an_py310",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 6e9165c425ffc9db085e8909d166e4b3fef70597..e2462e040b971e0a9d890c5abd864560f916d895 100644 (file)
@@ -9,8 +9,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="app",
     params=[
-        "tutorial001_py39",
-        "tutorial001_an_py39",
+        "tutorial001_py310",
+        "tutorial001_an_py310",
     ],
 )
 def get_app(request: pytest.FixtureRequest):
index 05d5ca619f34407149d0a065c7e9a3bccb9b6cd2..d046bd266fe724ec22ff5ea7cee0718b0dc96d27 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_change_status_code.tutorial001_py39 import app
+from docs_src.response_change_status_code.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 6b931c8bdaa1b7ca6e9e2f40ce43a58faaa04165..1068983395493188ba8c468b78893c6e953970c3 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_cookies.tutorial001_py39 import app
+from docs_src.response_cookies.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 3ee5f500c529f79215430878183939f5bd5be1b6..66812e4807b7f8e97f0f349b81be1770cf6c716a 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_cookies.tutorial002_py39 import app
+from docs_src.response_cookies.tutorial002_py310 import app
 
 client = TestClient(app)
 
index 2b034f1c98225646657420fc3109c41ff80b58cd..54406684d8d7570c43c4b1da05657ff35b8680d4 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 047e82c148fb2342d910e8c5482f4ce17ccb6f8e..7dcb8d292617ac961f1b21b58d1b144b4d1840a4 100644 (file)
@@ -8,7 +8,7 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
+        pytest.param("tutorial002_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 6232aad23ea1ab2f7e679ca67d72c51c2e0bc885..ea182246f6cacf10bfcdfca3080f20ed7ce98cac 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_headers.tutorial001_py39 import app
+from docs_src.response_headers.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 2ac2226cb1700cb36433ba790f663a60d1213f2f..9b90459cb7a369db86d0d0385e41998c2a7c396e 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_headers.tutorial002_py39 import app
+from docs_src.response_headers.tutorial002_py310 import app
 
 client = TestClient(app)
 
index 914f53783c16e51d77c9930c8df274c8af973fd1..bbdcc682027192cbdd1b793cd0d9fe297f223a22 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_01_py39"),
         pytest.param("tutorial001_01_py310", marks=needs_py310),
     ],
 )
index 10a4e37cd3575e3478cb844f0035665a0c5264a9..31b4659905504de65e3d28ac45b0cb95d5e15c7f 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index a1477b7dfd9253e9daa5e04cb14c4d87ec2ea8fc..8178c819637b9037ef4625a04570c480ec4296cf 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index a60a14ae8d9eb5257499bf2a9901a665a7a0edb2..1a0c4f2603c4c9bd2e7b772bb12fc8661d1c2ecc 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_01_py39"),
         pytest.param("tutorial003_01_py310", marks=needs_py310),
     ],
 )
index 460c882516b0b76679c554a8f7d682ad4a0ac93e..a28c56be92a0649c166829069219a2828d315ae3 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.response_model.tutorial003_02_py39 import app
+from docs_src.response_model.tutorial003_02_py310 import app
 
 client = TestClient(app)
 
index c83d78c4fac9d402b8dd04b680d03960f0bbf758..65e7470222aa3a47963e19b78a0472420fdb8235 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.response_model.tutorial003_03_py39 import app
+from docs_src.response_model.tutorial003_03_py310 import app
 
 client = TestClient(app)
 
index 145af126fde0fe27173ac15cde7ece9ff0432222..44f2e504eaec2a09e60128dad8aa2b782745f98a 100644 (file)
@@ -9,7 +9,6 @@ from ...utils import needs_py310
 @pytest.mark.parametrize(
     "module_name",
     [
-        pytest.param("tutorial003_04_py39"),
         pytest.param("tutorial003_04_py310", marks=needs_py310),
     ],
 )
index 187b6491fce7e4a1630327eea345ec3758621823..0f0e94fdaacae33bc82c58f8e1b43b3905cd13aa 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_05_py39"),
         pytest.param("tutorial003_05_py310", marks=needs_py310),
     ],
 )
index d40bce261b28a2a3a7b4d0f3f4562661b81ba218..e7c0e79f21a53f681867804791e30fc556a86b2b 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index 55b2334d4695427674bb6ea7cd745997d0551a78..75c8fc0aca373da1a9e80fdf990f254c6cced382 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
     ],
 )
index 5d6f542b5d273c8046f9fecd2d922aeba57acdd7..f80ce1b28b54f76b5d9417f5df28b545b74d2fee 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006_py39"),
         pytest.param("tutorial006_py310", marks=needs_py310),
     ],
 )
index 7199ceed656f896c882384115a2c78ee66b37c0d..69c32f92e2777f631339fbf5e33dd0191bfbd437 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
-        pytest.param("tutorial002_py39"),
+        pytest.param("tutorial001_py310"),
+        pytest.param("tutorial002_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index f19346a3a491360d2d7e47b7a3e78a2b8bc734a1..126dfbe7d3a0351f9434ed64d91cda9d68ed959b 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 8313cb14f6967553ea62c87f809e3b34f092e306..cac3337a2402a018697a268d9a3ee3dd7e655156 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index 3c45a64bcf5af14150e7e32e97644107d84e13e0..1ccca4da8575b3619593d25afedcbdbb2e7b188c 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index 4b8e15fa19542b05ad040329a563137a62c018a2..cffd270665a0e22432938907e02904ffbb68e9dd 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
-        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
     ],
 )
index 7f8e36df21ddbb58476b7808ed61c4188534f0d8..0bc17a00e12537909fa56f46e916a88bfeddaf8c 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
-        pytest.param("tutorial005_an_py39"),
         pytest.param("tutorial005_an_py310", marks=needs_py310),
     ],
 )
index 5742b51bf0fcf6fa7ca54742be420e09f40929e8..c1a15ae0098e7b391c629b7724e5c9e17062053b 100644 (file)
@@ -8,8 +8,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
-        pytest.param("tutorial001_an_py39"),
+        pytest.param("tutorial001_py310"),
+        pytest.param("tutorial001_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 1e8c6e01808b92e1833274dd564bbbe3c455e5e8..4d1202c32505bf48ac6d928abb82e3d1870ccd62 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index acd910c71f3553437b04beef4e6aa06475c0066e..45f4e57bbaea8b447c8b5ecfe83c5eca416575b4 100644 (file)
@@ -10,9 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index e842c92a138b4eebfd7b7e6a4dbc8252e4bd76ab..e52a029bd4bb114657ee0d713b8e0e32a8af23ea 100644 (file)
@@ -12,9 +12,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
-        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
     ],
 )
index 76b08860f531794eaac51b260cf667bebbd520c8..c6e0e78e09aa176ddc51e85d5c8e45d6fc67d808 100644 (file)
@@ -11,9 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
-        pytest.param("tutorial005_an_py39"),
         pytest.param("tutorial005_an_py310", marks=needs_py310),
     ],
 )
index 1c96f62ae3e352ee3c5c38a2e2ad7f8ceb66edb3..671946d97e40e8b8765c23943bbb60ee66e82d26 100644 (file)
@@ -9,8 +9,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial006_py39"),
-        pytest.param("tutorial006_an_py39"),
+        pytest.param("tutorial006_py310"),
+        pytest.param("tutorial006_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 24667422fe8a0a2052bb9db2b8711f6f516d1fc5..e7354575363fce2c19a5aea6bdb6e1a68923122a 100644 (file)
@@ -9,8 +9,8 @@ from inline_snapshot import snapshot
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial007_py39"),
-        pytest.param("tutorial007_an_py39"),
+        pytest.param("tutorial007_py310"),
+        pytest.param("tutorial007_an_py310"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 0be3b59f9908ef9269e411acd778b0f355068e84..653b20c7d2270c1dfcdb862908e49e42d1555560 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 87c63f69e0b9a2f6c8dbc949b6c2ed8b90a31223..0ef706a4d176919cfce180dd89b09c23102b1a2f 100644 (file)
@@ -10,7 +10,6 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index 52b9b1e629e04df3bfa47f12ea3cfea0199faf77..da27308e8045d7bd044b91bfdb49694e11a47cc2 100644 (file)
@@ -12,7 +12,7 @@ from pytest import MonkeyPatch
 @pytest.fixture(
     name="mod_name",
     params=[
-        pytest.param("app01_py39"),
+        pytest.param("app01_py310"),
     ],
 )
 def get_mod_name(request: pytest.FixtureRequest):
index 9cbed4fd1bec3d6e35a50dbf3727bc199d35b1bc..20594ebb74406b73d90015054ab33ad8d5daec81 100644 (file)
@@ -8,8 +8,8 @@ from pytest import MonkeyPatch
 @pytest.fixture(
     name="mod_path",
     params=[
-        pytest.param("app02_py39"),
-        pytest.param("app02_an_py39"),
+        pytest.param("app02_py310"),
+        pytest.param("app02_an_py310"),
     ],
 )
 def get_mod_path(request: pytest.FixtureRequest):
index 72de49796710f9c787c48e230a1d2816933f9a9a..f4539c96d748c5511b62c73512f138cc26bcfd59 100644 (file)
@@ -9,8 +9,8 @@ from pytest import MonkeyPatch
 @pytest.fixture(
     name="mod_path",
     params=[
-        pytest.param("app03_py39"),
-        pytest.param("app03_an_py39"),
+        pytest.param("app03_py310"),
+        pytest.param("app03_an_py310"),
     ],
 )
 def get_mod_path(request: pytest.FixtureRequest):
index f4576a0d21b746cc29b38bcd15a06f806e309872..8857c35df35a183a6cf28fd22dfaf6d519c35ab0 100644 (file)
@@ -5,7 +5,7 @@ from fastapi.testclient import TestClient
 from pytest import MonkeyPatch
 
 
-@pytest.fixture(name="app", params=[pytest.param("tutorial001_py39")])
+@pytest.fixture(name="app", params=[pytest.param("tutorial001_py310")])
 def get_app(request: pytest.FixtureRequest, monkeypatch: MonkeyPatch):
     monkeypatch.setenv("ADMIN_EMAIL", "admin@example.com")
     mod = importlib.import_module(f"docs_src.settings.{request.param}")
index aec20e42e13817af65c9438785c156fb21fa59b7..3407ec758873fa32d5f114becade7948cfba5283 100644 (file)
@@ -22,9 +22,7 @@ def clear_sqlmodel():
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 4ea7d5f64743d84b80edd4223c003a0031fb6cad..51a36b6c793f36e34e87c0e7f1eee2e2010fcaa8 100644 (file)
@@ -22,9 +22,7 @@ def clear_sqlmodel():
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index dd93fee790722bd8cfbc081dab05c0100750dac8..1d57310f307dcd3c579b2f1f697c6ba6ccd3bff7 100644 (file)
@@ -12,7 +12,7 @@ def client():
     static_dir.mkdir(exist_ok=True)
     sample_file = static_dir / "sample.txt"
     sample_file.write_text("This is a sample static file.")
-    from docs_src.static_files.tutorial001_py39 import app
+    from docs_src.static_files.tutorial001_py310 import app
 
     with TestClient(app) as client:
         yield client
index a8fb3dc36fb0be448144c250d5704f5b0cbb884c..63fb68fb27e1e5989fa779802210a9beb12b5717 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.sub_applications.tutorial001_py39 import app
+from docs_src.sub_applications.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 818508037df8c0d7f141f405672fb956ce10e0b5..04bc3fce86b96a429ea71d05c740dc2daa05e679 100644 (file)
@@ -11,7 +11,7 @@ def test_main():
         shutil.rmtree("./templates")
     shutil.copytree("./docs_src/templates/templates/", "./templates")
     shutil.copytree("./docs_src/templates/static/", "./static")
-    from docs_src.templates.tutorial001_py39 import app
+    from docs_src.templates.tutorial001_py310 import app
 
     client = TestClient(app)
     response = client.get("/items/foo")
index 5284888053cb23322994dd2acb0ed1b543f52899..d071d5309563481b46f845f503ebf6f52ee54824 100644 (file)
@@ -1,6 +1,6 @@
 from inline_snapshot import snapshot
 
-from docs_src.app_testing.app_a_py39.test_main import client, test_read_main
+from docs_src.app_testing.app_a_py310.test_main import client, test_read_main
 
 
 def test_main():
index 3d679cd5a684d3ab79fdc7af9eb2b0d7350cc543..2d042fd6900c3a50891564f5182bd4cb8bfb6d04 100644 (file)
@@ -9,9 +9,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="test_module",
     params=[
-        "app_b_py39.test_main",
         pytest.param("app_b_py310.test_main", marks=needs_py310),
-        "app_b_an_py39.test_main",
         pytest.param("app_b_an_py310.test_main", marks=needs_py310),
     ],
 )
index 2b501d36a756c280bb530f3a7cf53e536393f33d..b9bb182b77deee4a68231dfee589212abdbaaaea 100644 (file)
@@ -1,6 +1,6 @@
 from inline_snapshot import snapshot
 
-from docs_src.app_testing.tutorial001_py39 import client, test_read_main
+from docs_src.app_testing.tutorial001_py310 import client, test_read_main
 
 
 def test_main():
index cc9b5ba27c48cfc7573248cd7a4e2b7777569ce4..840248dc3061d01eb199acd97b652ba318da256c 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.app_testing.tutorial002_py39 import test_read_main, test_websocket
+from docs_src.app_testing.tutorial002_py310 import test_read_main, test_websocket
 
 
 def test_main():
index 4faa820e98e48353560baaab6bab329951cb819b..196fc4555982fb5371626db09fdf616bd7cd775e 100644 (file)
@@ -3,5 +3,5 @@ import pytest
 
 def test_main():
     with pytest.warns(DeprecationWarning):
-        from docs_src.app_testing.tutorial003_py39 import test_read_items
+        from docs_src.app_testing.tutorial003_py310 import test_read_items
     test_read_items()
index c95214ffe32b93698765b082d2191d79726f0650..d5de1bb6033903a83eb4f790c31a98cb52cc3135 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.app_testing.tutorial004_py39 import test_read_items
+from docs_src.app_testing.tutorial004_py310 import test_read_items
 
 
 def test_main():
index 6e9656bf559d528f2163d3f0a075a6fc6ac362e4..81491276eb3304a20988bcbccfce70613766a951 100644 (file)
@@ -9,9 +9,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="test_module",
     params=[
-        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index cb8ae8b050a5b54374f9fa93fda53dbe66d5b02a..4145177e4a438f35840b9e8153248e38bf7cf8fa 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from docs_src.using_request_directly.tutorial001_py39 import app
+from docs_src.using_request_directly.tutorial001_py310 import app
 
 client = TestClient(app)
 
index 4f8368db289331cff501ed218513f4e1c2d5520f..6f3bf1429a831373b8fc947376c26b1c480b0baa 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 from fastapi.testclient import TestClient
 from fastapi.websockets import WebSocketDisconnect
 
-from docs_src.websockets.tutorial001_py39 import app
+from docs_src.websockets.tutorial001_py310 import app
 
 client = TestClient(app)
 
index ebf1fc8e8111db6dc82c46994e8ff5fdfd25882a..0509b0d0d616877f28f2257cafb4fc79fb2ecbb2 100644 (file)
@@ -11,9 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="app",
     params=[
-        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 0be1fc81d63de64453feb4ef885695cb5979e539..781146371d43615617a6bd4e386532b487138454 100644 (file)
@@ -8,7 +8,7 @@ from fastapi.testclient import TestClient
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial003_py39"),
+        pytest.param("tutorial003_py310"),
     ],
 )
 def get_mod(request: pytest.FixtureRequest):
index 9fe8c2a4b826259921d3b48e78cabcfcd6db3dc9..9bcd56dfc265eeca6dfec906cf5804da557b6f13 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.wsgi.tutorial001_py39 import app
+from docs_src.wsgi.tutorial001_py310 import app
 
 client = TestClient(app)