]> git.ipfire.org Git - thirdparty/fastapi/fastapi.git/commitdiff
⚰️ Remove Python 3.8 from CI and remove Python 3.8 examples from source docs (#14559)
authorSebastián Ramírez <tiangolo@gmail.com>
Wed, 17 Dec 2025 20:41:43 +0000 (12:41 -0800)
committerGitHub <noreply@github.com>
Wed, 17 Dec 2025 20:41:43 +0000 (21:41 +0100)
Co-authored-by: Yurii Motov <yurii.motov.monte@gmail.com>
Co-authored-by: Motov Yurii <109919500+YuriiMotov@users.noreply.github.com>
815 files changed:
.github/workflows/test.yml
docs/de/docs/advanced/additional-responses.md
docs/de/docs/advanced/async-tests.md
docs/de/docs/advanced/behind-a-proxy.md
docs/de/docs/advanced/custom-response.md
docs/de/docs/advanced/events.md
docs/de/docs/advanced/generate-clients.md
docs/de/docs/advanced/middleware.md
docs/de/docs/advanced/openapi-webhooks.md
docs/de/docs/advanced/path-operation-advanced-configuration.md
docs/de/docs/advanced/response-change-status-code.md
docs/de/docs/advanced/response-cookies.md
docs/de/docs/advanced/response-directly.md
docs/de/docs/advanced/response-headers.md
docs/de/docs/advanced/settings.md
docs/de/docs/advanced/sub-applications.md
docs/de/docs/advanced/templates.md
docs/de/docs/advanced/testing-events.md
docs/de/docs/advanced/testing-websockets.md
docs/de/docs/advanced/using-request-directly.md
docs/de/docs/advanced/websockets.md
docs/de/docs/advanced/wsgi.md
docs/de/docs/how-to/conditional-openapi.md
docs/de/docs/how-to/configure-swagger-ui.md
docs/de/docs/how-to/custom-docs-ui-assets.md
docs/de/docs/how-to/extending-openapi.md
docs/de/docs/how-to/graphql.md
docs/de/docs/project-generation.md
docs/de/docs/python-types.md
docs/de/docs/tutorial/background-tasks.md
docs/de/docs/tutorial/body-nested-models.md
docs/de/docs/tutorial/body.md
docs/de/docs/tutorial/cors.md
docs/de/docs/tutorial/debugging.md
docs/de/docs/tutorial/dependencies/classes-as-dependencies.md
docs/de/docs/tutorial/dependencies/dependencies-with-yield.md
docs/de/docs/tutorial/dependencies/global-dependencies.md
docs/de/docs/tutorial/dependencies/sub-dependencies.md
docs/de/docs/tutorial/first-steps.md
docs/de/docs/tutorial/handling-errors.md
docs/de/docs/tutorial/metadata.md
docs/de/docs/tutorial/middleware.md
docs/de/docs/tutorial/path-operation-configuration.md
docs/de/docs/tutorial/path-params-numeric-validations.md
docs/de/docs/tutorial/path-params.md
docs/de/docs/tutorial/query-params-str-validations.md
docs/de/docs/tutorial/query-params.md
docs/de/docs/tutorial/response-model.md
docs/de/docs/tutorial/response-status-code.md
docs/de/docs/tutorial/static-files.md
docs/de/docs/tutorial/testing.md
docs/en/docs/advanced/additional-responses.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/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/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/management-tasks.md
docs/en/docs/python-types.md
docs/en/docs/tutorial/background-tasks.md
docs/en/docs/tutorial/body-nested-models.md
docs/en/docs/tutorial/body.md
docs/en/docs/tutorial/cors.md
docs/en/docs/tutorial/debugging.md
docs/en/docs/tutorial/dependencies/classes-as-dependencies.md
docs/en/docs/tutorial/dependencies/dependencies-with-yield.md
docs/en/docs/tutorial/dependencies/global-dependencies.md
docs/en/docs/tutorial/dependencies/sub-dependencies.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/response-model.md
docs/en/docs/tutorial/response-status-code.md
docs/en/docs/tutorial/static-files.md
docs/en/docs/tutorial/testing.md
docs/es/docs/advanced/additional-responses.md
docs/es/docs/advanced/async-tests.md
docs/es/docs/advanced/behind-a-proxy.md
docs/es/docs/advanced/custom-response.md
docs/es/docs/advanced/events.md
docs/es/docs/advanced/generate-clients.md
docs/es/docs/advanced/middleware.md
docs/es/docs/advanced/openapi-webhooks.md
docs/es/docs/advanced/path-operation-advanced-configuration.md
docs/es/docs/advanced/response-change-status-code.md
docs/es/docs/advanced/response-cookies.md
docs/es/docs/advanced/response-directly.md
docs/es/docs/advanced/response-headers.md
docs/es/docs/advanced/settings.md
docs/es/docs/advanced/sub-applications.md
docs/es/docs/advanced/templates.md
docs/es/docs/advanced/testing-events.md
docs/es/docs/advanced/testing-websockets.md
docs/es/docs/advanced/using-request-directly.md
docs/es/docs/advanced/websockets.md
docs/es/docs/advanced/wsgi.md
docs/es/docs/how-to/conditional-openapi.md
docs/es/docs/how-to/configure-swagger-ui.md
docs/es/docs/how-to/custom-docs-ui-assets.md
docs/es/docs/how-to/extending-openapi.md
docs/es/docs/how-to/graphql.md
docs/es/docs/python-types.md
docs/es/docs/tutorial/background-tasks.md
docs/es/docs/tutorial/body-nested-models.md
docs/es/docs/tutorial/body.md
docs/es/docs/tutorial/cors.md
docs/es/docs/tutorial/debugging.md
docs/es/docs/tutorial/dependencies/classes-as-dependencies.md
docs/es/docs/tutorial/dependencies/dependencies-with-yield.md
docs/es/docs/tutorial/dependencies/global-dependencies.md
docs/es/docs/tutorial/dependencies/sub-dependencies.md
docs/es/docs/tutorial/first-steps.md
docs/es/docs/tutorial/handling-errors.md
docs/es/docs/tutorial/metadata.md
docs/es/docs/tutorial/middleware.md
docs/es/docs/tutorial/path-operation-configuration.md
docs/es/docs/tutorial/path-params-numeric-validations.md
docs/es/docs/tutorial/path-params.md
docs/es/docs/tutorial/query-params-str-validations.md
docs/es/docs/tutorial/query-params.md
docs/es/docs/tutorial/response-model.md
docs/es/docs/tutorial/response-status-code.md
docs/es/docs/tutorial/static-files.md
docs/es/docs/tutorial/testing.md
docs/pt/docs/advanced/additional-responses.md
docs/pt/docs/advanced/async-tests.md
docs/pt/docs/advanced/behind-a-proxy.md
docs/pt/docs/advanced/custom-response.md
docs/pt/docs/advanced/events.md
docs/pt/docs/advanced/generate-clients.md
docs/pt/docs/advanced/middleware.md
docs/pt/docs/advanced/openapi-webhooks.md
docs/pt/docs/advanced/path-operation-advanced-configuration.md
docs/pt/docs/advanced/response-change-status-code.md
docs/pt/docs/advanced/response-cookies.md
docs/pt/docs/advanced/response-directly.md
docs/pt/docs/advanced/response-headers.md
docs/pt/docs/advanced/settings.md
docs/pt/docs/advanced/sub-applications.md
docs/pt/docs/advanced/templates.md
docs/pt/docs/advanced/testing-events.md
docs/pt/docs/advanced/testing-websockets.md
docs/pt/docs/advanced/using-request-directly.md
docs/pt/docs/advanced/websockets.md
docs/pt/docs/advanced/wsgi.md
docs/pt/docs/how-to/conditional-openapi.md
docs/pt/docs/how-to/configure-swagger-ui.md
docs/pt/docs/how-to/custom-docs-ui-assets.md
docs/pt/docs/how-to/extending-openapi.md
docs/pt/docs/how-to/graphql.md
docs/pt/docs/python-types.md
docs/pt/docs/tutorial/background-tasks.md
docs/pt/docs/tutorial/body-nested-models.md
docs/pt/docs/tutorial/body.md
docs/pt/docs/tutorial/cors.md
docs/pt/docs/tutorial/debugging.md
docs/pt/docs/tutorial/dependencies/classes-as-dependencies.md
docs/pt/docs/tutorial/dependencies/dependencies-with-yield.md
docs/pt/docs/tutorial/dependencies/global-dependencies.md
docs/pt/docs/tutorial/dependencies/sub-dependencies.md
docs/pt/docs/tutorial/first-steps.md
docs/pt/docs/tutorial/handling-errors.md
docs/pt/docs/tutorial/metadata.md
docs/pt/docs/tutorial/middleware.md
docs/pt/docs/tutorial/path-operation-configuration.md
docs/pt/docs/tutorial/path-params-numeric-validations.md
docs/pt/docs/tutorial/path-params.md
docs/pt/docs/tutorial/query-params-str-validations.md
docs/pt/docs/tutorial/query-params.md
docs/pt/docs/tutorial/response-model.md
docs/pt/docs/tutorial/response-status-code.md
docs/pt/docs/tutorial/static-files.md
docs/pt/docs/tutorial/testing.md
docs/pt/llm-prompt.md
docs/ru/docs/advanced/additional-responses.md
docs/ru/docs/advanced/async-tests.md
docs/ru/docs/advanced/behind-a-proxy.md
docs/ru/docs/advanced/custom-response.md
docs/ru/docs/advanced/events.md
docs/ru/docs/advanced/generate-clients.md
docs/ru/docs/advanced/middleware.md
docs/ru/docs/advanced/openapi-webhooks.md
docs/ru/docs/advanced/path-operation-advanced-configuration.md
docs/ru/docs/advanced/response-change-status-code.md
docs/ru/docs/advanced/response-cookies.md
docs/ru/docs/advanced/response-directly.md
docs/ru/docs/advanced/response-headers.md
docs/ru/docs/advanced/settings.md
docs/ru/docs/advanced/sub-applications.md
docs/ru/docs/advanced/templates.md
docs/ru/docs/advanced/testing-events.md
docs/ru/docs/advanced/testing-websockets.md
docs/ru/docs/advanced/using-request-directly.md
docs/ru/docs/advanced/websockets.md
docs/ru/docs/advanced/wsgi.md
docs/ru/docs/how-to/conditional-openapi.md
docs/ru/docs/how-to/configure-swagger-ui.md
docs/ru/docs/how-to/custom-docs-ui-assets.md
docs/ru/docs/how-to/extending-openapi.md
docs/ru/docs/how-to/graphql.md
docs/ru/docs/python-types.md
docs/ru/docs/tutorial/background-tasks.md
docs/ru/docs/tutorial/body-nested-models.md
docs/ru/docs/tutorial/body.md
docs/ru/docs/tutorial/cors.md
docs/ru/docs/tutorial/debugging.md
docs/ru/docs/tutorial/dependencies/classes-as-dependencies.md
docs/ru/docs/tutorial/dependencies/dependencies-with-yield.md
docs/ru/docs/tutorial/dependencies/global-dependencies.md
docs/ru/docs/tutorial/dependencies/sub-dependencies.md
docs/ru/docs/tutorial/first-steps.md
docs/ru/docs/tutorial/handling-errors.md
docs/ru/docs/tutorial/metadata.md
docs/ru/docs/tutorial/middleware.md
docs/ru/docs/tutorial/path-operation-configuration.md
docs/ru/docs/tutorial/path-params-numeric-validations.md
docs/ru/docs/tutorial/path-params.md
docs/ru/docs/tutorial/query-params-str-validations.md
docs/ru/docs/tutorial/query-params.md
docs/ru/docs/tutorial/response-model.md
docs/ru/docs/tutorial/response-status-code.md
docs/ru/docs/tutorial/static-files.md
docs/ru/docs/tutorial/testing.md
docs_src/additional_responses/tutorial001_py39.py [moved from docs_src/additional_responses/tutorial001.py with 100% similarity]
docs_src/additional_responses/tutorial002_py39.py [moved from docs_src/additional_responses/tutorial002.py with 100% similarity]
docs_src/additional_responses/tutorial003_py39.py [moved from docs_src/additional_responses/tutorial003.py with 100% similarity]
docs_src/additional_responses/tutorial004_py39.py [moved from docs_src/additional_responses/tutorial004.py with 100% similarity]
docs_src/additional_status_codes/tutorial001_an.py [deleted file]
docs_src/additional_status_codes/tutorial001_py39.py [moved from docs_src/additional_status_codes/tutorial001.py with 100% similarity]
docs_src/advanced_middleware/tutorial001_py39.py [moved from docs_src/advanced_middleware/tutorial001.py with 100% similarity]
docs_src/advanced_middleware/tutorial002_py39.py [moved from docs_src/advanced_middleware/tutorial002.py with 100% similarity]
docs_src/advanced_middleware/tutorial003_py39.py [moved from docs_src/advanced_middleware/tutorial003.py with 100% similarity]
docs_src/app_testing/app_a_py39/__init__.py [moved from docs_src/app_testing/app_b/__init__.py with 100% similarity]
docs_src/app_testing/app_a_py39/main.py [moved from docs_src/app_testing/main.py with 100% similarity]
docs_src/app_testing/app_a_py39/test_main.py [moved from docs_src/app_testing/test_main.py with 100% similarity]
docs_src/app_testing/app_b_an/main.py [deleted file]
docs_src/app_testing/app_b_an/test_main.py [deleted file]
docs_src/app_testing/app_b_py39/__init__.py [moved from docs_src/app_testing/app_b_an/__init__.py with 100% similarity]
docs_src/app_testing/app_b_py39/main.py [moved from docs_src/app_testing/app_b/main.py with 100% similarity]
docs_src/app_testing/app_b_py39/test_main.py [moved from docs_src/app_testing/app_b/test_main.py with 100% similarity]
docs_src/app_testing/tutorial001_py39.py [moved from docs_src/app_testing/tutorial001.py with 100% similarity]
docs_src/app_testing/tutorial002_py39.py [moved from docs_src/app_testing/tutorial002.py with 100% similarity]
docs_src/app_testing/tutorial003_py39.py [moved from docs_src/app_testing/tutorial003.py with 100% similarity]
docs_src/app_testing/tutorial004_py39.py [moved from docs_src/app_testing/tutorial004.py with 100% similarity]
docs_src/async_tests/app_a_py39/__init__.py [moved from docs_src/bigger_applications/app/__init__.py with 100% similarity]
docs_src/async_tests/app_a_py39/main.py [moved from docs_src/async_tests/main.py with 100% similarity]
docs_src/async_tests/app_a_py39/test_main.py [moved from docs_src/async_tests/test_main.py with 100% similarity]
docs_src/authentication_error_status_code/tutorial001_an.py [deleted file]
docs_src/background_tasks/tutorial001_py39.py [moved from docs_src/background_tasks/tutorial001.py with 100% similarity]
docs_src/background_tasks/tutorial002_an.py [deleted file]
docs_src/background_tasks/tutorial002_py39.py [moved from docs_src/background_tasks/tutorial002.py with 100% similarity]
docs_src/behind_a_proxy/tutorial001_01_py39.py [moved from docs_src/behind_a_proxy/tutorial001_01.py with 100% similarity]
docs_src/behind_a_proxy/tutorial001_py39.py [moved from docs_src/behind_a_proxy/tutorial001.py with 100% similarity]
docs_src/behind_a_proxy/tutorial002_py39.py [moved from docs_src/behind_a_proxy/tutorial002.py with 100% similarity]
docs_src/behind_a_proxy/tutorial003_py39.py [moved from docs_src/behind_a_proxy/tutorial003.py with 100% similarity]
docs_src/behind_a_proxy/tutorial004_py39.py [moved from docs_src/behind_a_proxy/tutorial004.py with 100% similarity]
docs_src/bigger_applications/app_an/dependencies.py [deleted file]
docs_src/bigger_applications/app_an/internal/admin.py [deleted file]
docs_src/bigger_applications/app_an/main.py [deleted file]
docs_src/bigger_applications/app_an/routers/items.py [deleted file]
docs_src/bigger_applications/app_an/routers/users.py [deleted file]
docs_src/bigger_applications/app_py39/__init__.py [moved from docs_src/bigger_applications/app/internal/__init__.py with 100% similarity]
docs_src/bigger_applications/app_py39/dependencies.py [moved from docs_src/bigger_applications/app/dependencies.py with 100% similarity]
docs_src/bigger_applications/app_py39/internal/__init__.py [moved from docs_src/bigger_applications/app/routers/__init__.py with 100% similarity]
docs_src/bigger_applications/app_py39/internal/admin.py [moved from docs_src/bigger_applications/app/internal/admin.py with 100% similarity]
docs_src/bigger_applications/app_py39/main.py [moved from docs_src/bigger_applications/app/main.py with 100% similarity]
docs_src/bigger_applications/app_py39/routers/__init__.py [moved from docs_src/bigger_applications/app_an/__init__.py with 100% similarity]
docs_src/bigger_applications/app_py39/routers/items.py [moved from docs_src/bigger_applications/app/routers/items.py with 100% similarity]
docs_src/bigger_applications/app_py39/routers/users.py [moved from docs_src/bigger_applications/app/routers/users.py with 100% similarity]
docs_src/body/tutorial001_py39.py [moved from docs_src/body/tutorial001.py with 100% similarity]
docs_src/body/tutorial002_py39.py [moved from docs_src/body/tutorial002.py with 100% similarity]
docs_src/body/tutorial003_py39.py [moved from docs_src/body/tutorial003.py with 100% similarity]
docs_src/body/tutorial004_py39.py [moved from docs_src/body/tutorial004.py with 100% similarity]
docs_src/body_fields/tutorial001_an.py [deleted file]
docs_src/body_fields/tutorial001_py39.py [moved from docs_src/body_fields/tutorial001.py with 100% similarity]
docs_src/body_multiple_params/tutorial001_an.py [deleted file]
docs_src/body_multiple_params/tutorial001_py39.py [moved from docs_src/body_multiple_params/tutorial001.py with 100% similarity]
docs_src/body_multiple_params/tutorial002_py39.py [moved from docs_src/body_multiple_params/tutorial002.py with 100% similarity]
docs_src/body_multiple_params/tutorial003_an.py [deleted file]
docs_src/body_multiple_params/tutorial003_py39.py [moved from docs_src/body_multiple_params/tutorial003.py with 100% similarity]
docs_src/body_multiple_params/tutorial004_an.py [deleted file]
docs_src/body_multiple_params/tutorial004_py39.py [moved from docs_src/body_multiple_params/tutorial004.py with 100% similarity]
docs_src/body_multiple_params/tutorial005_an.py [deleted file]
docs_src/body_multiple_params/tutorial005_py39.py [moved from docs_src/body_multiple_params/tutorial005.py with 100% similarity]
docs_src/body_nested_models/tutorial001_py39.py [moved from docs_src/body_nested_models/tutorial001.py with 100% similarity]
docs_src/body_nested_models/tutorial002.py [deleted file]
docs_src/body_nested_models/tutorial003.py [deleted file]
docs_src/body_nested_models/tutorial004.py [deleted file]
docs_src/body_nested_models/tutorial005.py [deleted file]
docs_src/body_nested_models/tutorial006.py [deleted file]
docs_src/body_nested_models/tutorial007.py [deleted file]
docs_src/body_nested_models/tutorial008.py [deleted file]
docs_src/body_nested_models/tutorial009.py [deleted file]
docs_src/body_updates/tutorial001.py [deleted file]
docs_src/body_updates/tutorial002.py [deleted file]
docs_src/conditional_openapi/tutorial001_py39.py [moved from docs_src/conditional_openapi/tutorial001.py with 100% similarity]
docs_src/configure_swagger_ui/tutorial001_py39.py [moved from docs_src/configure_swagger_ui/tutorial001.py with 100% similarity]
docs_src/configure_swagger_ui/tutorial002_py39.py [moved from docs_src/configure_swagger_ui/tutorial002.py with 100% similarity]
docs_src/configure_swagger_ui/tutorial003_py39.py [moved from docs_src/configure_swagger_ui/tutorial003.py with 100% similarity]
docs_src/cookie_param_models/tutorial001_an.py [deleted file]
docs_src/cookie_param_models/tutorial001_py39.py [moved from docs_src/cookie_param_models/tutorial001.py with 100% similarity]
docs_src/cookie_param_models/tutorial002_an.py [deleted file]
docs_src/cookie_param_models/tutorial002_pv1_an.py [deleted file]
docs_src/cookie_param_models/tutorial002_pv1_py39.py [moved from docs_src/cookie_param_models/tutorial002_pv1.py with 100% similarity]
docs_src/cookie_param_models/tutorial002_py39.py [moved from docs_src/cookie_param_models/tutorial002.py with 100% similarity]
docs_src/cookie_params/tutorial001_an.py [deleted file]
docs_src/cookie_params/tutorial001_py39.py [moved from docs_src/cookie_params/tutorial001.py with 100% similarity]
docs_src/cors/tutorial001_py39.py [moved from docs_src/cors/tutorial001.py with 100% similarity]
docs_src/custom_docs_ui/tutorial001_py39.py [moved from docs_src/custom_docs_ui/tutorial001.py with 100% similarity]
docs_src/custom_docs_ui/tutorial002_py39.py [moved from docs_src/custom_docs_ui/tutorial002.py with 100% similarity]
docs_src/custom_request_and_route/tutorial001.py [deleted file]
docs_src/custom_request_and_route/tutorial001_an.py [deleted file]
docs_src/custom_request_and_route/tutorial002.py [deleted file]
docs_src/custom_request_and_route/tutorial002_an.py [deleted file]
docs_src/custom_request_and_route/tutorial003_py39.py [moved from docs_src/custom_request_and_route/tutorial003.py with 100% similarity]
docs_src/custom_response/tutorial001_py39.py [moved from docs_src/custom_response/tutorial001.py with 100% similarity]
docs_src/custom_response/tutorial001b_py39.py [moved from docs_src/custom_response/tutorial001b.py with 100% similarity]
docs_src/custom_response/tutorial002_py39.py [moved from docs_src/custom_response/tutorial002.py with 100% similarity]
docs_src/custom_response/tutorial003_py39.py [moved from docs_src/custom_response/tutorial003.py with 100% similarity]
docs_src/custom_response/tutorial004_py39.py [moved from docs_src/custom_response/tutorial004.py with 100% similarity]
docs_src/custom_response/tutorial005_py39.py [moved from docs_src/custom_response/tutorial005.py with 100% similarity]
docs_src/custom_response/tutorial006_py39.py [moved from docs_src/custom_response/tutorial006.py with 100% similarity]
docs_src/custom_response/tutorial006b_py39.py [moved from docs_src/custom_response/tutorial006b.py with 100% similarity]
docs_src/custom_response/tutorial006c_py39.py [moved from docs_src/custom_response/tutorial006c.py with 100% similarity]
docs_src/custom_response/tutorial007_py39.py [moved from docs_src/custom_response/tutorial007.py with 100% similarity]
docs_src/custom_response/tutorial008_py39.py [moved from docs_src/custom_response/tutorial008.py with 100% similarity]
docs_src/custom_response/tutorial009_py39.py [moved from docs_src/custom_response/tutorial009.py with 100% similarity]
docs_src/custom_response/tutorial009b_py39.py [moved from docs_src/custom_response/tutorial009b.py with 100% similarity]
docs_src/custom_response/tutorial009c_py39.py [moved from docs_src/custom_response/tutorial009c.py with 100% similarity]
docs_src/custom_response/tutorial010_py39.py [moved from docs_src/custom_response/tutorial010.py with 100% similarity]
docs_src/dataclasses/tutorial001_py39.py [moved from docs_src/dataclasses/tutorial001.py with 100% similarity]
docs_src/dataclasses/tutorial002.py [deleted file]
docs_src/dataclasses/tutorial003.py [deleted file]
docs_src/debugging/tutorial001_py39.py [moved from docs_src/debugging/tutorial001.py with 100% similarity]
docs_src/dependencies/tutorial001_02_an.py [deleted file]
docs_src/dependencies/tutorial001_an.py [deleted file]
docs_src/dependencies/tutorial001_py39.py [moved from docs_src/dependencies/tutorial001.py with 100% similarity]
docs_src/dependencies/tutorial002_an.py [deleted file]
docs_src/dependencies/tutorial002_py39.py [moved from docs_src/dependencies/tutorial002.py with 100% similarity]
docs_src/dependencies/tutorial003_an.py [deleted file]
docs_src/dependencies/tutorial003_py39.py [moved from docs_src/dependencies/tutorial003.py with 100% similarity]
docs_src/dependencies/tutorial004_an.py [deleted file]
docs_src/dependencies/tutorial004_py39.py [moved from docs_src/dependencies/tutorial004.py with 100% similarity]
docs_src/dependencies/tutorial005_an.py [deleted file]
docs_src/dependencies/tutorial005_py39.py [moved from docs_src/dependencies/tutorial005.py with 100% similarity]
docs_src/dependencies/tutorial006_an.py [deleted file]
docs_src/dependencies/tutorial006_py39.py [moved from docs_src/dependencies/tutorial006.py with 100% similarity]
docs_src/dependencies/tutorial007_py39.py [moved from docs_src/dependencies/tutorial007.py with 100% similarity]
docs_src/dependencies/tutorial008_an.py [deleted file]
docs_src/dependencies/tutorial008_py39.py [moved from docs_src/dependencies/tutorial008.py with 100% similarity]
docs_src/dependencies/tutorial008b_an.py [deleted file]
docs_src/dependencies/tutorial008b_py39.py [moved from docs_src/dependencies/tutorial008b.py with 100% similarity]
docs_src/dependencies/tutorial008c_an.py [deleted file]
docs_src/dependencies/tutorial008c_py39.py [moved from docs_src/dependencies/tutorial008c.py with 100% similarity]
docs_src/dependencies/tutorial008d_an.py [deleted file]
docs_src/dependencies/tutorial008d_py39.py [moved from docs_src/dependencies/tutorial008d.py with 100% similarity]
docs_src/dependencies/tutorial008e_an.py [deleted file]
docs_src/dependencies/tutorial008e_py39.py [moved from docs_src/dependencies/tutorial008e.py with 100% similarity]
docs_src/dependencies/tutorial009.py [deleted file]
docs_src/dependencies/tutorial010_py39.py [moved from docs_src/dependencies/tutorial010.py with 100% similarity]
docs_src/dependencies/tutorial011_an.py [deleted file]
docs_src/dependencies/tutorial011_py39.py [moved from docs_src/dependencies/tutorial011.py with 100% similarity]
docs_src/dependencies/tutorial012_an.py [deleted file]
docs_src/dependencies/tutorial012_an_py39.py
docs_src/dependencies/tutorial012_py39.py [moved from docs_src/dependencies/tutorial012.py with 100% similarity]
docs_src/dependency_testing/tutorial001_an.py [deleted file]
docs_src/dependency_testing/tutorial001_py39.py [moved from docs_src/dependency_testing/tutorial001.py with 100% similarity]
docs_src/encoder/tutorial001_py39.py [moved from docs_src/encoder/tutorial001.py with 100% similarity]
docs_src/events/tutorial001_py39.py [moved from docs_src/events/tutorial001.py with 100% similarity]
docs_src/events/tutorial002_py39.py [moved from docs_src/events/tutorial002.py with 100% similarity]
docs_src/events/tutorial003_py39.py [moved from docs_src/events/tutorial003.py with 100% similarity]
docs_src/extending_openapi/tutorial001_py39.py [moved from docs_src/extending_openapi/tutorial001.py with 100% similarity]
docs_src/extra_data_types/tutorial001_an.py [deleted file]
docs_src/extra_data_types/tutorial001_py39.py [moved from docs_src/extra_data_types/tutorial001.py with 100% similarity]
docs_src/extra_models/tutorial001_py39.py [moved from docs_src/extra_models/tutorial001.py with 100% similarity]
docs_src/extra_models/tutorial002_py39.py [moved from docs_src/extra_models/tutorial002.py with 100% similarity]
docs_src/extra_models/tutorial003_py39.py [moved from docs_src/extra_models/tutorial003.py with 100% similarity]
docs_src/extra_models/tutorial004.py [deleted file]
docs_src/extra_models/tutorial005.py [deleted file]
docs_src/first_steps/tutorial001_py39.py [moved from docs_src/first_steps/tutorial001.py with 100% similarity]
docs_src/first_steps/tutorial002.py [deleted file]
docs_src/first_steps/tutorial003_py39.py [moved from docs_src/first_steps/tutorial003.py with 100% similarity]
docs_src/generate_clients/tutorial001.py [deleted file]
docs_src/generate_clients/tutorial002.py [deleted file]
docs_src/generate_clients/tutorial003.py [deleted file]
docs_src/generate_clients/tutorial004_py39.py [moved from docs_src/generate_clients/tutorial004.py with 100% similarity]
docs_src/graphql/tutorial001_py39.py [moved from docs_src/graphql/tutorial001.py with 100% similarity]
docs_src/handling_errors/tutorial001_py39.py [moved from docs_src/handling_errors/tutorial001.py with 100% similarity]
docs_src/handling_errors/tutorial002_py39.py [moved from docs_src/handling_errors/tutorial002.py with 100% similarity]
docs_src/handling_errors/tutorial003_py39.py [moved from docs_src/handling_errors/tutorial003.py with 100% similarity]
docs_src/handling_errors/tutorial004_py39.py [moved from docs_src/handling_errors/tutorial004.py with 100% similarity]
docs_src/handling_errors/tutorial005_py39.py [moved from docs_src/handling_errors/tutorial005.py with 100% similarity]
docs_src/handling_errors/tutorial006_py39.py [moved from docs_src/handling_errors/tutorial006.py with 100% similarity]
docs_src/header_param_models/tutorial001.py [deleted file]
docs_src/header_param_models/tutorial001_an.py [deleted file]
docs_src/header_param_models/tutorial002.py [deleted file]
docs_src/header_param_models/tutorial002_an.py [deleted file]
docs_src/header_param_models/tutorial002_pv1.py [deleted file]
docs_src/header_param_models/tutorial002_pv1_an.py [deleted file]
docs_src/header_param_models/tutorial003.py [deleted file]
docs_src/header_param_models/tutorial003_an.py [deleted file]
docs_src/header_params/tutorial001_an.py [deleted file]
docs_src/header_params/tutorial001_py39.py [moved from docs_src/header_params/tutorial001.py with 100% similarity]
docs_src/header_params/tutorial002_an.py [deleted file]
docs_src/header_params/tutorial002_py39.py [moved from docs_src/header_params/tutorial002.py with 100% similarity]
docs_src/header_params/tutorial003.py [deleted file]
docs_src/header_params/tutorial003_an.py [deleted file]
docs_src/metadata/tutorial001_1_py39.py [moved from docs_src/metadata/tutorial001_1.py with 100% similarity]
docs_src/metadata/tutorial001_py39.py [moved from docs_src/metadata/tutorial001.py with 100% similarity]
docs_src/metadata/tutorial002_py39.py [moved from docs_src/metadata/tutorial002.py with 100% similarity]
docs_src/metadata/tutorial003_py39.py [moved from docs_src/metadata/tutorial003.py with 100% similarity]
docs_src/metadata/tutorial004_py39.py [moved from docs_src/metadata/tutorial004.py with 100% similarity]
docs_src/middleware/tutorial001_py39.py [moved from docs_src/middleware/tutorial001.py with 100% similarity]
docs_src/openapi_callbacks/tutorial001_py39.py [moved from docs_src/openapi_callbacks/tutorial001.py with 100% similarity]
docs_src/openapi_webhooks/tutorial001_py39.py [moved from docs_src/openapi_webhooks/tutorial001.py with 100% similarity]
docs_src/path_operation_advanced_configuration/tutorial001_py39.py [moved from docs_src/path_operation_advanced_configuration/tutorial001.py with 100% similarity]
docs_src/path_operation_advanced_configuration/tutorial002_py39.py [moved from docs_src/path_operation_advanced_configuration/tutorial002.py with 100% similarity]
docs_src/path_operation_advanced_configuration/tutorial003_py39.py [moved from docs_src/path_operation_advanced_configuration/tutorial003.py with 100% similarity]
docs_src/path_operation_advanced_configuration/tutorial004.py [deleted file]
docs_src/path_operation_advanced_configuration/tutorial005_py39.py [moved from docs_src/path_operation_advanced_configuration/tutorial005.py with 100% similarity]
docs_src/path_operation_advanced_configuration/tutorial006_py39.py [moved from docs_src/path_operation_advanced_configuration/tutorial006.py with 100% similarity]
docs_src/path_operation_advanced_configuration/tutorial007.py [deleted file]
docs_src/path_operation_advanced_configuration/tutorial007_pv1.py [deleted file]
docs_src/path_operation_configuration/tutorial001.py [deleted file]
docs_src/path_operation_configuration/tutorial002.py [deleted file]
docs_src/path_operation_configuration/tutorial002b_py39.py [moved from docs_src/path_operation_configuration/tutorial002b.py with 100% similarity]
docs_src/path_operation_configuration/tutorial003.py [deleted file]
docs_src/path_operation_configuration/tutorial004.py [deleted file]
docs_src/path_operation_configuration/tutorial005.py [deleted file]
docs_src/path_operation_configuration/tutorial006_py39.py [moved from docs_src/path_operation_configuration/tutorial006.py with 100% similarity]
docs_src/path_params/tutorial001_py39.py [moved from docs_src/path_params/tutorial001.py with 100% similarity]
docs_src/path_params/tutorial002_py39.py [moved from docs_src/path_params/tutorial002.py with 100% similarity]
docs_src/path_params/tutorial003_py39.py [moved from docs_src/path_params/tutorial003.py with 100% similarity]
docs_src/path_params/tutorial003b_py39.py [moved from docs_src/path_params/tutorial003b.py with 100% similarity]
docs_src/path_params/tutorial004_py39.py [moved from docs_src/path_params/tutorial004.py with 100% similarity]
docs_src/path_params/tutorial005_py39.py [moved from docs_src/path_params/tutorial005.py with 100% similarity]
docs_src/path_params_numeric_validations/tutorial001_an.py [deleted file]
docs_src/path_params_numeric_validations/tutorial001_py39.py [moved from docs_src/path_params_numeric_validations/tutorial001.py with 100% similarity]
docs_src/path_params_numeric_validations/tutorial002_an.py [deleted file]
docs_src/path_params_numeric_validations/tutorial002_py39.py [moved from docs_src/path_params_numeric_validations/tutorial002.py with 100% similarity]
docs_src/path_params_numeric_validations/tutorial003_an.py [deleted file]
docs_src/path_params_numeric_validations/tutorial003_py39.py [moved from docs_src/path_params_numeric_validations/tutorial003.py with 100% similarity]
docs_src/path_params_numeric_validations/tutorial004_an.py [deleted file]
docs_src/path_params_numeric_validations/tutorial004_py39.py [moved from docs_src/path_params_numeric_validations/tutorial004.py with 100% similarity]
docs_src/path_params_numeric_validations/tutorial005_an.py [deleted file]
docs_src/path_params_numeric_validations/tutorial005_py39.py [moved from docs_src/path_params_numeric_validations/tutorial005.py with 100% similarity]
docs_src/path_params_numeric_validations/tutorial006_an.py [deleted file]
docs_src/path_params_numeric_validations/tutorial006_py39.py [moved from docs_src/path_params_numeric_validations/tutorial006.py with 100% similarity]
docs_src/pydantic_v1_in_v2/tutorial001_an_py39.py [moved from docs_src/pydantic_v1_in_v2/tutorial001_an.py with 100% similarity]
docs_src/pydantic_v1_in_v2/tutorial002_an_py39.py [moved from docs_src/pydantic_v1_in_v2/tutorial002_an.py with 100% similarity]
docs_src/pydantic_v1_in_v2/tutorial003_an_py39.py [moved from docs_src/pydantic_v1_in_v2/tutorial003_an.py with 100% similarity]
docs_src/pydantic_v1_in_v2/tutorial004_an.py [deleted file]
docs_src/python_types/tutorial001_py39.py [moved from docs_src/python_types/tutorial001.py with 100% similarity]
docs_src/python_types/tutorial002_py39.py [moved from docs_src/python_types/tutorial002.py with 100% similarity]
docs_src/python_types/tutorial003_py39.py [moved from docs_src/python_types/tutorial003.py with 100% similarity]
docs_src/python_types/tutorial004_py39.py [moved from docs_src/python_types/tutorial004.py with 100% similarity]
docs_src/python_types/tutorial005_py39.py [moved from docs_src/python_types/tutorial005.py with 100% similarity]
docs_src/python_types/tutorial006.py [deleted file]
docs_src/python_types/tutorial007.py [deleted file]
docs_src/python_types/tutorial008.py [deleted file]
docs_src/python_types/tutorial008b_py39.py [moved from docs_src/python_types/tutorial008b.py with 100% similarity]
docs_src/python_types/tutorial009_py39.py [moved from docs_src/python_types/tutorial009.py with 100% similarity]
docs_src/python_types/tutorial009b_py39.py [moved from docs_src/python_types/tutorial009b.py with 100% similarity]
docs_src/python_types/tutorial009c_py39.py [moved from docs_src/python_types/tutorial009c.py with 100% similarity]
docs_src/python_types/tutorial010_py39.py [moved from docs_src/python_types/tutorial010.py with 100% similarity]
docs_src/python_types/tutorial011.py [deleted file]
docs_src/python_types/tutorial012_py39.py [moved from docs_src/python_types/tutorial012.py with 100% similarity]
docs_src/python_types/tutorial013.py [deleted file]
docs_src/query_param_models/tutorial001.py [deleted file]
docs_src/query_param_models/tutorial001_an.py [deleted file]
docs_src/query_param_models/tutorial001_an_py39.py
docs_src/query_param_models/tutorial001_py39.py
docs_src/query_param_models/tutorial002.py [deleted file]
docs_src/query_param_models/tutorial002_an.py [deleted file]
docs_src/query_param_models/tutorial002_an_py39.py
docs_src/query_param_models/tutorial002_pv1.py [deleted file]
docs_src/query_param_models/tutorial002_pv1_an.py [deleted file]
docs_src/query_param_models/tutorial002_pv1_an_py39.py
docs_src/query_param_models/tutorial002_pv1_py39.py
docs_src/query_param_models/tutorial002_py39.py
docs_src/query_params/tutorial001_py39.py [moved from docs_src/query_params/tutorial001.py with 100% similarity]
docs_src/query_params/tutorial002_py39.py [moved from docs_src/query_params/tutorial002.py with 100% similarity]
docs_src/query_params/tutorial003_py39.py [moved from docs_src/query_params/tutorial003.py with 100% similarity]
docs_src/query_params/tutorial004_py39.py [moved from docs_src/query_params/tutorial004.py with 100% similarity]
docs_src/query_params/tutorial005_py39.py [moved from docs_src/query_params/tutorial005.py with 100% similarity]
docs_src/query_params/tutorial006_py39.py [moved from docs_src/query_params/tutorial006.py with 100% similarity]
docs_src/query_params/tutorial006b.py [deleted file]
docs_src/query_params_str_validations/tutorial001_py39.py [moved from docs_src/query_params_str_validations/tutorial001.py with 100% similarity]
docs_src/query_params_str_validations/tutorial002_an_py39.py [moved from docs_src/query_params_str_validations/tutorial002_an.py with 81% similarity]
docs_src/query_params_str_validations/tutorial002_py39.py [moved from docs_src/query_params_str_validations/tutorial002.py with 100% similarity]
docs_src/query_params_str_validations/tutorial003_an.py [deleted file]
docs_src/query_params_str_validations/tutorial003_py39.py [moved from docs_src/query_params_str_validations/tutorial003.py with 100% similarity]
docs_src/query_params_str_validations/tutorial004_an.py [deleted file]
docs_src/query_params_str_validations/tutorial004_py39.py [moved from docs_src/query_params_str_validations/tutorial004.py with 100% similarity]
docs_src/query_params_str_validations/tutorial005_an.py [deleted file]
docs_src/query_params_str_validations/tutorial005_py39.py [moved from docs_src/query_params_str_validations/tutorial005.py with 100% similarity]
docs_src/query_params_str_validations/tutorial006_an.py [deleted file]
docs_src/query_params_str_validations/tutorial006_py39.py [moved from docs_src/query_params_str_validations/tutorial006.py with 100% similarity]
docs_src/query_params_str_validations/tutorial006c_an.py [deleted file]
docs_src/query_params_str_validations/tutorial006c_py39.py [moved from docs_src/query_params_str_validations/tutorial006c.py with 100% similarity]
docs_src/query_params_str_validations/tutorial007_an.py [deleted file]
docs_src/query_params_str_validations/tutorial007_py39.py [moved from docs_src/query_params_str_validations/tutorial007.py with 100% similarity]
docs_src/query_params_str_validations/tutorial008_an.py [deleted file]
docs_src/query_params_str_validations/tutorial008_py39.py [moved from docs_src/query_params_str_validations/tutorial008.py with 100% similarity]
docs_src/query_params_str_validations/tutorial009_an.py [deleted file]
docs_src/query_params_str_validations/tutorial009_py39.py [moved from docs_src/query_params_str_validations/tutorial009.py with 100% similarity]
docs_src/query_params_str_validations/tutorial010_an.py [deleted file]
docs_src/query_params_str_validations/tutorial010_py39.py [moved from docs_src/query_params_str_validations/tutorial010.py with 100% similarity]
docs_src/query_params_str_validations/tutorial011.py [deleted file]
docs_src/query_params_str_validations/tutorial011_an.py [deleted file]
docs_src/query_params_str_validations/tutorial012.py [deleted file]
docs_src/query_params_str_validations/tutorial012_an.py [deleted file]
docs_src/query_params_str_validations/tutorial013_an.py [deleted file]
docs_src/query_params_str_validations/tutorial013_py39.py [moved from docs_src/query_params_str_validations/tutorial013.py with 100% similarity]
docs_src/query_params_str_validations/tutorial014_an.py [deleted file]
docs_src/query_params_str_validations/tutorial014_py39.py [moved from docs_src/query_params_str_validations/tutorial014.py with 100% similarity]
docs_src/query_params_str_validations/tutorial015_an.py [deleted file]
docs_src/request_files/tutorial001_02_an.py [deleted file]
docs_src/request_files/tutorial001_02_py39.py [moved from docs_src/request_files/tutorial001_02.py with 100% similarity]
docs_src/request_files/tutorial001_03_an.py [deleted file]
docs_src/request_files/tutorial001_03_py39.py [moved from docs_src/request_files/tutorial001_03.py with 100% similarity]
docs_src/request_files/tutorial001_an.py [deleted file]
docs_src/request_files/tutorial001_py39.py [moved from docs_src/request_files/tutorial001.py with 100% similarity]
docs_src/request_files/tutorial002.py [deleted file]
docs_src/request_files/tutorial002_an.py [deleted file]
docs_src/request_files/tutorial003.py [deleted file]
docs_src/request_files/tutorial003_an.py [deleted file]
docs_src/request_form_models/tutorial001_an.py [deleted file]
docs_src/request_form_models/tutorial001_py39.py [moved from docs_src/request_form_models/tutorial001.py with 100% similarity]
docs_src/request_form_models/tutorial002_an.py [deleted file]
docs_src/request_form_models/tutorial002_pv1_an.py [deleted file]
docs_src/request_form_models/tutorial002_pv1_py39.py [moved from docs_src/request_form_models/tutorial002_pv1.py with 100% similarity]
docs_src/request_form_models/tutorial002_py39.py [moved from docs_src/request_form_models/tutorial002.py with 100% similarity]
docs_src/request_forms/tutorial001_an.py [deleted file]
docs_src/request_forms/tutorial001_py39.py [moved from docs_src/request_forms/tutorial001.py with 100% similarity]
docs_src/request_forms_and_files/tutorial001_an.py [deleted file]
docs_src/request_forms_and_files/tutorial001_py39.py [moved from docs_src/request_forms_and_files/tutorial001.py with 100% similarity]
docs_src/response_change_status_code/tutorial001_py39.py [moved from docs_src/response_change_status_code/tutorial001.py with 100% similarity]
docs_src/response_cookies/tutorial001_py39.py [moved from docs_src/response_cookies/tutorial001.py with 100% similarity]
docs_src/response_cookies/tutorial002_py39.py [moved from docs_src/response_cookies/tutorial002.py with 100% similarity]
docs_src/response_directly/tutorial001_py39.py [moved from docs_src/response_directly/tutorial001.py with 100% similarity]
docs_src/response_directly/tutorial002_py39.py [moved from docs_src/response_directly/tutorial002.py with 100% similarity]
docs_src/response_headers/tutorial001_py39.py [moved from docs_src/response_headers/tutorial001.py with 100% similarity]
docs_src/response_headers/tutorial002_py39.py [moved from docs_src/response_headers/tutorial002.py with 100% similarity]
docs_src/response_model/tutorial001.py [deleted file]
docs_src/response_model/tutorial001_01.py [deleted file]
docs_src/response_model/tutorial002_py39.py [moved from docs_src/response_model/tutorial002.py with 100% similarity]
docs_src/response_model/tutorial003_01_py39.py [moved from docs_src/response_model/tutorial003_01.py with 100% similarity]
docs_src/response_model/tutorial003_02_py39.py [moved from docs_src/response_model/tutorial003_02.py with 100% similarity]
docs_src/response_model/tutorial003_03_py39.py [moved from docs_src/response_model/tutorial003_03.py with 100% similarity]
docs_src/response_model/tutorial003_04_py39.py [moved from docs_src/response_model/tutorial003_04.py with 100% similarity]
docs_src/response_model/tutorial003_05_py39.py [moved from docs_src/response_model/tutorial003_05.py with 100% similarity]
docs_src/response_model/tutorial003_py39.py [moved from docs_src/response_model/tutorial003.py with 100% similarity]
docs_src/response_model/tutorial004.py [deleted file]
docs_src/response_model/tutorial005_py39.py [moved from docs_src/response_model/tutorial005.py with 100% similarity]
docs_src/response_model/tutorial006_py39.py [moved from docs_src/response_model/tutorial006.py with 100% similarity]
docs_src/response_status_code/tutorial001_py39.py [moved from docs_src/response_status_code/tutorial001.py with 100% similarity]
docs_src/response_status_code/tutorial002_py39.py [moved from docs_src/response_status_code/tutorial002.py with 100% similarity]
docs_src/schema_extra_example/tutorial001_pv1_py39.py [moved from docs_src/schema_extra_example/tutorial001_pv1.py with 100% similarity]
docs_src/schema_extra_example/tutorial001_py39.py [moved from docs_src/schema_extra_example/tutorial001.py with 100% similarity]
docs_src/schema_extra_example/tutorial002_py39.py [moved from docs_src/schema_extra_example/tutorial002.py with 100% similarity]
docs_src/schema_extra_example/tutorial003_an.py [deleted file]
docs_src/schema_extra_example/tutorial003_py39.py [moved from docs_src/schema_extra_example/tutorial003.py with 100% similarity]
docs_src/schema_extra_example/tutorial004_an.py [deleted file]
docs_src/schema_extra_example/tutorial004_py39.py [moved from docs_src/schema_extra_example/tutorial004.py with 100% similarity]
docs_src/schema_extra_example/tutorial005_an.py [deleted file]
docs_src/schema_extra_example/tutorial005_py39.py [moved from docs_src/schema_extra_example/tutorial005.py with 100% similarity]
docs_src/security/tutorial001_an.py [deleted file]
docs_src/security/tutorial001_py39.py [moved from docs_src/security/tutorial001.py with 100% similarity]
docs_src/security/tutorial002_an.py [deleted file]
docs_src/security/tutorial002_py39.py [moved from docs_src/security/tutorial002.py with 100% similarity]
docs_src/security/tutorial003_an.py [deleted file]
docs_src/security/tutorial003_py39.py [moved from docs_src/security/tutorial003.py with 100% similarity]
docs_src/security/tutorial004_an.py [deleted file]
docs_src/security/tutorial004_py39.py [moved from docs_src/security/tutorial004.py with 100% similarity]
docs_src/security/tutorial005.py [deleted file]
docs_src/security/tutorial005_an.py [deleted file]
docs_src/security/tutorial006_an.py [deleted file]
docs_src/security/tutorial006_py39.py [moved from docs_src/security/tutorial006.py with 100% similarity]
docs_src/security/tutorial007_an.py [deleted file]
docs_src/security/tutorial007_py39.py [moved from docs_src/security/tutorial007.py with 100% similarity]
docs_src/separate_openapi_schemas/tutorial001.py [deleted file]
docs_src/separate_openapi_schemas/tutorial002.py [deleted file]
docs_src/settings/app01_py39/__init__.py [moved from docs_src/bigger_applications/app_an/internal/__init__.py with 100% similarity]
docs_src/settings/app01_py39/config.py [moved from docs_src/settings/app01/config.py with 100% similarity]
docs_src/settings/app01_py39/main.py [moved from docs_src/settings/app01/main.py with 100% similarity]
docs_src/settings/app02/__init__.py [deleted file]
docs_src/settings/app02_an/__init__.py [deleted file]
docs_src/settings/app02_an/config.py [deleted file]
docs_src/settings/app02_an/main.py [deleted file]
docs_src/settings/app02_an/test_main.py [deleted file]
docs_src/settings/app02_py39/__init__.py [moved from docs_src/bigger_applications/app_an/routers/__init__.py with 100% similarity]
docs_src/settings/app02_py39/config.py [moved from docs_src/settings/app02/config.py with 100% similarity]
docs_src/settings/app02_py39/main.py [moved from docs_src/settings/app02/main.py with 100% similarity]
docs_src/settings/app02_py39/test_main.py [moved from docs_src/settings/app02/test_main.py with 100% similarity]
docs_src/settings/app03/__init__.py [deleted file]
docs_src/settings/app03_an/__init__.py [deleted file]
docs_src/settings/app03_an/config.py [deleted file]
docs_src/settings/app03_an/config_pv1.py [deleted file]
docs_src/settings/app03_an/main.py [deleted file]
docs_src/settings/app03_py39/__init__.py [moved from docs_src/settings/app01/__init__.py with 100% similarity]
docs_src/settings/app03_py39/config.py [moved from docs_src/settings/app03/config.py with 100% similarity]
docs_src/settings/app03_py39/config_pv1.py [moved from docs_src/settings/app03/config_pv1.py with 100% similarity]
docs_src/settings/app03_py39/main.py [moved from docs_src/settings/app03/main.py with 100% similarity]
docs_src/settings/tutorial001_pv1_py39.py [moved from docs_src/settings/tutorial001_pv1.py with 100% similarity]
docs_src/settings/tutorial001_py39.py [moved from docs_src/settings/tutorial001.py with 100% similarity]
docs_src/sql_databases/tutorial001.py [deleted file]
docs_src/sql_databases/tutorial001_an.py [deleted file]
docs_src/sql_databases/tutorial002.py [deleted file]
docs_src/sql_databases/tutorial002_an.py [deleted file]
docs_src/static_files/tutorial001_py39.py [moved from docs_src/static_files/tutorial001.py with 100% similarity]
docs_src/sub_applications/tutorial001_py39.py [moved from docs_src/sub_applications/tutorial001.py with 100% similarity]
docs_src/templates/tutorial001_py39.py [moved from docs_src/templates/tutorial001.py with 100% similarity]
docs_src/using_request_directly/tutorial001_py39.py [moved from docs_src/using_request_directly/tutorial001.py with 100% similarity]
docs_src/websockets/tutorial001_py39.py [moved from docs_src/websockets/tutorial001.py with 100% similarity]
docs_src/websockets/tutorial002_an.py [deleted file]
docs_src/websockets/tutorial002_py39.py [moved from docs_src/websockets/tutorial002.py with 100% similarity]
docs_src/websockets/tutorial003.py [deleted file]
docs_src/wsgi/tutorial001_py39.py [moved from docs_src/wsgi/tutorial001.py with 100% similarity]
fastapi/_compat/shared.py
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 [moved from tests/test_tutorial/test_async_tests/test_main.py with 58% similarity]
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_fields/test_tutorial001.py
tests/test_tutorial/test_body_multiple_params/test_tutorial001.py
tests/test_tutorial/test_body_multiple_params/test_tutorial003.py
tests/test_tutorial/test_body_nested_models/test_tutorial009.py
tests/test_tutorial/test_body_updates/test_tutorial001.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_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_dependencies/test_tutorial001.py
tests/test_tutorial/test_dependencies/test_tutorial004.py
tests/test_tutorial/test_dependencies/test_tutorial006.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_tutorial012.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_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.py
tests/test_tutorial/test_generate_clients/test_tutorial003.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_tutorial004.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_advanced_configurations/test_tutorial007_pv1.py
tests/test_tutorial/test_path_operation_configurations/test_tutorial002b.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_tutorial004.py
tests/test_tutorial/test_path_params/test_tutorial005.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial001.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial002.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial003.py
tests/test_tutorial/test_pydantic_v1_in_v2/test_tutorial004.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_tutorial005.py
tests/test_tutorial/test_query_params/test_tutorial006.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_form_models/test_tutorial002_pv1.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_headers/test_tutorial001.py
tests/test_tutorial/test_response_headers/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_schema_extra_example/test_tutorial001.py
tests/test_tutorial/test_schema_extra_example/test_tutorial001_pv1.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_tutorial003.py
tests/test_tutorial/test_security/test_tutorial005.py
tests/test_tutorial/test_security/test_tutorial006.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_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_sub_applications/test_tutorial001.py
tests/test_tutorial/test_templates/test_tutorial001.py
tests/test_tutorial/test_testing/test_main_a.py [moved from tests/test_tutorial/test_testing/test_main.py with 90% similarity]
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 c430854265b855f9404ab8ddd78e53fc804ce06b..8a839a928a8b70e8b0fcbf2d5e2c45c47e1f30df 100644 (file)
@@ -46,13 +46,6 @@ jobs:
         python-version: [ "3.14" ]
         pydantic-version: [ "pydantic>=2.0.2,<3.0.0" ]
         include:
-          - os: macos-latest
-            python-version: "3.8"
-            pydantic-version: "pydantic>=1.10.0,<2.0.0"
-          - os: windows-latest
-            python-version: "3.8"
-            pydantic-version: "pydantic>=2.0.2,<3.0.0"
-            coverage: coverage
           - os: ubuntu-latest
             python-version: "3.9"
             pydantic-version: "pydantic>=1.10.0,<2.0.0"
@@ -101,10 +94,6 @@ jobs:
         run: uv pip install -r requirements-tests.txt
       - name: Install Pydantic
         run: uv pip install "${{ matrix.pydantic-version }}"
-      # TODO: Remove this once Python 3.8 is no longer supported
-      - name: Install older AnyIO in Python 3.8
-        if: matrix.python-version == '3.8'
-        run: uv pip install "anyio[trio]<4.0.0"
       - run: mkdir coverage
       - name: Test
         run: bash scripts/test.sh
@@ -131,7 +120,7 @@ jobs:
       - uses: actions/checkout@v6
       - uses: actions/setup-python@v6
         with:
-          python-version: '3.8'
+          python-version: '3.11'
       - name: Setup uv
         uses: astral-sh/setup-uv@v7
         with:
index 29a0a147775126eeb3f0094a814347054c011849..0f9b122516679f6fdb806332639b3488904ec056 100644 (file)
@@ -26,7 +26,7 @@ Jedes dieser Response-`dict`s kann einen Schlüssel `model` haben, welcher ein P
 
 Um beispielsweise eine weitere Response mit dem Statuscode `404` und einem Pydantic-Modell `Message` zu deklarieren, können Sie schreiben:
 
-{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
 
 /// note | Hinweis
 
@@ -203,7 +203,7 @@ Sie können beispielsweise eine Response mit dem Statuscode `404` deklarieren, d
 
 Und eine Response mit dem Statuscode `200`, die Ihr `response_model` verwendet, aber ein benutzerdefiniertes Beispiel (`example`) enthält:
 
-{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
 
 Es wird alles kombiniert und in Ihre OpenAPI eingebunden und in der API-Dokumentation angezeigt:
 
index ad824520527f785b568c2c733292fb0e0e1ffc88..7206f136fd348e7eff0cd0b392f6dce43d51b138 100644 (file)
@@ -32,11 +32,11 @@ Betrachten wir als einfaches Beispiel eine Dateistruktur ähnlich der in [Größ
 
 Die Datei `main.py` hätte als Inhalt:
 
-{* ../../docs_src/async_tests/main.py *}
+{* ../../docs_src/async_tests/app_a_py39/main.py *}
 
 Die Datei `test_main.py` hätte die Tests für `main.py`, das könnte jetzt so aussehen:
 
-{* ../../docs_src/async_tests/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
 
 ## Es ausführen { #run-it }
 
@@ -56,7 +56,7 @@ $ pytest
 
 Der Marker `@pytest.mark.anyio` teilt pytest mit, dass diese Testfunktion asynchron aufgerufen werden soll:
 
-{* ../../docs_src/async_tests/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
 
 /// tip | Tipp
 
@@ -66,7 +66,7 @@ Beachten Sie, dass die Testfunktion jetzt `async def` ist und nicht nur `def` wi
 
 Dann können wir einen `AsyncClient` mit der App erstellen und mit `await` asynchrone Requests an ihn senden.
 
-{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
 
 Das ist das Äquivalent zu:
 
index 183d0beeef567a950e8dd33035c1ff8bd3f96e37..1c74590503fd97d86015938e7d24d3f44d2d2498 100644 (file)
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
 
 Angenommen, Sie definieren eine *Pfadoperation* `/items/`:
 
-{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
 
 Wenn der Client versucht, zu `/items` zu gehen, würde er standardmäßig zu `/items/` umgeleitet.
 
@@ -115,7 +115,7 @@ In diesem Fall würde der ursprüngliche Pfad `/app` tatsächlich unter `/api/v1
 
 Auch wenn Ihr gesamter Code unter der Annahme geschrieben ist, dass es nur `/app` gibt.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
 
 Und der Proxy würde das **Pfadpräfix** on-the-fly **„entfernen“**, bevor er den <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr> an den Anwendungsserver (wahrscheinlich Uvicorn via FastAPI CLI) übermittelt, dafür sorgend, dass Ihre Anwendung davon überzeugt ist, dass sie unter `/app` bereitgestellt wird, sodass Sie nicht Ihren gesamten Code dahingehend aktualisieren müssen, das Präfix `/api/v1` zu verwenden.
 
@@ -193,7 +193,7 @@ Sie können den aktuellen `root_path` abrufen, der von Ihrer Anwendung für jede
 
 Hier fügen wir ihn, nur zu Demonstrationszwecken, in die Nachricht ein.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
 
 Wenn Sie Uvicorn dann starten mit:
 
@@ -220,7 +220,7 @@ wäre die <abbr title="Response – Antwort: Daten, die der Server zum anfragend
 
 Falls Sie keine Möglichkeit haben, eine Kommandozeilenoption wie `--root-path` oder ähnlich zu übergeben, können Sie, alternativ dazu, beim Erstellen Ihrer FastAPI-Anwendung den Parameter `root_path` setzen:
 
-{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
 
 Die Übergabe des `root_path` an `FastAPI` wäre das Äquivalent zur Übergabe der `--root-path`-Kommandozeilenoption an Uvicorn oder Hypercorn.
 
@@ -400,7 +400,7 @@ Wenn Sie eine benutzerdefinierte Liste von Servern (`servers`) übergeben und es
 
 Zum Beispiel:
 
-{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
 
 Erzeugt ein OpenAPI-Schema, wie:
 
@@ -455,7 +455,7 @@ Wenn Sie den Parameter `servers` nicht angeben und `root_path` den Wert `/` hat,
 
 Wenn Sie nicht möchten, dass **FastAPI** einen automatischen Server inkludiert, welcher `root_path` verwendet, können Sie den Parameter `root_path_in_servers=False` verwenden:
 
-{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
 
 Dann wird er nicht in das OpenAPI-Schema aufgenommen.
 
index 8714086e59632eb83c7523f3f454c500ff2f7379..1226fcb20cdbdd289d3e701a11d1bea3272ef25e 100644 (file)
@@ -30,7 +30,7 @@ Das liegt daran, dass FastAPI standardmäßig jedes enthaltene Element überprü
 
 Wenn Sie jedoch sicher sind, dass der von Ihnen zurückgegebene Inhalt **mit JSON serialisierbar** ist, können Sie ihn direkt an die Response-Klasse übergeben und die zusätzliche Arbeit vermeiden, die FastAPI hätte, indem es Ihren zurückgegebenen Inhalt durch den `jsonable_encoder` leitet, bevor es ihn an die Response-Klasse übergibt.
 
-{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
 
 /// info | Info
 
@@ -55,7 +55,7 @@ Um eine Response mit HTML direkt von **FastAPI** zurückzugeben, verwenden Sie `
 * Importieren Sie `HTMLResponse`.
 * Übergeben Sie `HTMLResponse` als den Parameter `response_class` Ihres *Pfadoperation-Dekorators*.
 
-{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
 
 /// info | Info
 
@@ -73,7 +73,7 @@ Wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link
 
 Das gleiche Beispiel von oben, das eine `HTMLResponse` zurückgibt, könnte so aussehen:
 
-{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
 
 /// warning | Achtung
 
@@ -97,7 +97,7 @@ Die `response_class` wird dann nur zur Dokumentation der OpenAPI-*Pfadoperation*
 
 Es könnte zum Beispiel so etwas sein:
 
-{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
 
 In diesem Beispiel generiert die Funktion `generate_html_response()` bereits eine `Response` und gibt sie zurück, anstatt das HTML in einem `str` zurückzugeben.
 
@@ -136,7 +136,7 @@ Sie akzeptiert die folgenden Parameter:
 
 FastAPI (eigentlich Starlette) fügt automatisch einen Content-Length-Header ein. Außerdem wird es einen Content-Type-Header einfügen, der auf dem media_type basiert, und für Texttypen einen Zeichensatz (charset) anfügen.
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ### `HTMLResponse` { #htmlresponse }
 
@@ -146,7 +146,7 @@ Nimmt Text oder Bytes entgegen und gibt eine HTML-Response zurück, wie Sie oben
 
 Nimmt Text oder Bytes entgegen und gibt eine Plain-Text-Response zurück.
 
-{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
 
 ### `JSONResponse` { #jsonresponse }
 
@@ -180,7 +180,7 @@ Dazu muss `ujson` installiert werden, z. B. mit `pip install ujson`.
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
 
 /// tip | Tipp
 
@@ -194,13 +194,13 @@ Gibt eine HTTP-Weiterleitung (HTTP-Redirect) zurück. Verwendet standardmäßig
 
 Sie können eine `RedirectResponse` direkt zurückgeben:
 
-{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
 
 ---
 
 Oder Sie können sie im Parameter `response_class` verwenden:
 
-{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
 
 Wenn Sie das tun, können Sie die URL direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
 
@@ -210,13 +210,13 @@ In diesem Fall ist der verwendete `status_code` der Standardcode für die `Redir
 
 Sie können den Parameter `status_code` auch in Kombination mit dem Parameter `response_class` verwenden:
 
-{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
 
 ### `StreamingResponse` { #streamingresponse }
 
 Nimmt einen asynchronen Generator oder einen normalen Generator/Iterator und streamt den Responsebody.
 
-{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
 
 #### Verwendung von `StreamingResponse` mit dateiartigen Objekten { #using-streamingresponse-with-file-like-objects }
 
@@ -226,7 +226,7 @@ Auf diese Weise müssen Sie nicht alles zuerst in den Arbeitsspeicher lesen und
 
 Das umfasst viele Bibliotheken zur Interaktion mit Cloud-Speicher, Videoverarbeitung und anderen.
 
-{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
 
 1. Das ist die Generatorfunktion. Es handelt sich um eine „Generatorfunktion“, da sie `yield`-Anweisungen enthält.
 2. Durch die Verwendung eines `with`-Blocks stellen wir sicher, dass das dateiartige Objekt geschlossen wird, nachdem die Generatorfunktion fertig ist. Also, nachdem sie mit dem Senden der Response fertig ist.
@@ -255,11 +255,11 @@ Nimmt zur Instanziierung einen anderen Satz von Argumenten entgegen als die ande
 
 Datei-Responses enthalten die entsprechenden `Content-Length`-, `Last-Modified`- und `ETag`-Header.
 
-{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
 
 Sie können auch den Parameter `response_class` verwenden:
 
-{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
 
 In diesem Fall können Sie den Dateipfad direkt von Ihrer *Pfadoperation*-Funktion zurückgeben.
 
@@ -273,7 +273,7 @@ Sie möchten etwa, dass Ihre Response eingerücktes und formatiertes JSON zurüc
 
 Sie könnten eine `CustomORJSONResponse` erstellen. Das Wichtigste, was Sie tun müssen, ist, eine `Response.render(content)`-Methode zu erstellen, die den Inhalt als `bytes` zurückgibt:
 
-{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
 
 Statt:
 
@@ -299,7 +299,7 @@ Der Parameter, der das definiert, ist `default_response_class`.
 
 Im folgenden Beispiel verwendet **FastAPI** standardmäßig `ORJSONResponse` in allen *Pfadoperationen*, anstelle von `JSONResponse`.
 
-{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
 
 /// tip | Tipp
 
index f94526b4fc8b29339f2ca07ed38ec628ebf8c4ab..7e1191b55e567d217c8ad6ae4119d9a615778742 100644 (file)
@@ -30,7 +30,7 @@ Beginnen wir mit einem Beispiel und sehen es uns dann im Detail an.
 
 Wir erstellen eine asynchrone Funktion `lifespan()` mit `yield` wie folgt:
 
-{* ../../docs_src/events/tutorial003.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
 
 Hier simulieren wir den langsamen *Startup*, das Laden des Modells, indem wir die (Fake-)Modellfunktion vor dem `yield` in das <abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Modellen für maschinelles Lernen einfügen. Dieser Code wird ausgeführt, **bevor** die Anwendung **beginnt, Requests entgegenzunehmen**, während des *Startups*.
 
@@ -48,7 +48,7 @@ Möglicherweise müssen Sie eine neue Version starten, oder Sie haben es einfach
 
 Das Erste, was auffällt, ist, dass wir eine asynchrone Funktion mit `yield` definieren. Das ist sehr ähnlich zu Abhängigkeiten mit `yield`.
 
-{* ../../docs_src/events/tutorial003.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
 
 Der erste Teil der Funktion, vor dem `yield`, wird ausgeführt **bevor** die Anwendung startet.
 
@@ -60,7 +60,7 @@ Wie Sie sehen, ist die Funktion mit einem `@asynccontextmanager` versehen.
 
 Dadurch wird die Funktion in einen sogenannten „**asynchronen Kontextmanager**“ umgewandelt.
 
-{* ../../docs_src/events/tutorial003.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
 
 Ein **Kontextmanager** in Python ist etwas, das Sie in einer `with`-Anweisung verwenden können, zum Beispiel kann `open()` als Kontextmanager verwendet werden:
 
@@ -82,7 +82,7 @@ In unserem obigen Codebeispiel verwenden wir ihn nicht direkt, sondern übergebe
 
 Der Parameter `lifespan` der `FastAPI`-App benötigt einen **asynchronen Kontextmanager**, wir können ihm also unseren neuen asynchronen Kontextmanager `lifespan` übergeben.
 
-{* ../../docs_src/events/tutorial003.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
 
 ## Alternative Events (<abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr>) { #alternative-events-deprecated }
 
@@ -104,7 +104,7 @@ Diese Funktionen können mit `async def` oder normalem `def` deklariert werden.
 
 Um eine Funktion hinzuzufügen, die vor dem Start der Anwendung ausgeführt werden soll, deklarieren Sie diese mit dem Event `startup`:
 
-{* ../../docs_src/events/tutorial001.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
 
 In diesem Fall initialisiert die Eventhandler-Funktion `startup` die „Datenbank“ der Items (nur ein `dict`) mit einigen Werten.
 
@@ -116,7 +116,7 @@ Und Ihre Anwendung empfängt erst dann Requests, wenn alle `startup`-Eventhandle
 
 Um eine Funktion hinzuzufügen, die beim Shutdown der Anwendung ausgeführt werden soll, deklarieren Sie sie mit dem Event `shutdown`:
 
-{* ../../docs_src/events/tutorial002.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
 
 Hier schreibt die `shutdown`-Eventhandler-Funktion eine Textzeile `"Application shutdown"` in eine Datei `log.txt`.
 
index d8836295b6950fb1b675d03b403ffe24dc2b8646..659343f5bcb61f570f992dff6f8f4915278f9496 100644 (file)
@@ -167,7 +167,7 @@ Aber für den generierten Client könnten wir die OpenAPI-Operation-IDs direkt v
 
 Wir könnten das OpenAPI-JSON in eine Datei `openapi.json` herunterladen und dann mit einem Skript wie dem folgenden **den präfixierten Tag entfernen**:
 
-{* ../../docs_src/generate_clients/tutorial004.py *}
+{* ../../docs_src/generate_clients/tutorial004_py39.py *}
 
 //// tab | Node.js
 
index 8396a626b6aa852dca19788c5019adae10abf4e3..ccc6a64c3bdb86943941a8a046fc6d8f6627c425 100644 (file)
@@ -57,13 +57,13 @@ Erzwingt, dass alle eingehenden <abbr title="Request – Anfrage: Daten, die der
 
 Alle eingehenden Requests an `http` oder `ws` werden stattdessen an das sichere Schema umgeleitet.
 
-{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
 
 ## `TrustedHostMiddleware` { #trustedhostmiddleware }
 
 Erzwingt, dass alle eingehenden Requests einen korrekt gesetzten `Host`-Header haben, um sich vor HTTP-Host-Header-Angriffen zu schützen.
 
-{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
 
 Die folgenden Argumente werden unterstützt:
 
@@ -78,7 +78,7 @@ Verarbeitet GZip-Responses für alle Requests, die `"gzip"` im `Accept-Encoding`
 
 Diese Middleware verarbeitet sowohl Standard- als auch Streaming-Responses.
 
-{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
 
 Die folgenden Argumente werden unterstützt:
 
index a09a675ed6c811c25192a4adc3eed73daf347ca8..ca9c63960ed04a806a386d7ca39e9a40a62d9b00 100644 (file)
@@ -32,7 +32,7 @@ Webhooks sind in OpenAPI 3.1.0 und höher verfügbar und werden von FastAPI `0.9
 
 Wenn Sie eine **FastAPI**-Anwendung erstellen, gibt es ein `webhooks`-Attribut, das Sie verwenden können, um *Webhooks* zu definieren, genauso wie Sie *Pfadoperationen* definieren würden, zum Beispiel mit `@app.webhooks.post()`.
 
-{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
 
 Die von Ihnen definierten Webhooks landen im **OpenAPI**-Schema und der automatischen **Dokumentations-Oberfläche**.
 
index bad768feb59ca2c9a21dbb348e4bfd9ce108a82c..e722526002a7d84dfb22687863aa552e9d1311de 100644 (file)
@@ -12,7 +12,7 @@ Mit dem Parameter `operation_id` können Sie die OpenAPI `operationId` festlegen
 
 Sie müssten sicherstellen, dass sie für jede Operation eindeutig ist.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
 
 ### Verwendung des Namens der *Pfadoperation-Funktion* als operationId { #using-the-path-operation-function-name-as-the-operationid }
 
@@ -20,7 +20,7 @@ Wenn Sie die Funktionsnamen Ihrer API als `operationId`s verwenden möchten, kö
 
 Sie sollten dies tun, nachdem Sie alle Ihre *Pfadoperationen* hinzugefügt haben.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
 
 /// tip | Tipp
 
@@ -40,7 +40,7 @@ Auch wenn diese sich in unterschiedlichen Modulen (Python-Dateien) befinden.
 
 Um eine *Pfadoperation* aus dem generierten OpenAPI-Schema (und damit aus den automatischen Dokumentationssystemen) auszuschließen, verwenden Sie den Parameter `include_in_schema` und setzen Sie ihn auf `False`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
 
 ## Fortgeschrittene Beschreibung mittels Docstring { #advanced-description-from-docstring }
 
@@ -92,7 +92,7 @@ Sie können das OpenAPI-Schema für eine *Pfadoperation* erweitern, indem Sie de
 
 Dieses `openapi_extra` kann beispielsweise hilfreich sein, um [OpenAPI-Erweiterungen](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions) zu deklarieren:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
 
 Wenn Sie die automatische API-Dokumentation öffnen, wird Ihre Erweiterung am Ende der spezifischen *Pfadoperation* angezeigt.
 
@@ -139,7 +139,7 @@ Sie könnten sich beispielsweise dafür entscheiden, den <abbr title="Request 
 
 Das könnte man mit `openapi_extra` machen:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
 
 In diesem Beispiel haben wir kein Pydantic-Modell deklariert. Tatsächlich wird der Requestbody nicht einmal als JSON <abbr title="von einem einfachen Format, wie Bytes, in Python-Objekte konvertieren">geparst</abbr>, sondern direkt als `bytes` gelesen und die Funktion `magic_data_reader()` wäre dafür verantwortlich, ihn in irgendeiner Weise zu parsen.
 
index b079e241d189ee0002a270c501665783be09d409..b209c2d67134922149c5834a360452b076a1ae0a 100644 (file)
@@ -20,7 +20,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
 
 Anschließend können Sie den `status_code` in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
 
-{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
 
 Und dann können Sie jedes benötigte Objekt zurückgeben, wie Sie es normalerweise tun würden (ein `dict`, ein Datenbankmodell usw.).
 
index 02fe99c26a934abaf7850f26bd75c15b0096e5ce..87e636cfaf5054ab7552ada65d8d9f83000284e0 100644 (file)
@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
 
 Und dann können Sie Cookies in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt setzen.
 
-{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
 
 Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
 
@@ -24,7 +24,7 @@ Dazu können Sie eine Response erstellen, wie unter [Eine Response direkt zurüc
 
 Setzen Sie dann Cookies darin und geben Sie sie dann zurück:
 
-{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
 
 /// tip | Tipp
 
index 06ec2c32eddb8284d6067b1d8ae9e2cbaacaf846..0a28a6d0e268d46f58b9b7aa27c3cd67d85218fd 100644 (file)
@@ -54,7 +54,7 @@ Nehmen wir an, Sie möchten eine <a href="https://en.wikipedia.org/wiki/XML" cla
 
 Sie könnten Ihren XML-Inhalt als String in eine `Response` einfügen und sie zurückgeben:
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ## Anmerkungen { #notes }
 
index 1dc7c069112efe47430ce85492292bfcd19bb82e..dbebe03a38ccd680be7816b4f2a60b37d8c48ebf 100644 (file)
@@ -6,7 +6,7 @@ Sie können einen Parameter vom Typ `Response` in Ihrer *Pfadoperation-Funktion*
 
 Und dann können Sie Header in diesem *vorübergehenden* <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr>-Objekt festlegen.
 
-{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
 
 Anschließend können Sie wie gewohnt jedes gewünschte Objekt zurückgeben (ein `dict`, ein Datenbankmodell, usw.).
 
@@ -22,7 +22,7 @@ Sie können auch Header hinzufügen, wenn Sie eine `Response` direkt zurückgebe
 
 Erstellen Sie eine Response wie in [Eine Response direkt zurückgeben](response-directly.md){.internal-link target=_blank} beschrieben und übergeben Sie die Header als zusätzlichen Parameter:
 
-{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
 
 /// note | Technische Details
 
index 03263a28b0a6c1049a74c260a87d6ea88efb1006..ebacf76f423217ab9c2da242ebdbb8adec304324 100644 (file)
@@ -62,7 +62,7 @@ Sie können dieselben Validierungs-Funktionen und -Tools verwenden, die Sie für
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -74,7 +74,7 @@ In Pydantic v1 würden Sie `BaseSettings` direkt von `pydantic` statt von `pydan
 
 ///
 
-{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -92,7 +92,7 @@ Als Nächstes werden die Daten konvertiert und validiert. Wenn Sie also dieses `
 
 Dann können Sie das neue `settings`-Objekt in Ihrer Anwendung verwenden:
 
-{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
 
 ### Den Server ausführen { #run-the-server }
 
@@ -126,11 +126,11 @@ Sie könnten diese Einstellungen in eine andere Moduldatei einfügen, wie Sie in
 
 Sie könnten beispielsweise eine Datei `config.py` haben mit:
 
-{* ../../docs_src/settings/app01/config.py *}
+{* ../../docs_src/settings/app01_py39/config.py *}
 
 Und dann verwenden Sie diese in einer Datei `main.py`:
 
-{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
 
 /// tip | Tipp
 
index d634aac23b9835c7cd5f0a28dd2bda8f09ab0d7b..081574d0a9f1b6228c47e558577b4873e5b76036 100644 (file)
@@ -10,7 +10,7 @@ Wenn Sie zwei unabhängige FastAPI-Anwendungen mit deren eigenen unabhängigen O
 
 Erstellen Sie zunächst die Hauptanwendung **FastAPI** und deren *Pfadoperationen*:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
 
 ### Unteranwendung { #sub-application }
 
@@ -18,7 +18,7 @@ Erstellen Sie dann Ihre Unteranwendung und deren *Pfadoperationen*.
 
 Diese Unteranwendung ist nur eine weitere Standard-FastAPI-Anwendung, aber diese wird „gemountet“:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
 
 ### Die Unteranwendung mounten { #mount-the-sub-application }
 
@@ -26,7 +26,7 @@ Mounten Sie in Ihrer Top-Level-Anwendung `app` die Unteranwendung `subapi`.
 
 In diesem Fall wird sie im Pfad `/subapi` gemountet:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
 
 ### Die automatische API-Dokumentation testen { #check-the-automatic-api-docs }
 
index 65c7998b8af28942e1491e406238a3e9294c6299..97a45e6126e135062afe2578ff506345f324658e 100644 (file)
@@ -27,7 +27,7 @@ $ pip install jinja2
 * Deklarieren Sie einen `<abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Request</abbr>`-Parameter in der *Pfadoperation*, welcher ein Template zurückgibt.
 * Verwenden Sie die von Ihnen erstellten `templates`, um eine `TemplateResponse` zu rendern und zurückzugeben, übergeben Sie den Namen des Templates, das Requestobjekt und ein „Kontext“-<abbr title="Dictionary – Zuordnungstabelle: In anderen Sprachen auch Hash, Map, Objekt, Assoziatives Array genannt">Dictionary</abbr> mit Schlüssel-Wert-Paaren, die innerhalb des Jinja2-Templates verwendet werden sollen.
 
-{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
 
 /// note | Hinweis
 
index 569518c51dc5198129f47faae0cc871e11e95081..5b12f3f1860c31ee026e06e05d0be36e5fa8e87f 100644 (file)
@@ -2,11 +2,11 @@
 
 Wenn Sie `lifespan` in Ihren Tests ausführen müssen, können Sie den `TestClient` mit einer `with`-Anweisung verwenden:
 
-{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
 
 
 Sie können mehr Details unter [„Lifespan in Tests ausführen in der offiziellen Starlette-Dokumentation.“](https://www.starlette.dev/lifespan/#running-lifespan-in-tests) nachlesen.
 
 Für die deprecateten Events <abbr title="Hochfahren">`startup`</abbr> und <abbr title="Herunterfahren">`shutdown`</abbr> können Sie den `TestClient` wie folgt verwenden:
 
-{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
index f25aa4fd041cfc63c0b701b7476a8fb9f8ef232d..9ecca7a4f777c91e97b81351104a0a4bbef4032a 100644 (file)
@@ -4,7 +4,7 @@ Sie können den schon bekannten `TestClient` zum Testen von WebSockets verwenden
 
 Dazu verwenden Sie den `TestClient` in einer `with`-Anweisung, eine Verbindung zum WebSocket herstellend:
 
-{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
 
 /// note | Hinweis
 
index 8ec6741d07ac93ccbfc95c2475e6462728e70814..36d73b8067c2955daa784b7664738637e5baa5f2 100644 (file)
@@ -29,7 +29,7 @@ Angenommen, Sie möchten auf die IP-Adresse/den Host des Clients in Ihrer *Pfado
 
 Dazu müssen Sie direkt auf den Request zugreifen.
 
-{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
 
 Durch die Deklaration eines *Pfadoperation-Funktionsparameters*, dessen Typ der `Request` ist, weiß **FastAPI**, dass es den `Request` diesem Parameter übergeben soll.
 
index 5f662770f0e73402fe69dad4775c2d94c2568397..05ae5a4b31798ab562add119d7d4894f66fc80b4 100644 (file)
@@ -38,13 +38,13 @@ In der Produktion hätten Sie eine der oben genannten Optionen.
 
 Aber es ist der einfachste Weg, sich auf die Serverseite von WebSockets zu konzentrieren und ein funktionierendes Beispiel zu haben:
 
-{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
 
 ## Einen `websocket` erstellen { #create-a-websocket }
 
 Erstellen Sie in Ihrer **FastAPI**-Anwendung einen `websocket`:
 
-{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
 
 /// note | Technische Details
 
@@ -58,7 +58,7 @@ Sie könnten auch `from starlette.websockets import WebSocket` verwenden.
 
 In Ihrer WebSocket-Route können Sie Nachrichten `await`en und Nachrichten senden.
 
-{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
 
 Sie können Binär-, Text- und JSON-Daten empfangen und senden.
 
index 1de9739ddeceaaaec3960eb6fbef5709f30d1557..3cd776a6abac041ee5c90a1d7a64ca8ae0ce2a5a 100644 (file)
@@ -12,7 +12,7 @@ Wrappen Sie dann die WSGI-Anwendung (z. B. Flask) mit der Middleware.
 
 Und dann mounten Sie das auf einem Pfad.
 
-{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
+{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
 
 ## Es testen { #check-it }
 
index f6a2fad3bceda2ee96f82f576b80aadce7e079bb..6e665cc4c05e336256497355f8e9d47bf88c8b3e 100644 (file)
@@ -29,7 +29,7 @@ Sie können problemlos dieselben Pydantic-Einstellungen verwenden, um Ihre gener
 
 Zum Beispiel:
 
-{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
 
 Hier deklarieren wir die Einstellung `openapi_url` mit dem gleichen Defaultwert `"/openapi.json"`.
 
index 3616f03ac402721250ceffa92b882e5b77ea76b6..1c3f5c0c5a6e086800a0bf49d40310d77d5b6119 100644 (file)
@@ -18,7 +18,7 @@ Ohne Änderung der Einstellungen ist die Syntaxhervorhebung standardmäßig akti
 
 Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` setzen:
 
-{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
 
 ... und dann zeigt die Swagger-Oberfläche die Syntaxhervorhebung nicht mehr an:
 
@@ -28,7 +28,7 @@ Sie können sie jedoch deaktivieren, indem Sie `syntaxHighlight` auf `False` set
 
 Auf die gleiche Weise könnten Sie das Theme der Syntaxhervorhebung mit dem Schlüssel `"syntaxHighlight.theme"` festlegen (beachten Sie, dass er einen Punkt in der Mitte hat):
 
-{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
 
 Obige Konfiguration würde das Theme für die Farbe der Syntaxhervorhebung ändern:
 
@@ -46,7 +46,7 @@ Sie können jede davon überschreiben, indem Sie im Argument `swagger_ui_paramet
 
 Um beispielsweise `deepLinking` zu deaktivieren, könnten Sie folgende Einstellungen an `swagger_ui_parameters` übergeben:
 
-{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
 
 ## Andere Parameter der Swagger-Oberfläche { #other-swagger-ui-parameters }
 
index 6b8b1a1767b5336edf3f9c9736b21c94ef0dfc15..6b1d654adf9be8911c602639dbbd414ca4c7644d 100644 (file)
@@ -18,7 +18,7 @@ Der erste Schritt besteht darin, die automatischen Dokumentationen zu deaktivier
 
 Um diese zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
 
 ### Die benutzerdefinierten Dokumentationen hinzufügen { #include-the-custom-docs }
 
@@ -34,7 +34,7 @@ Sie können die internen Funktionen von FastAPI wiederverwenden, um die HTML-Sei
 
 Und ähnlich für ReDoc ...
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
 
 /// tip | Tipp
 
@@ -50,7 +50,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
 
 Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
 
 ### Es testen { #test-it }
 
@@ -118,7 +118,7 @@ Danach könnte Ihre Dateistruktur wie folgt aussehen:
 * Importieren Sie `StaticFiles`.
 * „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
 
 ### Die statischen Dateien testen { #test-the-static-files }
 
@@ -144,7 +144,7 @@ Wie bei der Verwendung eines benutzerdefinierten CDN besteht der erste Schritt d
 
 Um sie zu deaktivieren, setzen Sie deren URLs beim Erstellen Ihrer `FastAPI`-App auf `None`:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
 
 ### Die benutzerdefinierten Dokumentationen für statische Dateien hinzufügen { #include-the-custom-docs-for-static-files }
 
@@ -160,7 +160,7 @@ Auch hier können Sie die internen Funktionen von FastAPI wiederverwenden, um di
 
 Und ähnlich für ReDoc ...
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
 
 /// tip | Tipp
 
@@ -176,7 +176,7 @@ Swagger UI erledigt das hinter den Kulissen für Sie, benötigt aber diesen „U
 
 Um nun testen zu können, ob alles funktioniert, erstellen Sie eine *Pfadoperation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
 
 ### Benutzeroberfläche mit statischen Dateien testen { #test-static-files-ui }
 
index 146ee098bc1637146e468c2ceda4d94456afd8f1..c07ed2aa0823dc8bad172b84b552498935c1c07f 100644 (file)
@@ -43,19 +43,19 @@ Fügen wir beispielsweise <a href="https://github.com/Rebilly/ReDoc/blob/master/
 
 Schreiben Sie zunächst wie gewohnt Ihre ganze **FastAPI**-Anwendung:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
 
 ### Das OpenAPI-Schema generieren { #generate-the-openapi-schema }
 
 Verwenden Sie dann dieselbe Hilfsfunktion, um das OpenAPI-Schema innerhalb einer `custom_openapi()`-Funktion zu generieren:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
 
 ### Das OpenAPI-Schema ändern { #modify-the-openapi-schema }
 
 Jetzt können Sie die ReDoc-Erweiterung hinzufügen und dem `info`-„Objekt“ im OpenAPI-Schema ein benutzerdefiniertes `x-logo` hinzufügen:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
 
 ### Zwischenspeichern des OpenAPI-Schemas { #cache-the-openapi-schema }
 
@@ -65,13 +65,13 @@ Auf diese Weise muss Ihre Anwendung das Schema nicht jedes Mal generieren, wenn
 
 Es wird nur einmal generiert und dann wird dasselbe zwischengespeicherte Schema für die nächsten <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> verwendet.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
 
 ### Die Methode überschreiben { #override-the-method }
 
 Jetzt können Sie die Methode `.openapi()` durch Ihre neue Funktion ersetzen.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
 
 ### Es testen { #check-it }
 
index d2958dcd9e2fa3e0158a732f36821f6c1a0b106c..0583faf4a3682c2d48fab31224e78088b84b126d 100644 (file)
@@ -35,7 +35,7 @@ Abhängig von Ihrem Anwendungsfall könnten Sie eine andere Bibliothek vorziehen
 
 Hier ist eine kleine Vorschau, wie Sie Strawberry mit FastAPI integrieren können:
 
-{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *}
+{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *}
 
 Weitere Informationen zu Strawberry finden Sie in der <a href="https://strawberry.rocks/" class="external-link" target="_blank">Strawberry-Dokumentation</a>.
 
index 290f605b382b865e1127137893593dd20daa58f5..62702d8529d611e2308c9c9225bbe1367b46daa5 100644 (file)
@@ -13,7 +13,7 @@ GitHub-Repository: <a href="https://github.com/tiangolo/full-stack-fastapi-templ
   - 🔍 [Pydantic](https://docs.pydantic.dev), verwendet von FastAPI, für die Datenvalidierung und das Einstellungsmanagement.
   - 💾 [PostgreSQL](https://www.postgresql.org) als SQL-Datenbank.
 - 🚀 [React](https://react.dev) für das Frontend.
-  - 💃 Verwendung von TypeScript, Hooks, [Vite](https://vitejs.dev) und anderen Teilen eines modernen Frontend-Stacks.
+  - 💃 Verwendung von TypeScript, Hooks, Vite und anderen Teilen eines modernen Frontend-Stacks.
   - 🎨 [Tailwind CSS](https://tailwindcss.com) und [shadcn/ui](https://ui.shadcn.com) für die Frontend-Komponenten.
   - 🤖 Ein automatisch generierter Frontend-Client.
   - 🧪 [Playwright](https://playwright.dev) für End-to-End-Tests.
index 317ee4e629fa17922f4e9f836613ccf3935b84a4..221e77544efc19431b1faac3c719e31e11a3fe56 100644 (file)
@@ -22,7 +22,7 @@ Wenn Sie ein Python-Experte sind und bereits alles über Typhinweise wissen, üb
 
 Fangen wir mit einem einfachen Beispiel an:
 
-{* ../../docs_src/python_types/tutorial001.py *}
+{* ../../docs_src/python_types/tutorial001_py39.py *}
 
 Dieses Programm gibt aus:
 
@@ -34,9 +34,9 @@ Die Funktion macht Folgendes:
 
 * Nimmt einen `first_name` und `last_name`.
 * Schreibt den ersten Buchstaben eines jeden Wortes groß, mithilfe von `title()`.
-* <abbr title="Füge zu einer Einheit zusammen, eins nach dem anderen.">Verkettet</abbr> sie mit einem Leerzeichen in der Mitte.
+* <abbr title="Fügt sie zu einer Einheit zusammen. Mit dem Inhalt des einen nach dem anderen.">Verkettet</abbr> sie mit einem Leerzeichen in der Mitte.
 
-{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
 
 ### Es bearbeiten { #edit-it }
 
@@ -78,7 +78,7 @@ Das war's.
 
 Das sind die „Typhinweise“:
 
-{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
 
 Das ist nicht das gleiche wie das Deklarieren von Defaultwerten, wie es hier der Fall ist:
 
@@ -106,7 +106,7 @@ Hier können Sie durch die Optionen blättern, bis Sie diejenige finden, bei der
 
 Sehen Sie sich diese Funktion an, sie hat bereits Typhinweise:
 
-{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
 
 Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervollständigung, sondern auch eine Fehlerprüfung:
 
@@ -114,7 +114,7 @@ Da der Editor die Typen der Variablen kennt, erhalten Sie nicht nur Code-Vervoll
 
 Jetzt, da Sie wissen, dass Sie das reparieren müssen, konvertieren Sie `age` mittels `str(age)` in einen String:
 
-{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
 
 ## Deklarieren von Typen { #declaring-types }
 
@@ -133,7 +133,7 @@ Zum Beispiel diese:
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
 
 ### Generische Typen mit Typ-Parametern { #generic-types-with-type-parameters }
 
@@ -161,56 +161,24 @@ Wenn Sie über die **neueste Version von Python** verfügen, verwenden Sie die B
 
 Definieren wir zum Beispiel eine Variable, die eine `list` von `str` – eine Liste von Strings – sein soll.
 
-//// tab | Python 3.9+
-
 Deklarieren Sie die Variable mit der gleichen Doppelpunkt-Syntax (`:`).
 
 Als Typ nehmen Sie `list`.
 
 Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
 
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-Von `typing` importieren Sie `List` (mit Großbuchstaben `L`):
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-Deklarieren Sie die Variable mit der gleichen Doppelpunkt-Syntax (`:`).
-
-Als Typ nehmen Sie das `List`, das Sie von `typing` importiert haben.
-
-Da die Liste ein Typ ist, welcher innere Typen enthält, werden diese von eckigen Klammern umfasst:
-
-```Python hl_lines="4"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
 
 /// info | Info
 
 Die inneren Typen in den eckigen Klammern werden als „Typ-Parameter“ bezeichnet.
 
-In diesem Fall ist `str` der Typ-Parameter, der an `List` übergeben wird (oder `list` in Python 3.9 und darüber).
+In diesem Fall ist `str` der Typ-Parameter, der an `list` übergeben wird.
 
 ///
 
 Das bedeutet: Die Variable `items` ist eine Liste – `list` – und jedes der Elemente in dieser Liste ist ein String – `str`.
 
-/// tip | Tipp
-
-Wenn Sie Python 3.9 oder höher verwenden, müssen Sie `List` nicht von `typing` importieren, Sie können stattdessen den regulären `list`-Typ verwenden.
-
-///
-
 Auf diese Weise kann Ihr Editor Sie auch bei der Bearbeitung von Einträgen aus der Liste unterstützen:
 
 <img src="/img/python-types/image05.png">
@@ -225,21 +193,7 @@ Und trotzdem weiß der Editor, dass es sich um ein `str` handelt, und bietet ent
 
 Das Gleiche gilt für die Deklaration eines Tupels – `tuple` – und einer Menge – `set`:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial007_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
 
 Das bedeutet:
 
@@ -254,21 +208,7 @@ Der erste Typ-Parameter ist für die Schlüssel des `dict`.
 
 Der zweite Typ-Parameter ist für die Werte des `dict`:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial008_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
 
 Das bedeutet:
 
@@ -282,7 +222,7 @@ Sie können deklarieren, dass eine Variable einer von **verschiedenen Typen** se
 
 In Python 3.6 und höher (inklusive Python 3.10) können Sie den `Union`-Typ von `typing` verwenden und die möglichen Typen innerhalb der eckigen Klammern auflisten.
 
-In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem <abbr title='Allgemein: „oder“. In anderem Zusammenhang auch „Bitweises ODER“, aber letztere Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> aufzulisten.
+In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die möglichen Typen getrennt von einem <abbr title='auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> aufzulisten.
 
 //// tab | Python 3.10+
 
@@ -292,10 +232,10 @@ In Python 3.10 gibt es zusätzlich eine **neue Syntax**, die es erlaubt, die mö
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008b.py!}
+{!> ../../docs_src/python_types/tutorial008b_py39.py!}
 ```
 
 ////
@@ -309,7 +249,7 @@ Sie können deklarieren, dass ein Wert ein `str`, aber vielleicht auch `None` se
 In Python 3.6 und darüber (inklusive Python 3.10) können Sie das deklarieren, indem Sie `Optional` vom `typing` Modul importieren und verwenden.
 
 ```Python hl_lines="1  4"
-{!../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 Wenn Sie `Optional[str]` anstelle von nur `str` verwenden, wird Ihr Editor Ihnen dabei helfen, Fehler zu erkennen, bei denen Sie annehmen könnten, dass ein Wert immer eine String (`str`) ist, obwohl er auch `None` sein könnte.
@@ -326,18 +266,18 @@ Das bedeutet auch, dass Sie in Python 3.10 `Something | None` verwenden können:
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009.py!}
+{!> ../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 ////
 
-//// tab | Python 3.8+ Alternative
+//// tab | Python 3.9+ Alternative
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009b.py!}
+{!> ../../docs_src/python_types/tutorial009b_py39.py!}
 ```
 
 ////
@@ -353,11 +293,11 @@ Beide sind äquivalent und im Hintergrund dasselbe, aber ich empfehle `Union` st
 
 Ich denke, `Union[SomeType, None]` ist expliziter bezüglich seiner Bedeutung.
 
-Es geht nur um Wörter und Namen. Aber diese Worte können beeinflussen, wie Sie und Ihre Teamkollegen über den Code denken.
+Es geht nur um Worte und Namen. Aber diese Worte können beeinflussen, wie Sie und Ihre Teamkollegen über den Code denken.
 
 Nehmen wir zum Beispiel diese Funktion:
 
-{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
 
 Der Parameter `name` ist definiert als `Optional[str]`, aber er ist **nicht optional**, Sie können die Funktion nicht ohne diesen Parameter aufrufen:
 
@@ -390,13 +330,13 @@ Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern u
 * `set`
 * `dict`
 
-Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
+Und ebenso wie bei früheren Python-Versionen, aus dem `typing`-Modul:
 
 * `Union`
-* `Optional` (so wie unter Python 3.8)
+* `Optional`
 * ... und andere.
 
-In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den <abbr title='Allgemein: „oder“. In anderem Zusammenhang auch „Bitweises ODER“, aber letztere Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher.
+In Python 3.10 können Sie als Alternative zu den Generics `Union` und `Optional` den <abbr title='auch „bitweiser Oder-Operator“ genannt, aber diese Bedeutung ist hier nicht relevant'>vertikalen Balken (`|`)</abbr> verwenden, um Vereinigungen von Typen zu deklarieren, das ist besser und einfacher.
 
 ////
 
@@ -409,7 +349,7 @@ Sie können die eingebauten Typen als Generics verwenden (mit eckigen Klammern u
 * `set`
 * `dict`
 
-Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
+Und Generics aus dem `typing`-Modul:
 
 * `Union`
 * `Optional`
@@ -417,29 +357,17 @@ Verwenden Sie für den Rest, wie unter Python 3.8, das `typing`-Modul:
 
 ////
 
-//// tab | Python 3.8+
-
-* `List`
-* `Tuple`
-* `Set`
-* `Dict`
-* `Union`
-* `Optional`
-* ... und andere.
-
-////
-
 ### Klassen als Typen { #classes-as-types }
 
 Sie können auch eine Klasse als Typ einer Variablen deklarieren.
 
 Nehmen wir an, Sie haben eine Klasse `Person`, mit einem Namen:
 
-{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
 
 Dann können Sie eine Variable vom Typ `Person` deklarieren:
 
-{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
 
 Und wiederum bekommen Sie die volle Editor-Unterstützung:
 
@@ -463,29 +391,7 @@ Und Sie erhalten volle Editor-Unterstützung für dieses Objekt.
 
 Ein Beispiel aus der offiziellen Pydantic Dokumentation:
 
-//// tab | Python 3.10+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial011_py310.py *}
 
 /// info | Info
 
@@ -507,27 +413,9 @@ Pydantic verhält sich speziell, wenn Sie `Optional` oder `Union[Something, None
 
 Python bietet auch die Möglichkeit, **zusätzliche <abbr title="Daten über die Daten, in diesem Fall Informationen über den Typ, z. B. eine Beschreibung.">Metadaten</abbr>** in Typhinweisen unterzubringen, mittels `Annotated`.
 
-//// tab | Python 3.9+
-
-In Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren.
+Seit Python 3.9 ist `Annotated` ein Teil der Standardbibliothek, Sie können es von `typing` importieren.
 
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-In Versionen niedriger als Python 3.9 importieren Sie `Annotated` von `typing_extensions`.
-
-Es wird bereits mit **FastAPI** installiert sein.
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
 
 Python selbst macht nichts mit `Annotated`. Für Editoren und andere Tools ist der Typ immer noch `str`.
 
index 2c381ccfac93ffa59385a706fb00a55e44612794..1d34430dc6586da4e44f6b418f2ac76edd50f752 100644 (file)
@@ -15,7 +15,7 @@ Hierzu zählen beispielsweise:
 
 Importieren Sie zunächst `BackgroundTasks` und definieren Sie einen Parameter in Ihrer *Pfadoperation-Funktion* mit der Typdeklaration `BackgroundTasks`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
 
 **FastAPI** erstellt für Sie das Objekt vom Typ `BackgroundTasks` und übergibt es als diesen Parameter.
 
@@ -31,13 +31,13 @@ In diesem Fall schreibt die Taskfunktion in eine Datei (den Versand einer E-Mail
 
 Und da der Schreibvorgang nicht `async` und `await` verwendet, definieren wir die Funktion mit normalem `def`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
 
 ## Den Hintergrundtask hinzufügen { #add-the-background-task }
 
 Übergeben Sie innerhalb Ihrer *Pfadoperation-Funktion* Ihre Taskfunktion mit der Methode `.add_task()` an das *Hintergrundtasks*-Objekt:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
 
 `.add_task()` erhält als Argumente:
 
index 324d31928d4f0be609ca55dbc725d5d4442cc77d..65a5d7c1de957e22a4dcdde708e454b567f56f83 100644 (file)
@@ -14,35 +14,14 @@ Das bewirkt, dass `tags` eine Liste ist, wenngleich es nichts über den Typ der
 
 Aber Python erlaubt es, Listen mit inneren Typen, auch „Typ-Parameter“ genannt, zu deklarieren.
 
-### `List` von `typing` importieren { #import-typings-list }
-
-In Python 3.9 oder darüber können Sie einfach `list` verwenden, um diese Typannotationen zu deklarieren, wie wir unten sehen werden. 💡
-
-In Python-Versionen vor 3.9 (3.6 und darüber), müssen Sie zuerst `List` von Pythons Standardmodul `typing` importieren.
-
-{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
-
 ### Eine `list` mit einem Typ-Parameter deklarieren { #declare-a-list-with-a-type-parameter }
 
-Um Typen wie `list`, `dict`, `tuple` mit inneren Typ-Parametern (inneren Typen) zu deklarieren:
-
-* Wenn Sie eine Python-Version kleiner als 3.9 verwenden, importieren Sie das Äquivalent zum entsprechenden Typ vom `typing`-Modul
-* Überreichen Sie den/die inneren Typ(en) von eckigen Klammern umschlossen, `[` und `]`, als „Typ-Parameter“
-
-In Python 3.9 wäre das:
+Um Typen zu deklarieren, die Typ-Parameter (innere Typen) haben, wie `list`, `dict`, `tuple`, übergeben Sie den/die inneren Typ(en) als „Typ-Parameter“ in eckigen Klammern: `[` und `]`
 
 ```Python
 my_list: list[str]
 ```
 
-Und in Python-Versionen vor 3.9:
-
-```Python
-from typing import List
-
-my_list: List[str]
-```
-
 Das ist alles Standard-Python-Syntax für Typdeklarationen.
 
 Verwenden Sie dieselbe Standardsyntax für Modellattribute mit inneren Typen.
@@ -178,12 +157,6 @@ Beachten Sie, wie `Offer` eine Liste von `Item`s hat, die ihrerseits eine option
 
 Wenn das äußerste Element des JSON-Bodys, das Sie erwarten, ein JSON-`array` (eine Python-`list`) ist, können Sie den Typ im Funktionsparameter deklarieren, mit der gleichen Syntax wie in Pydantic-Modellen:
 
-```Python
-images: List[Image]
-```
-
-oder in Python 3.9 und darüber:
-
 ```Python
 images: list[Image]
 ```
index 1e6382b6f271f0fb623152f89554ffd2a0cdcbf7..0ad95b038698f15e0f53b618123fbf277782990c 100644 (file)
@@ -162,7 +162,7 @@ Die Funktionsparameter werden wie folgt erkannt:
 
 FastAPI weiß, dass der Wert von `q` nicht erforderlich ist, aufgrund des definierten Defaultwertes `= None`.
 
-Das `str | None` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.8+) wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
+Das `str | None` (Python 3.10+) oder `Union` in `Union[str, None]` (Python 3.9+) wird von FastAPI nicht verwendet, um zu bestimmen, dass der Wert nicht erforderlich ist. FastAPI weiß, dass er nicht erforderlich ist, weil er einen Defaultwert von `= None` hat.
 
 Das Hinzufügen der Typannotationen ermöglicht jedoch Ihrem Editor, Ihnen eine bessere Unterstützung zu bieten und Fehler zu erkennen.
 
index 191a7b4ef305a132465864cb7bfc86a12f9afc3b..81f0f36051bfe52a7bb8eb9d91b9d863ce21ae0a 100644 (file)
@@ -46,7 +46,7 @@ Sie können auch angeben, ob Ihr Backend erlaubt:
 * Bestimmte HTTP-Methoden (`POST`, `PUT`) oder alle mit der Wildcard `"*"`.
 * Bestimmte HTTP-Header oder alle mit der Wildcard `"*"`.
 
-{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
 
 Die von der `CORSMiddleware`-Implementierung verwendeten Defaultparameter sind standardmäßig restriktiv, daher müssen Sie bestimmte Origins, Methoden oder Header ausdrücklich aktivieren, damit Browser sie in einem Cross-Domain-Kontext verwenden dürfen.
 
index 0a31f86536cad00a1d4a2a8a45f7294441b4b97f..0d12877c10eb98c1c706a66f1e0519da0ae95659 100644 (file)
@@ -6,7 +6,7 @@ Sie können den Debugger in Ihrem Editor verbinden, zum Beispiel mit Visual Stud
 
 Importieren und führen Sie `uvicorn` direkt in Ihrer FastAPI-Anwendung aus:
 
-{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
 
 ### Über `__name__ == "__main__"` { #about-name-main }
 
index 3d4493f353b1e902724fdf1e1640ac5c5894d332..7df0842eb1af69193903476f206a274ec1261eae 100644 (file)
@@ -101,7 +101,7 @@ Jetzt können Sie Ihre Abhängigkeit mithilfe dieser Klasse deklarieren.
 
 Beachten Sie, wie wir `CommonQueryParams` im obigen Code zweimal schreiben:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ nicht annotiert
+//// tab | Python 3.9+ nicht annotiert
 
 /// tip | Tipp
 
@@ -137,7 +137,7 @@ Aus diesem extrahiert FastAPI die deklarierten Parameter, und dieses ist es, was
 
 In diesem Fall hat das erste `CommonQueryParams` in:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
 
 ////
 
-//// tab | Python 3.8+ nicht annotiert
+//// tab | Python 3.9+ nicht annotiert
 
 /// tip | Tipp
 
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
 
 Sie könnten tatsächlich einfach schreiben:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ nicht annotiert
+//// tab | Python 3.9+ nicht annotiert
 
 /// tip | Tipp
 
@@ -197,7 +197,7 @@ Es wird jedoch empfohlen, den Typ zu deklarieren, da Ihr Editor so weiß, was al
 
 Aber Sie sehen, dass wir hier etwas Codeduplizierung haben, indem wir `CommonQueryParams` zweimal schreiben:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ nicht annotiert
+//// tab | Python 3.9+ nicht annotiert
 
 /// tip | Tipp
 
@@ -225,7 +225,7 @@ In diesem speziellen Fall können Sie Folgendes tun:
 
 Anstatt zu schreiben:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ nicht annotiert
+//// tab | Python 3.9+ nicht annotiert
 
 /// tip | Tipp
 
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 ... schreiben Sie:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
 
 ////
 
-//// tab | Python 3.8 nicht annotiert
+//// tab | Python 3.9+ nicht annotiert
 
 /// tip | Tipp
 
index 34db6c6bedebfea813348763657fca46db3aff45..0083e7e7ead7bc0d887cb261de29f58a3cd5ba2b 100644 (file)
@@ -29,15 +29,15 @@ Sie könnten damit beispielsweise eine Datenbanksession erstellen und diese nach
 
 Nur der Code vor und einschließlich der `yield`-Anweisung wird ausgeführt, bevor eine <abbr title="Response – Antwort: Daten, die der Server zum anfragenden Client zurücksendet">Response</abbr> erzeugt wird:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
 
 Der ge`yield`ete Wert ist das, was in *Pfadoperationen* und andere Abhängigkeiten eingefügt wird:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
 
 Der auf die `yield`-Anweisung folgende Code wird nach der Response ausgeführt:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
 
 /// tip | Tipp
 
@@ -57,7 +57,7 @@ Sie können also mit `except SomeException` diese bestimmte Exception innerhalb
 
 Auf die gleiche Weise können Sie `finally` verwenden, um sicherzustellen, dass die Exit-Schritte ausgeführt werden, unabhängig davon, ob eine Exception geworfen wurde oder nicht.
 
-{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
 
 ## Unterabhängigkeiten mit `yield` { #sub-dependencies-with-yield }
 
@@ -268,7 +268,7 @@ In Python können Sie Kontextmanager erstellen, indem Sie <a href="https://docs.
 
 Sie können solche auch innerhalb von **FastAPI**-Abhängigkeiten mit `yield` verwenden, indem Sie `with`- oder `async with`-Anweisungen innerhalb der Abhängigkeits-Funktion verwenden:
 
-{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
 
 /// tip | Tipp
 
index 62cc788c3ea6fe88195b22a3ff199a3f3c77068c..0c6c7cadd3e8cb7bf4596be5aa0b040f227a9582 100644 (file)
@@ -6,7 +6,7 @@ Bei einigen Anwendungstypen möchten Sie möglicherweise Abhängigkeiten zur ges
 
 In diesem Fall werden sie auf alle *Pfadoperationen* in der Anwendung angewendet:
 
-{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
+{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
 
 Und alle Ideen aus dem Abschnitt über das [Hinzufügen von `dependencies` zu den *Pfadoperation-Dekoratoren*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} gelten weiterhin, aber in diesem Fall für alle *Pfadoperationen* in der App.
 
index 061952f9211847d51e2970df3482a97fea0ffeb7..d72f820dca05b266679e21a7e7e26ae89c4c9282 100644 (file)
@@ -62,7 +62,7 @@ Und es speichert den zurückgegebenen Wert in einem <abbr title="Mechanismus, de
 
 In einem fortgeschrittenen Szenario, bei dem Sie wissen, dass die Abhängigkeit bei jedem Schritt (möglicherweise mehrmals) in demselben Request aufgerufen werden muss, anstatt den zwischengespeicherten Wert zu verwenden, können Sie den Parameter `use_cache=False` festlegen, wenn Sie `Depends` verwenden:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
 
 ////
 
-//// tab | Python 3.8+ nicht annotiert
+//// tab | Python 3.9+ nicht annotiert
 
 /// tip | Tipp
 
index 71912d035b65d81af39db9cb5d449d371c98b79b..9505a0bdb7850df4a120dc949da01aeb461bfbf7 100644 (file)
@@ -2,7 +2,7 @@
 
 Die einfachste FastAPI-Datei könnte wie folgt aussehen:
 
-{* ../../docs_src/first_steps/tutorial001.py *}
+{* ../../docs_src/first_steps/tutorial001_py39.py *}
 
 Kopieren Sie das in eine Datei `main.py`.
 
@@ -183,7 +183,7 @@ Das war's! Jetzt können Sie Ihre App unter dieser URL aufrufen. ✨
 
 ### Schritt 1: `FastAPI` importieren { #step-1-import-fastapi }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
 
 `FastAPI` ist eine Python-Klasse, die die gesamte Funktionalität für Ihre API bereitstellt.
 
@@ -197,7 +197,7 @@ Sie können alle <a href="https://www.starlette.dev/" class="external-link" targ
 
 ### Schritt 2: Erzeugen einer `FastAPI`-„Instanz“ { #step-2-create-a-fastapi-instance }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
 
 In diesem Beispiel ist die Variable `app` eine „Instanz“ der Klasse `FastAPI`.
 
@@ -266,7 +266,7 @@ Wir werden sie auch „**Operationen**“ nennen.
 
 #### Definieren eines *Pfadoperation-Dekorators* { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
 
 Das `@app.get("/")` sagt **FastAPI**, dass die Funktion direkt darunter für die Bearbeitung von <abbr title="Request – Anfrage: Daten, die der Client zum Server sendet">Requests</abbr> zuständig ist, die an:
 
@@ -320,7 +320,7 @@ Das ist unsere „**Pfadoperation-Funktion**“:
 * **Operation**: ist `get`.
 * **Funktion**: ist die Funktion direkt unter dem „Dekorator“ (unter `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
 
 Dies ist eine Python-Funktion.
 
@@ -332,7 +332,7 @@ In diesem Fall handelt es sich um eine `async`-Funktion.
 
 Sie könnten sie auch als normale Funktion anstelle von `async def` definieren:
 
-{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
 
 /// note | Hinweis
 
@@ -342,7 +342,7 @@ Wenn Sie den Unterschied nicht kennen, lesen Sie [Async: *„In Eile?“*](../as
 
 ### Schritt 5: den Inhalt zurückgeben { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
 
 Sie können ein `dict`, eine `list`, einzelne Werte wie `str`, `int`, usw. zurückgeben.
 
index a39c3db37afa6d4181fc53df6862021407a8cb4a..d890b44629c62ce228e66ac149f63b9f021b6f07 100644 (file)
@@ -25,7 +25,7 @@ Um HTTP-<abbr title="Response – Antwort: Daten, die der Server zum anfragenden
 
 ### `HTTPException` importieren { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
 
 ### Eine `HTTPException` in Ihrem Code auslösen { #raise-an-httpexception-in-your-code }
 
@@ -39,7 +39,7 @@ Der Vorteil des Auslösens einer Exception gegenüber dem Zurückgeben eines Wer
 
 In diesem Beispiel lösen wir eine Exception mit einem Statuscode von `404` aus, wenn der Client einen Artikel mit einer nicht existierenden ID anfordert:
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
 
 ### Die resultierende Response { #the-resulting-response }
 
@@ -77,7 +77,7 @@ Sie werden es wahrscheinlich nicht direkt in Ihrem Code verwenden müssen.
 
 Aber falls Sie es für ein fortgeschrittenes Szenario benötigen, können Sie benutzerdefinierte Header hinzufügen:
 
-{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
 
 ## Benutzerdefinierte Exceptionhandler installieren { #install-custom-exception-handlers }
 
@@ -89,7 +89,7 @@ Und Sie möchten diese Exception global mit FastAPI handhaben.
 
 Sie könnten einen benutzerdefinierten Exceptionhandler mit `@app.exception_handler()` hinzufügen:
 
-{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
 
 Hier, wenn Sie `/unicorns/yolo` anfordern, wird die *Pfadoperation* eine `UnicornException` `raise`n.
 
@@ -127,7 +127,7 @@ Um diesen zu überschreiben, importieren Sie den `RequestValidationError` und ve
 
 Der Exceptionhandler erhält einen `Request` und die Exception.
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
 
 Wenn Sie nun zu `/items/foo` gehen, erhalten Sie anstelle des standardmäßigen JSON-Fehlers mit:
 
@@ -159,7 +159,7 @@ Auf die gleiche Weise können Sie den `HTTPException`-Handler überschreiben.
 
 Zum Beispiel könnten Sie eine Klartext-Response statt JSON für diese Fehler zurückgeben wollen:
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
 
 /// note | Technische Details
 
@@ -183,7 +183,7 @@ Der `RequestValidationError` enthält den empfangenen `body` mit den ungültigen
 
 Sie könnten diesen während der Entwicklung Ihrer Anwendung verwenden, um den Body zu loggen und zu debuggen, ihn an den Benutzer zurückzugeben usw.
 
-{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
 
 Versuchen Sie nun, einen ungültigen Artikel zu senden:
 
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
 
 Wenn Sie die Exception zusammen mit den gleichen Default-Exceptionhandlern von **FastAPI** verwenden möchten, können Sie die Default-Exceptionhandler aus `fastapi.exception_handlers` importieren und wiederverwenden:
 
-{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
 
 In diesem Beispiel geben Sie nur den Fehler mit einer sehr ausdrucksstarken Nachricht aus, aber Sie verstehen das Prinzip. Sie können die Exception verwenden und dann einfach die Default-Exceptionhandler wiederverwenden.
index 44d02e6d899600c9f318e795743daf3ea49df57a..ee88a21d63d30552670025083b025d5c77dfce0b 100644 (file)
@@ -18,7 +18,7 @@ Sie können die folgenden Felder festlegen, die in der OpenAPI-Spezifikation und
 
 Sie können diese wie folgt setzen:
 
-{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *}
+{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
 
 /// tip | Tipp
 
@@ -36,7 +36,7 @@ Seit OpenAPI 3.1.0 und FastAPI 0.99.0 können Sie die `license_info` auch mit ei
 
 Zum Beispiel:
 
-{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
 
 ## Metadaten für Tags { #metadata-for-tags }
 
@@ -58,7 +58,7 @@ Versuchen wir es mit einem Beispiel mit Tags für `users` und `items`.
 
 Erstellen Sie Metadaten für Ihre Tags und übergeben Sie diese an den Parameter `openapi_tags`:
 
-{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
 
 Beachten Sie, dass Sie Markdown innerhalb der Beschreibungen verwenden können. Zum Beispiel wird „login“ in Fettschrift (**login**) und „fancy“ in Kursivschrift (_fancy_) angezeigt.
 
@@ -72,7 +72,7 @@ Sie müssen nicht für alle von Ihnen verwendeten Tags Metadaten hinzufügen.
 
 Verwenden Sie den Parameter `tags` mit Ihren *Pfadoperationen* (und `APIRouter`n), um diese verschiedenen Tags zuzuweisen:
 
-{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
 
 /// info | Info
 
@@ -100,7 +100,7 @@ Sie können das aber mit dem Parameter `openapi_url` konfigurieren.
 
 Um beispielsweise festzulegen, dass es unter `/api/v1/openapi.json` bereitgestellt wird:
 
-{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
 
 Wenn Sie das OpenAPI-Schema vollständig deaktivieren möchten, können Sie `openapi_url=None` festlegen, wodurch auch die Dokumentationsbenutzeroberflächen deaktiviert werden, die es verwenden.
 
@@ -117,4 +117,4 @@ Sie können die beiden enthaltenen Dokumentationsbenutzeroberflächen konfigurie
 
 Um beispielsweise Swagger UI so einzustellen, dass sie unter `/documentation` bereitgestellt wird, und ReDoc zu deaktivieren:
 
-{* ../../docs_src/metadata/tutorial003.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
index 6410deba1ac3a71973d2bd58006aa4accab6a7ba..540a18c4d0e9c43251654d4c24f4c58f71d243bf 100644 (file)
@@ -31,7 +31,7 @@ Die Middleware-Funktion erhält:
     * Dann gibt es die von der entsprechenden *Pfadoperation* generierte `response` zurück.
 * Sie können die `response` dann weiter modifizieren, bevor Sie sie zurückgeben.
 
-{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
 
 /// tip | Tipp
 
@@ -57,7 +57,7 @@ Und auch nachdem die `response` generiert wurde, bevor sie zurückgegeben wird.
 
 Sie könnten beispielsweise einen benutzerdefinierten Header `X-Process-Time` hinzufügen, der die Zeit in Sekunden enthält, die benötigt wurde, um den Request zu verarbeiten und eine Response zu generieren:
 
-{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
 
 /// tip | Tipp
 
index c483f4e40569fb36bb5ed958efd97f38ac99af8f..3427b305281246151749b65791116e568791d4f8 100644 (file)
@@ -46,7 +46,7 @@ In diesem Fall macht es Sinn, die Tags in einem `Enum` zu speichern.
 
 **FastAPI** unterstützt das auf die gleiche Weise wie einfache Strings:
 
-{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
 
 ## Zusammenfassung und Beschreibung { #summary-and-description }
 
@@ -92,7 +92,7 @@ Daher, wenn Sie keine vergeben, wird **FastAPI** automatisch eine für „Erfolg
 
 Wenn Sie eine *Pfadoperation* als <abbr title="veraltet, obsolet: Es soll nicht mehr verwendet werden">deprecatet</abbr> kennzeichnen möchten, ohne sie zu entfernen, fügen Sie den Parameter `deprecated` hinzu:
 
-{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
 
 Sie wird in der interaktiven Dokumentation gut sichtbar als deprecatet markiert werden:
 
index 5b74749447c19fd641d35d0d1da86f6e63662d5e..8b52e8b42fdedb019fefe705c85a3c46ed98fbfb 100644 (file)
@@ -54,7 +54,7 @@ Für **FastAPI** spielt es keine Rolle. Es erkennt die Parameter anhand ihrer Na
 
 Sie können Ihre Funktion also so deklarieren:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
 
 Aber bedenken Sie, dass Sie dieses Problem nicht haben, wenn Sie `Annotated` verwenden, da es nicht darauf ankommt, dass Sie keine Funktionsparameter-Defaultwerte für `Query()` oder `Path()` verwenden.
 
@@ -83,7 +83,7 @@ Wenn Sie:
 
 Python wird nichts mit diesem `*` machen, aber es wird wissen, dass alle folgenden Parameter als Schlüsselwortargumente (Schlüssel-Wert-Paare) verwendet werden sollen, auch bekannt als <abbr title="Von: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Selbst wenn diese keinen Defaultwert haben.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
 
 ### Besser mit `Annotated` { #better-with-annotated }
 
index 1db288fb87d4e96d8e7f45fdc612832e0fac8afa..1de497315519facba1ca6535315bd148c5af9850 100644 (file)
@@ -2,7 +2,7 @@
 
 Sie können Pfad-„Parameter“ oder -„Variablen“ mit der gleichen Syntax deklarieren, welche in Python-<abbr title="Formatstring – Formatierter String: Der String enthält Ausdrücke, die mit geschweiften Klammern umschlossen sind. Solche Stellen werden durch den Wert des Ausdrucks ersetzt">Formatstrings</abbr> verwendet wird:
 
-{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
 
 Der Wert des Pfad-Parameters `item_id` wird Ihrer Funktion als das Argument `item_id` übergeben.
 
@@ -16,7 +16,7 @@ Wenn Sie dieses Beispiel ausführen und auf <a href="http://127.0.0.1:8000/items
 
 Sie können den Typ eines Pfad-Parameters in der Argumentliste der Funktion deklarieren, mit Standard-Python-Typannotationen:
 
-{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
 
 In diesem Fall wird `item_id` als `int` deklariert, also als Ganzzahl.
 
@@ -118,13 +118,13 @@ Und Sie haben auch einen Pfad `/users/{user_id}`, um Daten über einen spezifisc
 
 Weil *Pfadoperationen* in ihrer Reihenfolge ausgewertet werden, müssen Sie sicherstellen, dass der Pfad `/users/me` vor `/users/{user_id}` deklariert wurde:
 
-{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
 
 Ansonsten würde der Pfad für `/users/{user_id}` auch `/users/me` auswerten, und annehmen, dass ein Parameter `user_id` mit dem Wert `"me"` übergeben wurde.
 
 Sie können eine Pfadoperation auch nicht erneut definieren:
 
-{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
 
 Die erste Definition wird immer verwendet werden, da ihr Pfad zuerst übereinstimmt.
 
@@ -140,13 +140,8 @@ Indem Sie von `str` erben, weiß die API-Dokumentation, dass die Werte vom Typ `
 
 Erstellen Sie dann Klassen-Attribute mit festgelegten Werten, welches die erlaubten Werte sein werden:
 
-{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
 
-/// info | Info
-
-<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerationen (oder Enums)</a> gibt es in Python seit Version 3.4.
-
-///
 
 /// tip | Tipp
 
@@ -158,7 +153,7 @@ Falls Sie sich fragen, was „AlexNet“, „ResNet“ und „LeNet“ ist, das
 
 Dann erstellen Sie einen *Pfad-Parameter*, der als Typ die gerade erstellte Enum-Klasse hat (`ModelName`):
 
-{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
 
 ### Die API-Dokumentation testen { #check-the-docs }
 
@@ -174,13 +169,13 @@ Der *Pfad-Parameter* wird ein *<abbr title="Member – Mitglied: Einer der mögl
 
 Sie können ihn mit einem Member Ihrer Enumeration `ModelName` vergleichen:
 
-{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
 
 #### *Enumerations-Wert* erhalten { #get-the-enumeration-value }
 
 Den tatsächlichen Wert (in diesem Fall ein `str`) erhalten Sie via `model_name.value`, oder generell, `your_enum_member.value`:
 
-{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
 
 /// tip | Tipp
 
@@ -194,7 +189,7 @@ Sie können *Enum-Member* in ihrer *Pfadoperation* zurückgeben, sogar verschach
 
 Diese werden zu ihren entsprechenden Werten konvertiert (in diesem Fall Strings), bevor sie zum Client übertragen werden:
 
-{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
 
 In Ihrem Client erhalten Sie eine JSON-Response, wie etwa:
 
@@ -233,7 +228,7 @@ In diesem Fall ist der Name des Parameters `file_path`. Der letzte Teil, `:path`
 
 Sie verwenden das also wie folgt:
 
-{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
 
 /// tip | Tipp
 
index 744160bafff91de12a82bf937855bea24545718c..7cff29415afc0d86faedac37dedfad39c5e327d3 100644 (file)
@@ -55,7 +55,7 @@ q: str | None = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Union[str, None] = None
@@ -73,7 +73,7 @@ q: Annotated[str | None] = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Annotated[Union[str, None]] = None
index e46f31ad002658439b28736d2a8ddbef88da364b..05ed3bc83001452f0fa64c97603f301b2ca8d80a 100644 (file)
@@ -2,7 +2,7 @@
 
 Wenn Sie in Ihrer Funktion andere Parameter deklarieren, die nicht Teil der Pfad-Parameter sind, dann werden diese automatisch als „Query“-Parameter interpretiert.
 
-{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
 
 Die <abbr title="Abfrage">Query</abbr> ist die Menge von Schlüssel-Wert-Paaren, die nach dem `?` in einer URL folgen und durch `&`-Zeichen getrennt sind.
 
@@ -127,7 +127,7 @@ Wenn Sie keinen spezifischen Wert haben wollen, sondern der Parameter einfach op
 
 Aber wenn Sie wollen, dass ein Query-Parameter erforderlich ist, vergeben Sie einfach keinen Defaultwert:
 
-{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
 
 Hier ist `needy` ein erforderlicher Query-Parameter vom Typ `str`.
 
index 7b77125cb5a2ed0b0d6956f8a8faf6d5172f094d..4c0205b31f4c7eb4aa614f40704f28928da80510 100644 (file)
@@ -183,7 +183,7 @@ Es kann Fälle geben, bei denen Sie etwas zurückgeben, das kein gültiges Pydan
 
 Der häufigste Anwendungsfall ist, wenn Sie [eine Response direkt zurückgeben, wie es später im Handbuch für fortgeschrittene Benutzer erläutert wird](../advanced/response-directly.md){.internal-link target=_blank}.
 
-{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
 
 Dieser einfache Anwendungsfall wird automatisch von FastAPI gehandhabt, weil die Annotation des Rückgabetyps die Klasse (oder eine Unterklasse von) `Response` ist.
 
@@ -193,7 +193,7 @@ Und Tools werden auch glücklich sein, weil sowohl `RedirectResponse` als auch `
 
 Sie können auch eine Unterklasse von `Response` in der Typannotation verwenden.
 
-{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
 
 Das wird ebenfalls funktionieren, weil `RedirectResponse` eine Unterklasse von `Response` ist, und FastAPI sich um diesen einfachen Anwendungsfall automatisch kümmert.
 
index 928003c3fce9e9e183a321abb211afc5ed3e809c..fd17c9933635bb70929f3621a171116c6f62b452 100644 (file)
@@ -8,7 +8,7 @@ Genauso wie Sie ein Responsemodell angeben können, können Sie auch den HTTP-St
 * `@app.delete()`
 * usw.
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 /// note | Hinweis
 
@@ -74,7 +74,7 @@ Um mehr über die einzelnen Statuscodes zu erfahren und welcher wofür verwendet
 
 Lassen Sie uns das vorherige Beispiel noch einmal anschauen:
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 `201` ist der Statuscode für „Created“ („Erzeugt“).
 
@@ -82,7 +82,7 @@ Aber Sie müssen sich nicht merken, was jeder dieser Codes bedeutet.
 
 Sie können die Annehmlichkeit von Variablen aus `fastapi.status` nutzen.
 
-{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
 
 Diese sind nur eine Annehmlichkeit, sie enthalten dieselbe Zahl, aber so können Sie die Autovervollständigung Ihres Editors verwenden, um sie zu finden:
 
index 0c4e7c8abdd08e00d198ff803688e30b1cfe9bed..9ba250175630944b40d3e32cbbbcd9cf476dbeb0 100644 (file)
@@ -7,7 +7,7 @@ Mit `StaticFiles` können Sie statische Dateien aus einem Verzeichnis automatisc
 * Importieren Sie `StaticFiles`.
 * „Mounten“ Sie eine `StaticFiles()`-Instanz in einem bestimmten Pfad.
 
-{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
 
 /// note | Technische Details
 
index b18469998de0b7ea7516f99e20fc71de85528c68..d889b1e1fb7bf1a382dee16b92de0e5b7177a7e9 100644 (file)
@@ -30,7 +30,7 @@ Verwenden Sie das `TestClient`-Objekt auf die gleiche Weise wie `httpx`.
 
 Schreiben Sie einfache `assert`-Anweisungen mit den Standard-Python-Ausdrücken, die Sie überprüfen müssen (wiederum, Standard-`pytest`).
 
-{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
 
 /// tip | Tipp
 
@@ -76,7 +76,7 @@ Nehmen wir an, Sie haben eine Dateistruktur wie in [Größere Anwendungen](bigge
 In der Datei `main.py` haben Sie Ihre **FastAPI**-Anwendung:
 
 
-{* ../../docs_src/app_testing/main.py *}
+{* ../../docs_src/app_testing/app_a_py39/main.py *}
 
 
 ### Testdatei { #testing-file }
@@ -93,7 +93,7 @@ Dann könnten Sie eine Datei `test_main.py` mit Ihren Tests haben. Sie könnte s
 
 Da sich diese Datei im selben Package befindet, können Sie relative Importe verwenden, um das Objekt `app` aus dem `main`-Modul (`main.py`) zu importieren:
 
-{* ../../docs_src/app_testing/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
 
 
 ... und haben den Code für die Tests wie zuvor.
index cb3a40d13eaf8ed95eeb4dfbd3f135a236a6648e..bb70753edd185e3e250622fd567b517230f39318 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.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py39.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.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
 
 It will all be combined and included in your OpenAPI, and shown in the API docs:
 
index e920e22c3c0420bd902ec4fb1f9614b2601fd356..65ddc60b2d93a289698f0f31b7ac62b014ce17f0 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/main.py *}
+{* ../../docs_src/async_tests/app_a_py39/main.py *}
 
 The file `test_main.py` would have the tests for `main.py`, it could look like this now:
 
-{* ../../docs_src/async_tests/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py39/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/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py39/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/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
 
 This is the equivalent to:
 
index f4dbd45607b0f236b287caeae69abe17d4ecf255..4fef02bd1c4c6ff31e684789caf0bcb78ea11829 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.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.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.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.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.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.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.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py39.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.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py39.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.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
 
 and then it won't include it in the OpenAPI schema.
 
index 0f3d8b7017999bbf99641ed2e56d033868c1bfea..e53409c39dfba8786bf5c9b5ccd0d87c4fd43cf2 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.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py39.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.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py39.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.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py39.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.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py39.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.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.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.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py39.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.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py39.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.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
 
 ---
 
 Or you can use it in the `response_class` parameter:
 
 
-{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py39.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.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py39.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.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py39.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.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py39.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.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
 
 You can also use the `response_class` parameter:
 
-{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py39.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.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py39.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.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
 
 /// tip
 
index d9e3cb52e7d427ad07b12df9374201184d63c417..9414b7a3f0a77debf64d36511133fdab66c7d527 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.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py39.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.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py39.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.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py39.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.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py39.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.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py39.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.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
 
 Here, the `shutdown` event handler function will write a text line `"Application shutdown"` to a file `log.txt`.
 
index 897c308086cfa60bec671a87946109d9364a480e..2d0c2aa0c919adbf8047c84fd564cf8121c3085e 100644 (file)
@@ -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.py *}
+{* ../../docs_src/generate_clients/tutorial004_py39.py *}
 
 //// tab | Node.js
 
index 8deb0d917da9ba110c4b2823dd5a728991887c3c..765b389329a2368ab91f9235c8b0e254ecf0b102 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.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py39.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.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py39.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.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
 
 The following arguments are supported:
 
index 416cf4b75b97ba947bd2ff710449f9ef0770ead6..59f060c032e1a5c4b39e0cb23ee95573108ffada 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.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
 
 The webhooks that you define will end up in the **OpenAPI** schema and the automatic **docs UI**.
 
index 5879bc5c71cd58208cb56e54c3682abf66d4f7d0..01196af79e004b82580f96d3bdaf1975d4925a03 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.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.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.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.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.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.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.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.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.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
 
 In this example, we didn't declare any Pydantic model. In fact, the request body is not even <abbr title="converted from some plain format, like bytes, into Python objects">parsed</abbr> as JSON, it is read directly as `bytes`, and the function `magic_data_reader()` would be in charge of parsing it in some way.
 
index 912ed0f1a15987194fe2d01a77f9364f494cdceb..d9708aa627fd63d551bb5c4080feaa8d293bf4bb 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.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py39.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 1f41d84b7c34d4e831aeb952417da58ce0c37db1..5b6fab112b418338ad0d2d77f772179716c7e05c 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.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py39.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.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
 
 /// tip
 
index 156b4dac7e819600d3dd804a068060dc81776dd7..4374cb963743a5ca300cd774f05b406b0f2bdd53 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.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ## Notes { #notes }
 
index 855ba05f80bc1eb51042bb53873d9cab9718f0ca..5e9338fbe2c6caa20e83d0ab077ba6455581b9f1 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.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py39.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.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
 
 /// note | Technical Details
 
index 0220c52ce140888c7f484b28afc2bc9b8e26e58a..268983f1ef0da514fe07d6acb9264335fc9559c3 100644 (file)
@@ -62,7 +62,7 @@ You can use all the same validation features and tools you use for Pydantic mode
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -74,7 +74,7 @@ In Pydantic v1 you would import `BaseSettings` directly from `pydantic` instead
 
 ///
 
-{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -92,7 +92,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.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
 
 ### Run the server { #run-the-server }
 
@@ -126,11 +126,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/config.py *}
+{* ../../docs_src/settings/app01_py39/config.py *}
 
 And then use it in a file `main.py`:
 
-{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
 
 /// tip
 
index fbd0e1af3922fa0bc409e09848e46c4d65037ecc..60bb15c0292c7776f6d55669b802cd8611b375b5 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.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.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.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.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.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
 
 ### Check the automatic API docs { #check-the-automatic-api-docs }
 
index 356f4d9caf450f406c808685b50a464c5222e8b2..c843d60f73e25fdabd916e04bac0c56d89c40750 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.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
 
 /// note
 
index dd93374c4cd520d80261b035ac9f49fa0080a969..13c6e2a259ca9d17edfc928374a39859f55ff555 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.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../docs_src/app_testing/tutorial004_py39.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.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
index 27eb2de2fc024666b190adb3a2ff3a12c1e276c7..a3cc381a33869f18084511a0092a7e1111c9ebca 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.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
 
 /// note
 
index c71d3b05d1200b21d98a4d504476c8249bb8496f..bc23f2df9058d8aceab0a9bc8db9e4e55d28358c 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.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py39.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 ce11485a896f42447d3ae00bf47849647995d48e..286df6943225b4a90867a13b747c1cc7208da196 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.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
 
 ## Create a `websocket` { #create-a-websocket }
 
 In your **FastAPI** application, create a `websocket`:
 
-{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py39.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.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
 
 You can receive and send binary, text, and JSON data.
 
index 29fd2d359c8e2f27dbe224069f1c1069887acda3..07147df0a8c6bec91c65e68f4dc0b90aa55417ab 100644 (file)
@@ -12,7 +12,7 @@ Then wrap the WSGI (e.g. Flask) app with the middleware.
 
 And then mount that under a path.
 
-{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
+{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
 
 ## Check it { #check-it }
 
index e5893e584bdad161441dd6d280fecc384f98a794..ecb45b4a5b5f265860accd202dfeb346b9d43a03 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.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
 
 Here we declare the setting `openapi_url` with the same default of `"/openapi.json"`.
 
index 3dbfcffecac76c9bd8472cba7eec46b1f0618ae4..ff46dc5b1b434e0d4fc11d00faae3f229adae6b3 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.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py39.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.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py39.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.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
 
 ## Other Swagger UI Parameters { #other-swagger-ui-parameters }
 
index 91228c8c930bba3c322897e9c8144c7b73f3ee04..61a97dca2b54fe374720f9d2b7447211c00bb6e0 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.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.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.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.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.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.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.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.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.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.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.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.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.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
 
 ### Test Static Files UI { #test-static-files-ui }
 
index 5e672665ef1fe9f03c746d9f25f9e165c55e08d3..2dc262cbad14c2f53f731f8ec815d01c857a1385 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.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.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.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.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.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.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.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.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.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
 
 ### Check it { #check-it }
 
index 99b024d39b3d0ca60e8f2aae0dc94413f3319bdd..a002c08ca3929f601738ba484216bbb5cc1c3a4d 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.py hl[3,22,25] *}
+{* ../../docs_src/graphql/tutorial001_py39.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 05cd5d27d0bec3a3108f4d74c922268f79983a5f..aac4d6fe40a4aa92f63bab9f4677feb67989d802 100644 (file)
@@ -239,7 +239,7 @@ A PR should have a specific use case that it is solving.
 * If the PR is for a feature, it should have docs.
     * Unless it's a feature we want to discourage, like support for a corner case that we don't want users to use.
 * The docs should include a source example file, not write Python directly in Markdown.
-* If the source example(s) file can have different syntax for Python 3.8, 3.9, 3.10, there should be different versions of the file, and they should be shown in tabs in the docs.
+* If the source example(s) file can have different syntax for different Python versions, there should be different versions of the file, and they should be shown in tabs in the docs.
 * There should be tests testing the source example.
 * Before the PR is applied, the new tests should fail.
 * After applying the PR, the new tests should pass.
index e4bd2a87493e1fd1e822d81674b449c7ec92bc85..b685deef29b73d636950ed874cb026ae284e3f04 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.py *}
+{* ../../docs_src/python_types/tutorial001_py39.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()`.
 * <abbr title="Puts them together, as one. With the contents of one after the other.">Concatenates</abbr> them with a space in the middle.
 
-{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
 
 ### Edit it { #edit-it }
 
@@ -78,7 +78,7 @@ That's it.
 
 Those are the "type hints":
 
-{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py39.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.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py39.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.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
 
 ## Declaring types { #declaring-types }
 
@@ -133,7 +133,7 @@ You can use, for example:
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
 
 ### Generic types with type parameters { #generic-types-with-type-parameters }
 
@@ -161,56 +161,24 @@ If you can use the **latest versions of Python**, use the examples for the lates
 
 For example, let's define a variable to be a `list` of `str`.
 
-//// tab | Python 3.9+
-
 Declare the variable, with the same colon (`:`) syntax.
 
 As the type, put `list`.
 
 As the list is a type that contains some internal types, you put them in square brackets:
 
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-From `typing`, import `List` (with a capital `L`):
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-Declare the variable, with the same colon (`:`) syntax.
-
-As the type, put the `List` that you imported from `typing`.
-
-As the list is a type that contains some internal types, you put them in square brackets:
-
-```Python hl_lines="4"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
 
 /// info
 
 Those internal types in the square brackets are called "type parameters".
 
-In this case, `str` is the type parameter passed to `List` (or `list` in Python 3.9 and above).
+In this case, `str` is the type parameter passed to `list`.
 
 ///
 
 That means: "the variable `items` is a `list`, and each of the items in this list is a `str`".
 
-/// tip
-
-If you use Python 3.9 or above, you don't have to import `List` from `typing`, you can use the same regular `list` type instead.
-
-///
-
 By doing that, your editor can provide support even while processing items from the list:
 
 <img src="/img/python-types/image05.png">
@@ -225,21 +193,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:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial007_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
 
 This means:
 
@@ -254,21 +208,7 @@ The first type parameter is for the keys of the `dict`.
 
 The second type parameter is for the values of the `dict`:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial008_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
 
 This means:
 
@@ -292,10 +232,10 @@ In Python 3.10 there's also a **new syntax** where you can put the possible type
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008b.py!}
+{!> ../../docs_src/python_types/tutorial008b_py39.py!}
 ```
 
 ////
@@ -309,7 +249,7 @@ You can declare that a value could have a type, like `str`, but that it could al
 In Python 3.6 and above (including Python 3.10) you can declare it by importing and using `Optional` from the `typing` module.
 
 ```Python hl_lines="1  4"
-{!../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 Using `Optional[str]` instead of just `str` will let the editor help you detect errors where you could be assuming that a value is always a `str`, when it could actually be `None` too.
@@ -326,18 +266,18 @@ This also means that in Python 3.10, you can use `Something | None`:
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009.py!}
+{!> ../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 ////
 
-//// tab | Python 3.8+ alternative
+//// tab | Python 3.9+ alternative
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009b.py!}
+{!> ../../docs_src/python_types/tutorial009b_py39.py!}
 ```
 
 ////
@@ -357,7 +297,7 @@ It's just about the words and names. But those words can affect how you and your
 
 As an example, let's take this function:
 
-{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
 
 The parameter `name` is defined as `Optional[str]`, but it is **not optional**, you cannot call the function without the parameter:
 
@@ -390,10 +330,10 @@ You can use the same builtin types as generics (with square brackets and types i
 * `set`
 * `dict`
 
-And the same as with Python 3.8, from the `typing` module:
+And the same as with previous Python versions, from the `typing` module:
 
 * `Union`
-* `Optional` (the same as with Python 3.8)
+* `Optional`
 * ...and others.
 
 In Python 3.10, as an alternative to using the generics `Union` and `Optional`, you can use the <abbr title='also called "bitwise or operator", but that meaning is not relevant here'>vertical bar (`|`)</abbr> to declare unions of types, that's a lot better and simpler.
@@ -409,7 +349,7 @@ You can use the same builtin types as generics (with square brackets and types i
 * `set`
 * `dict`
 
-And the same as with Python 3.8, from the `typing` module:
+And generics from the `typing` module:
 
 * `Union`
 * `Optional`
@@ -417,29 +357,17 @@ And the same as with Python 3.8, from the `typing` module:
 
 ////
 
-//// tab | Python 3.8+
-
-* `List`
-* `Tuple`
-* `Set`
-* `Dict`
-* `Union`
-* `Optional`
-* ...and others.
-
-////
-
 ### Classes as types { #classes-as-types }
 
 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.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
 
 Then you can declare a variable to be of type `Person`:
 
-{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
 
 And then, again, you get all the editor support:
 
@@ -463,29 +391,7 @@ And you get all the editor support with that resulting object.
 
 An example from the official Pydantic docs:
 
-//// tab | Python 3.10+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial011_py310.py *}
 
 /// info
 
@@ -507,27 +413,9 @@ Pydantic has a special behavior when you use `Optional` or `Union[Something, Non
 
 Python also has a feature that allows putting **additional <abbr title="Data about the data, in this case, information about the type, e.g. a description.">metadata</abbr>** in these type hints using `Annotated`.
 
-//// tab | Python 3.9+
-
-In Python 3.9, `Annotated` is part of the standard library, so you can import it from `typing`.
+Since Python 3.9, `Annotated` is a part of the standard library, so you can import it from `typing`.
 
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-In versions below Python 3.9, you import `Annotated` from `typing_extensions`.
-
-It will already be installed with **FastAPI**.
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial013_py39.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 ab44f89c19dc1c6e82db19a150d939c2b7169380..be7ecd58715cbc0c05829ae5f769ec2164b6f686 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.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.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.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.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.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
 
 `.add_task()` receives as arguments:
 
index 445235a42030baf8d4932355ab3662ad8b4f4006..5fd83a8f3c78744f549d5849b752afd598b09d88 100644 (file)
@@ -14,35 +14,15 @@ This will make `tags` be a list, although it doesn't declare the type of the ele
 
 But Python has a specific way to declare lists with internal types, or "type parameters":
 
-### Import typing's `List` { #import-typings-list }
-
-In Python 3.9 and above you can use the standard `list` to declare these type annotations as we'll see below. 💡
-
-But in Python versions before 3.9 (3.6 and above), you first need to import `List` from standard Python's `typing` module:
-
-{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
-
 ### Declare a `list` with a type parameter { #declare-a-list-with-a-type-parameter }
 
-To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`:
-
-* If you are in a Python version lower than 3.9, import their equivalent version from the `typing` module
-* Pass the internal type(s) as "type parameters" using square brackets: `[` and `]`
-
-In Python 3.9 it would be:
+To declare types that have type parameters (internal types), like `list`, `dict`, `tuple`,
+pass the internal type(s) as "type parameters" using square brackets: `[` and `]`
 
 ```Python
 my_list: list[str]
 ```
 
-In versions of Python before 3.9, it would be:
-
-```Python
-from typing import List
-
-my_list: List[str]
-```
-
 That's all standard Python syntax for type declarations.
 
 Use that same standard syntax for model attributes with internal types.
@@ -178,12 +158,6 @@ Notice how `Offer` has a list of `Item`s, which in turn have an optional list of
 
 If the top level value of the JSON body you expect is a JSON `array` (a Python `list`), you can declare the type in the parameter of the function, the same as in Pydantic models:
 
-```Python
-images: List[Image]
-```
-
-or in Python 3.9 and above:
-
 ```Python
 images: list[Image]
 ```
index a820802f7404e678d262c48e4be7897eed575df9..25087b84062105e1f3d699a8593f7091272001c7 100644 (file)
@@ -163,7 +163,7 @@ The function parameters will be recognized as follows:
 
 FastAPI will know that the value of `q` is not required because of the default value `= None`.
 
-The `str | None` (Python 3.10+) or `Union` in `Union[str, None]` (Python 3.8+) is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`.
+The `str | None` (Python 3.10+) or `Union` in `Union[str, None]` (Python 3.9+) is not used by FastAPI to determine that the value is not required, it will know it's not required because it has a default value of `= None`.
 
 But adding the type annotations will allow your editor to give you better support and detect errors.
 
index e3de37b43c0a94673d9c2e2f9c1438f7c8d18e5d..8a3a8eb0a8b56cc1f57df4cbc3a234cd6dbab26b 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.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py39.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 08b440084ed1654d2ae2b974e53555b09b3357bd..a2edfe7203902bcbb61f3e273046f5399f578c6d 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.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
 
 ### About `__name__ == "__main__"` { #about-name-main }
 
index 686a5632e2f74130dc66b72a137f4f8d5220d6e1..0a6a786b50c4dc8a7df584be784e49d9e9a491be 100644 (file)
@@ -101,7 +101,7 @@ Now you can declare your dependency using this class.
 
 Notice how we write `CommonQueryParams` twice in the above code:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip
 
@@ -137,7 +137,7 @@ It is from this one that FastAPI will extract the declared parameters and that i
 
 In this case, the first `CommonQueryParams`, in:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip
 
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
 
 You could actually write just:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip
 
@@ -197,7 +197,7 @@ But declaring the type is encouraged as that way your editor will know what will
 
 But you see that we are having some code repetition here, writing `CommonQueryParams` twice:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip
 
@@ -225,7 +225,7 @@ For those specific cases, you can do the following:
 
 Instead of writing:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip
 
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 ...you write:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
 
 ////
 
-//// tab | Python 3.8 non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip
 
index 494c40efab429194b433ca1ac9427bf4784f6748..d9f334561955ce101621571d18ee30033d78716f 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.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
 
 The yielded value is what is injected into *path operations* and other dependencies:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
 
 The code following the `yield` statement is executed after the response:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py39.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.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
 
 ## Sub-dependencies with `yield` { #sub-dependencies-with-yield }
 
@@ -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.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
 
 /// tip
 
index 5814397e53ddba519b707349227dbbdd28496964..df5af2dff2863ea5bdb2fc46de8453e122d55212 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[16] *}
+{* ../../docs_src/dependencies/tutorial012_an_py39.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 d5dc90bef38421fcf2cf07b81afd67c815a2054e..967bffda79dd87f25d66faffa7bc99de8b2ab6a4 100644 (file)
@@ -62,7 +62,7 @@ And it will save the returned value in a <abbr title="A utility/system to store
 
 In an advanced scenario where you know you need the dependency to be called at every step (possibly multiple times) in the same request instead of using the "cached" value, you can set the parameter `use_cache=False` when using `Depends`:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip
 
index b88ff6a187954e12fa903a0259e08b4b7a280e9e..df8e91ecd4a1926c66d33d3d32356adf78ab8dcb 100644 (file)
@@ -2,7 +2,7 @@
 
 The simplest FastAPI file could look like this:
 
-{* ../../docs_src/first_steps/tutorial001.py *}
+{* ../../docs_src/first_steps/tutorial001_py39.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.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py39.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.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py39.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.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py39.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.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py39.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.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py39.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.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
 
 You can return a `dict`, `list`, singular values as `str`, `int`, etc.
 
index 4092039b160dc3798bab28f50418ec9e6add1b1c..0e43d7f6f173fba18994072a2a4c8fd1af4d32ed 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.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.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.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.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.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py39.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.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py39.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.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.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.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.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.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py39.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.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py39.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 55ef620bfc2cd49eff218a3708f4d4e414d2f13d..941359a15426322a93a9e25f8963c3fe72c69233 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.py hl[3:16, 19:32] *}
+{* ../../docs_src/metadata/tutorial001_py39.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.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py39.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.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py39.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.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py39.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.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py39.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.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
index d8889fc63e2f549c8b37551585b54a7471105484..1e77251c587b595ca829bd7e8b8211059b28e0c2 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.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py39.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.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
 
 /// tip
 
index 522d67288ae10d85a264f96c941dec45c79d5dc6..59be5ab37673c935e34353d537bfe9abcee8f595 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.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py39.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 <abbr title="obsolete, recommended not to use it">deprecated</abbr>, but without removing it, pass the parameter `deprecated`:
 
-{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
 
 It will be clearly marked as deprecated in the interactive docs:
 
index f7f2d6ceb0e1279dbbc4d6c3d54c92e6e0d1bcae..8b1b8a83929dda007edcf1784fea8fae8ef88396 100644 (file)
@@ -54,7 +54,7 @@ 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.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.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()`.
 
@@ -83,7 +83,7 @@ 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.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
 
 ### Better with `Annotated` { #better-with-annotated }
 
index 457cc2713f06bf29fb18ddf7ffe34d6df97adc03..ea4307900c56f8b03ffd5f206cec861ef34ba85e 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.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py39.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.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py39.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.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py39.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.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
 
 The first one will always be used since the path matches first.
 
@@ -140,13 +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.py hl[1,6:9] *}
-
-/// info
-
-<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerations (or enums) are available in Python</a> since version 3.4.
-
-///
+{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
 
 /// tip
 
@@ -158,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.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
 
 ### Check the docs { #check-the-docs }
 
@@ -174,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.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py39.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.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
 
 /// tip
 
@@ -194,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.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
 
 In your client you will get a JSON response like:
 
@@ -233,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.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
 
 /// tip
 
index adf08a9249e931d805e27ea40da19e8337f7bad9..aba87a44849a20c58becea485a254fe0d2b114cf 100644 (file)
@@ -55,7 +55,7 @@ q: str | None = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Union[str, None] = None
@@ -73,7 +73,7 @@ q: Annotated[str | None] = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Annotated[Union[str, None]] = None
index 2323b83c7cb9bd5eb7e8428d2e84fbd8b5850760..3c9c225fb0c9b8bde5508cce45d7172784d1035c 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.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py39.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.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
 
 Here the query parameter `needy` is a required query parameter of type `str`.
 
index 5090dbcdfd253a9675c7c479e14070747ec32bbd..a38c610d4fff70b84474a7c4849c1ebb67c00704 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.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py39.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.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
 
 This will also work because `RedirectResponse` is a subclass of `Response`, and FastAPI will automatically handle this simple case.
 
index a2d9757b28cfc75174a494791db964c5aa7b3b90..63895924863c53de4e37e586336809e759e85462 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.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.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.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.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.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py39.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 66b934d4f6118cb19a7ff43430eaa6973c28848e..8cf5a5a8aef2680842d0c345f591402fc467fb72 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.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
 
 /// note | Technical Details
 
index c6a0e5b7d5bb0d971a83d523c21f7908dd3eb28e..f61e62ac549d3b73faf2ea036fc8d5e764bb19d6 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.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py39.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/main.py *}
+{* ../../docs_src/app_testing/app_a_py39/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/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
 
 
 ...and have the code for the tests just like before.
index 08f0a080b56090e7fc04566e612645d726a3d577..d0baa97a4500cfbfad2b6d3a8eacec0d80c6d478 100644 (file)
@@ -26,7 +26,7 @@ Cada uno de esos `dict`s de response puede tener una clave `model`, conteniendo
 
 Por ejemplo, para declarar otro response con un código de estado `404` y un modelo Pydantic `Message`, puedes escribir:
 
-{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
 
 /// note | Nota
 
@@ -203,7 +203,7 @@ Por ejemplo, puedes declarar un response con un código de estado `404` que usa
 
 Y un response con un código de estado `200` que usa tu `response_model`, pero incluye un `example` personalizado:
 
-{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
 
 Todo se combinará e incluirá en tu OpenAPI, y se mostrará en la documentación de la API:
 
index 3a663d50eadda17e1c21859aca6c82e962bcd5b4..4627e9bd18d4c576098554bf00f5878c50c6526b 100644 (file)
@@ -32,11 +32,11 @@ Para un ejemplo simple, consideremos una estructura de archivos similar a la des
 
 El archivo `main.py` tendría:
 
-{* ../../docs_src/async_tests/main.py *}
+{* ../../docs_src/async_tests/app_a_py39/main.py *}
 
 El archivo `test_main.py` tendría los tests para `main.py`, podría verse así ahora:
 
-{* ../../docs_src/async_tests/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
 
 ## Ejecútalo { #run-it }
 
@@ -56,7 +56,7 @@ $ pytest
 
 El marcador `@pytest.mark.anyio` le dice a pytest que esta función de test debe ser llamada asíncronamente:
 
-{* ../../docs_src/async_tests/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
 
 /// tip | Consejo
 
@@ -66,7 +66,7 @@ Nota que la función de test ahora es `async def` en lugar de solo `def` como an
 
 Luego podemos crear un `AsyncClient` con la app y enviar requests asíncronos a ella, usando `await`.
 
-{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
 
 Esto es equivalente a:
 
index 407a35d2ddde5c49567a5de9d04a64f8f1d0280f..f81c16ee812211a5ff8eb0981a5df5fc03909249 100644 (file)
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
 
 Por ejemplo, digamos que defines una *path operation* `/items/`:
 
-{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
 
 Si el cliente intenta ir a `/items`, por defecto, sería redirigido a `/items/`.
 
@@ -115,7 +115,7 @@ En este caso, el path original `/app` realmente sería servido en `/api/v1/app`.
 
 Aunque todo tu código esté escrito asumiendo que solo existe `/app`.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
 
 Y el proxy estaría **"eliminando"** el **prefijo del path** sobre la marcha antes de transmitir el request al servidor de aplicaciones (probablemente Uvicorn a través de FastAPI CLI), manteniendo a tu aplicación convencida de que está siendo servida en `/app`, así que no tienes que actualizar todo tu código para incluir el prefijo `/api/v1`.
 
@@ -193,7 +193,7 @@ Puedes obtener el `root_path` actual utilizado por tu aplicación para cada requ
 
 Aquí lo estamos incluyendo en el mensaje solo con fines de demostración.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
 
 Luego, si inicias Uvicorn con:
 
@@ -220,7 +220,7 @@ El response sería algo como:
 
 Alternativamente, si no tienes una forma de proporcionar una opción de línea de comandos como `--root-path` o su equivalente, puedes configurar el parámetro `root_path` al crear tu app de FastAPI:
 
-{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
 
 Pasar el `root_path` a `FastAPI` sería el equivalente a pasar la opción de línea de comandos `--root-path` a Uvicorn o Hypercorn.
 
@@ -400,7 +400,7 @@ Si pasas una lista personalizada de `servers` y hay un `root_path` (porque tu AP
 
 Por ejemplo:
 
-{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
 
 Generará un esquema de OpenAPI como:
 
@@ -455,7 +455,7 @@ Si no especificas el parámetro `servers` y `root_path` es igual a `/`, la propi
 
 Si no quieres que **FastAPI** incluya un server automático usando el `root_path`, puedes usar el parámetro `root_path_in_servers=False`:
 
-{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
 
 y entonces no lo incluirá en el esquema de OpenAPI.
 
index ace26b3e040f5a6a7957e76823b567b593955958..0884c41a7473d41c12cdc3724b27d476fcf355ae 100644 (file)
@@ -30,7 +30,7 @@ Esto se debe a que, por defecto, FastAPI inspeccionará cada elemento dentro y s
 
 Pero si estás seguro de que el contenido que estás devolviendo es **serializable con JSON**, puedes pasarlo directamente a la clase de response y evitar la sobrecarga extra que FastAPI tendría al pasar tu contenido de retorno a través de `jsonable_encoder` antes de pasarlo a la clase de response.
 
-{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
 
 /// info | Información
 
@@ -55,7 +55,7 @@ Para devolver un response con HTML directamente desde **FastAPI**, usa `HTMLResp
 * Importa `HTMLResponse`.
 * Pasa `HTMLResponse` como parámetro `response_class` de tu *path operation decorator*.
 
-{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
 
 /// info | Información
 
@@ -73,7 +73,7 @@ Como se ve en [Devolver una Response directamente](response-directly.md){.intern
 
 El mismo ejemplo de arriba, devolviendo una `HTMLResponse`, podría verse así:
 
-{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
 
 /// warning | Advertencia
 
@@ -97,7 +97,7 @@ El `response_class` solo se usará para documentar el OpenAPI *path operation*,
 
 Por ejemplo, podría ser algo así:
 
-{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
 
 En este ejemplo, la función `generate_html_response()` ya genera y devuelve una `Response` en lugar de devolver el HTML en un `str`.
 
@@ -136,7 +136,7 @@ Acepta los siguientes parámetros:
 
 FastAPI (de hecho Starlette) incluirá automáticamente un header Content-Length. También incluirá un header Content-Type, basado en el `media_type` y añadiendo un conjunto de caracteres para tipos de texto.
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ### `HTMLResponse` { #htmlresponse }
 
@@ -146,7 +146,7 @@ Toma algún texto o bytes y devuelve un response HTML, como leíste arriba.
 
 Toma algún texto o bytes y devuelve un response de texto plano.
 
-{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
 
 ### `JSONResponse` { #jsonresponse }
 
@@ -180,7 +180,7 @@ Esto requiere instalar `ujson`, por ejemplo, con `pip install ujson`.
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
 
 /// tip | Consejo
 
@@ -194,13 +194,13 @@ Devuelve una redirección HTTP. Usa un código de estado 307 (Redirección Tempo
 
 Puedes devolver un `RedirectResponse` directamente:
 
-{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
 
 ---
 
 O puedes usarlo en el parámetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
 
 Si haces eso, entonces puedes devolver la URL directamente desde tu *path operation function*.
 
@@ -210,13 +210,13 @@ En este caso, el `status_code` utilizado será el por defecto para `RedirectResp
 
 También puedes usar el parámetro `status_code` combinado con el parámetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
 
 ### `StreamingResponse` { #streamingresponse }
 
 Toma un generador `async` o un generador/iterador normal y transmite el cuerpo del response.
 
-{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
 
 #### Usando `StreamingResponse` con objetos similares a archivos { #using-streamingresponse-with-file-like-objects }
 
@@ -226,7 +226,7 @@ De esa manera, no tienes que leerlo todo primero en memoria, y puedes pasar esa
 
 Esto incluye muchos paquetes para interactuar con almacenamiento en la nube, procesamiento de video y otros.
 
-{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
 
 1. Esta es la función generadora. Es una "función generadora" porque contiene declaraciones `yield` dentro.
 2. Al usar un bloque `with`, nos aseguramos de que el objeto similar a un archivo se cierre después de que la función generadora termine. Así, después de que termina de enviar el response.
@@ -255,11 +255,11 @@ Toma un conjunto diferente de argumentos para crear un instance que los otros ti
 
 Los responses de archivos incluirán los headers apropiados `Content-Length`, `Last-Modified` y `ETag`.
 
-{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
 
 También puedes usar el parámetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
 
 En este caso, puedes devolver la path del archivo directamente desde tu *path operation* function.
 
@@ -273,7 +273,7 @@ Digamos que quieres que devuelva JSON con sangría y formato, por lo que quieres
 
 Podrías crear un `CustomORJSONResponse`. Lo principal que tienes que hacer es crear un método `Response.render(content)` que devuelva el contenido como `bytes`:
 
-{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
 
 Ahora en lugar de devolver:
 
@@ -299,7 +299,7 @@ El parámetro que define esto es `default_response_class`.
 
 En el ejemplo a continuación, **FastAPI** usará `ORJSONResponse` por defecto, en todas las *path operations*, en lugar de `JSONResponse`.
 
-{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
 
 /// tip | Consejo
 
index bf06e715a74c0fd55df84e9ca752233ec112650f..c2002a6f5334effaec09fae528ff15e5a237140e 100644 (file)
@@ -30,7 +30,7 @@ Comencemos con un ejemplo y luego veámoslo en detalle.
 
 Creamos una función asíncrona `lifespan()` con `yield` así:
 
-{* ../../docs_src/events/tutorial003.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
 
 Aquí estamos simulando la operación costosa de *startup* de cargar el modelo poniendo la función del (falso) modelo en el diccionario con modelos de machine learning antes del `yield`. Este código será ejecutado **antes** de que la aplicación **comience a tomar requests**, durante el *startup*.
 
@@ -48,7 +48,7 @@ Quizás necesites iniciar una nueva versión, o simplemente te cansaste de ejecu
 
 Lo primero que hay que notar es que estamos definiendo una función asíncrona con `yield`. Esto es muy similar a las Dependencias con `yield`.
 
-{* ../../docs_src/events/tutorial003.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
 
 La primera parte de la función, antes del `yield`, será ejecutada **antes** de que la aplicación comience.
 
@@ -60,7 +60,7 @@ Si revisas, la función está decorada con un `@asynccontextmanager`.
 
 Eso convierte a la función en algo llamado un "**async context manager**".
 
-{* ../../docs_src/events/tutorial003.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
 
 Un **context manager** en Python es algo que puedes usar en un statement `with`, por ejemplo, `open()` puede ser usado como un context manager:
 
@@ -82,7 +82,7 @@ En nuestro ejemplo de código arriba, no lo usamos directamente, pero se lo pasa
 
 El parámetro `lifespan` de la app de `FastAPI` toma un **async context manager**, por lo que podemos pasar nuestro nuevo `lifespan` async context manager a él.
 
-{* ../../docs_src/events/tutorial003.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
 
 ## Eventos Alternativos (obsoleto) { #alternative-events-deprecated }
 
@@ -104,7 +104,7 @@ Estas funciones pueden ser declaradas con `async def` o `def` normal.
 
 Para añadir una función que debería ejecutarse antes de que la aplicación inicie, declárala con el evento `"startup"`:
 
-{* ../../docs_src/events/tutorial001.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
 
 En este caso, la función manejadora del evento `startup` inicializará los ítems de la "base de datos" (solo un `dict`) con algunos valores.
 
@@ -116,7 +116,7 @@ Y tu aplicación no comenzará a recibir requests hasta que todos los manejadore
 
 Para añadir una función que debería ejecutarse cuando la aplicación se esté cerrando, declárala con el evento `"shutdown"`:
 
-{* ../../docs_src/events/tutorial002.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
 
 Aquí, la función manejadora del evento `shutdown` escribirá una línea de texto `"Application shutdown"` a un archivo `log.txt`.
 
index 861b58b508b50a2d638e958bb5140c4b41cdfc41..daf6cefed3fa4ce49a2659df922be7b7dd4e4dc3 100644 (file)
@@ -167,7 +167,7 @@ Pero para el cliente generado podríamos **modificar** los operation IDs de Open
 
 Podríamos descargar el JSON de OpenAPI a un archivo `openapi.json` y luego podríamos **remover ese tag prefijado** con un script como este:
 
-{* ../../docs_src/generate_clients/tutorial004.py *}
+{* ../../docs_src/generate_clients/tutorial004_py39.py *}
 
 //// tab | Node.js
 
index 4783612a4b2f1512e3e7765ae652d468560abef0..7eead8ae14590f2ed9ae859297622c139ec5c9e5 100644 (file)
@@ -57,13 +57,13 @@ Impone que todas las requests entrantes deben ser `https` o `wss`.
 
 Cualquier request entrante a `http` o `ws` será redirigida al esquema seguro.
 
-{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
 
 ## `TrustedHostMiddleware` { #trustedhostmiddleware }
 
 Impone que todas las requests entrantes tengan correctamente configurado el header `Host`, para proteger contra ataques de HTTP Host Header.
 
-{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
 
 Se soportan los siguientes argumentos:
 
@@ -78,7 +78,7 @@ Maneja responses GZip para cualquier request que incluya `"gzip"` en el header `
 
 El middleware manejará tanto responses estándar como en streaming.
 
-{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
 
 Se soportan los siguientes argumentos:
 
index 2dfa74b21003c1651747fb3ff1281b4e0961719b..c358a140086f8f2d191559deba2bb78a91742826 100644 (file)
@@ -32,7 +32,7 @@ Los webhooks están disponibles en OpenAPI 3.1.0 y superiores, soportados por Fa
 
 Cuando creas una aplicación de **FastAPI**, hay un atributo `webhooks` que puedes usar para definir *webhooks*, de la misma manera que definirías *path operations*, por ejemplo con `@app.webhooks.post()`.
 
-{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
 
 Los webhooks que defines terminarán en el esquema de **OpenAPI** y en la interfaz automática de **documentación**.
 
index 98965ee9e2da4b28fac0c38bced705e26c248ece..396159868b3fbf6434e9c39c2edc48ce8a911239 100644 (file)
@@ -12,7 +12,7 @@ Puedes establecer el `operationId` de OpenAPI para ser usado en tu *path operati
 
 Tienes que asegurarte de que sea único para cada operación.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
 
 ### Usar el nombre de la *path operation function* como el operationId { #using-the-path-operation-function-name-as-the-operationid }
 
@@ -20,7 +20,7 @@ Si quieres usar los nombres de las funciones de tus APIs como `operationId`s, pu
 
 Deberías hacerlo después de agregar todas tus *path operations*.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
 
 /// tip | Consejo
 
@@ -40,7 +40,7 @@ Incluso si están en diferentes módulos (archivos de Python).
 
 Para excluir una *path operation* del esquema OpenAPI generado (y por lo tanto, de los sistemas de documentación automática), utiliza el parámetro `include_in_schema` y configúralo en `False`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
 
 ## Descripción avanzada desde el docstring { #advanced-description-from-docstring }
 
@@ -92,7 +92,7 @@ Puedes extender el esquema de OpenAPI para una *path operation* usando el parám
 
 Este `openapi_extra` puede ser útil, por ejemplo, para declarar [Extensiones de OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
 
 Si abres la documentación automática de la API, tu extensión aparecerá en la parte inferior de la *path operation* específica.
 
@@ -139,7 +139,7 @@ Por ejemplo, podrías decidir leer y validar el request con tu propio código, s
 
 Podrías hacer eso con `openapi_extra`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
 
 En este ejemplo, no declaramos ningún modelo Pydantic. De hecho, el cuerpo del request ni siquiera se <abbr title="convertido de algún formato plano, como bytes, a objetos de Python">parse</abbr> como JSON, se lee directamente como `bytes`, y la función `magic_data_reader()` sería la encargada de parsearlo de alguna manera.
 
index 067267750b6192f6e7d8b1e6e3bb75d498d93a03..940f1dd3ff6f67c1537b6a4624f4a7642e625610 100644 (file)
@@ -20,7 +20,7 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function*
 
 Y luego puedes establecer el `status_code` en ese objeto de response *temporal*.
 
-{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
 
 Y luego puedes devolver cualquier objeto que necesites, como lo harías normalmente (un `dict`, un modelo de base de datos, etc.).
 
index ce2ff0281d7ecff0e1e677d672508d54e4f3ffe9..550a5d97a774760c526b1a1915f7f95fe3e0f65d 100644 (file)
@@ -6,7 +6,7 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function*
 
 Y luego puedes establecer cookies en ese objeto de response *temporal*.
 
-{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
 
 Y entonces puedes devolver cualquier objeto que necesites, como normalmente lo harías (un `dict`, un modelo de base de datos, etc).
 
@@ -24,7 +24,7 @@ Para hacer eso, puedes crear un response como se describe en [Devolver un Respon
 
 Luego establece Cookies en ella, y luego devuélvela:
 
-{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
 
 /// tip | Consejo
 
index 96b30b915c031643050f1bb6b06d4fb912767d3e..2da4e84e706f6b60ba74f5e4408b6171a54e54a6 100644 (file)
@@ -54,7 +54,7 @@ Digamos que quieres devolver un response en <a href="https://en.wikipedia.org/wi
 
 Podrías poner tu contenido XML en un string, poner eso en un `Response`, y devolverlo:
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ## Notas { #notes }
 
index c4fdebed4265c906acbb9594a117982d4427d95b..9e099bca3d474114eb81e2bf3c17f7a82144f51e 100644 (file)
@@ -6,7 +6,7 @@ Puedes declarar un parámetro de tipo `Response` en tu *path operation function*
 
 Y luego puedes establecer headers en ese objeto de response *temporal*.
 
-{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
 
 Y luego puedes devolver cualquier objeto que necesites, como harías normalmente (un `dict`, un modelo de base de datos, etc).
 
@@ -22,7 +22,7 @@ También puedes agregar headers cuando devuelves un `Response` directamente.
 
 Crea un response como se describe en [Retorna un Response Directamente](response-directly.md){.internal-link target=_blank} y pasa los headers como un parámetro adicional:
 
-{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
 
 /// note | Detalles Técnicos
 
index 65dee933dbc916b56185d430fb20eed4ea0f2abd..610bda5e247328c27d1e6c56504f9fc787098430 100644 (file)
@@ -62,7 +62,7 @@ Puedes usar todas las mismas funcionalidades de validación y herramientas que u
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -74,7 +74,7 @@ En Pydantic v1 importarías `BaseSettings` directamente desde `pydantic` en luga
 
 ///
 
-{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -92,7 +92,7 @@ Luego convertirá y validará los datos. Así que, cuando uses ese objeto `setti
 
 Luego puedes usar el nuevo objeto `settings` en tu aplicación:
 
-{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
 
 ### Ejecutar el servidor { #run-the-server }
 
@@ -126,11 +126,11 @@ Podrías poner esas configuraciones en otro archivo de módulo como viste en [Ap
 
 Por ejemplo, podrías tener un archivo `config.py` con:
 
-{* ../../docs_src/settings/app01/config.py *}
+{* ../../docs_src/settings/app01_py39/config.py *}
 
 Y luego usarlo en un archivo `main.py`:
 
-{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
 
 /// tip | Consejo
 
index ddc0cd69a5227d3d4d469dc505caa6654fd497f3..f604d18bad3f36546b6656630085f8e8591228a0 100644 (file)
@@ -10,7 +10,7 @@ Si necesitas tener dos aplicaciones de **FastAPI** independientes, cada una con
 
 Primero, crea la aplicación principal de nivel superior de **FastAPI**, y sus *path operations*:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
 
 ### Sub-aplicación { #sub-application }
 
@@ -18,7 +18,7 @@ Luego, crea tu sub-aplicación, y sus *path operations*.
 
 Esta sub-aplicación es solo otra aplicación estándar de FastAPI, pero es la que se "montará":
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
 
 ### Montar la sub-aplicación { #mount-the-sub-application }
 
@@ -26,7 +26,7 @@ En tu aplicación de nivel superior, `app`, monta la sub-aplicación, `subapi`.
 
 En este caso, se montará en el path `/subapi`:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
 
 ### Revisa la documentación automática de la API { #check-the-automatic-api-docs }
 
index f6b7eb63687abae895fdfed9ae4a32f4e2bf0bc2..e5e8fe0613b4ed484350e0bfb2682c378e988d0d 100644 (file)
@@ -27,7 +27,7 @@ $ pip install jinja2
 * Declara un parámetro `Request` en la *path operation* que devolverá una plantilla.
 * Usa los `templates` que creaste para renderizar y devolver un `TemplateResponse`, pasa el nombre de la plantilla, el objeto de request, y un diccionario "context" con pares clave-valor que se usarán dentro de la plantilla Jinja2.
 
-{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
 
 /// note | Nota
 
index 3b48d5fa12ee143b7ae27c2b17dd9874d6b15874..4f7bf0314795371af458069ab702e9c0d73b26a2 100644 (file)
@@ -2,11 +2,11 @@
 
 Cuando necesitas que `lifespan` se ejecute en tus tests, puedes usar el `TestClient` con un statement `with`:
 
-{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
 
 
 Puedes leer más detalles sobre ["Ejecutar lifespan en tests en el sitio oficial de documentación de Starlette."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
 
 Para los eventos obsoletos `startup` y `shutdown`, puedes usar el `TestClient` así:
 
-{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
index 092c75f57193fbb2a3b6d274df6bf98b8242a233..3f60aa2caf35d7d48a84acd2ee76e8b11d9bfe95 100644 (file)
@@ -4,7 +4,7 @@ Puedes usar el mismo `TestClient` para probar WebSockets.
 
 Para esto, usas el `TestClient` en un statement `with`, conectándote al WebSocket:
 
-{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
 
 /// note | Nota
 
index 74426f302bd6dcfca049024b1cba12dc24a304ee..64feef81d73bf5e6e0f8f224eaf563e96706ee77 100644 (file)
@@ -29,7 +29,7 @@ Imaginemos que quieres obtener la dirección IP/host del cliente dentro de tu *p
 
 Para eso necesitas acceder al request directamente.
 
-{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
 
 Al declarar un parámetro de *path operation function* con el tipo siendo `Request`, **FastAPI** sabrá pasar el `Request` en ese parámetro.
 
index 6b70e02b1f7e1f3a67db70af4d84e6babb16517c..39ddc12c4d10abbcbe0dfaa1d5d99e17dfaef35c 100644 (file)
@@ -38,13 +38,13 @@ En producción tendrías una de las opciones anteriores.
 
 Pero es la forma más sencilla de enfocarse en el lado del servidor de WebSockets y tener un ejemplo funcional:
 
-{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
 
 ## Crear un `websocket` { #create-a-websocket }
 
 En tu aplicación de **FastAPI**, crea un `websocket`:
 
-{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
 
 /// note | Detalles Técnicos
 
@@ -58,7 +58,7 @@ También podrías usar `from starlette.websockets import WebSocket`.
 
 En tu ruta de WebSocket puedes `await` para recibir mensajes y enviar mensajes.
 
-{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
 
 Puedes recibir y enviar datos binarios, de texto y JSON.
 
index 9fd54e68da61adad1b3f5071622838c1f058272b..d5113250abf2991469e2c2909ec74cb712fc0cd7 100644 (file)
@@ -12,7 +12,7 @@ Luego envuelve la aplicación WSGI (p. ej., Flask) con el middleware.
 
 Y luego móntala bajo un path.
 
-{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
+{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
 
 ## Revisa { #check-it }
 
index 0e04b3d5485925492f7a9900b3c7fcba587890d2..a06ad95489f2fdacad9cbcd7452503554b9703e9 100644 (file)
@@ -29,7 +29,7 @@ Puedes usar fácilmente las mismas configuraciones de Pydantic para configurar t
 
 Por ejemplo:
 
-{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
 
 Aquí declaramos la configuración `openapi_url` con el mismo valor por defecto de `"/openapi.json"`.
 
index 23f4ac1aaa3d278a998006e8972bcc2a8cf6f8dc..b2865d77d591fb06c2a7ebd23cfc2acd11d8a6cb 100644 (file)
@@ -18,7 +18,7 @@ Sin cambiar la configuración, el resaltado de sintaxis está activado por defec
 
 Pero puedes desactivarlo estableciendo `syntaxHighlight` en `False`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
 
 ...y entonces Swagger UI ya no mostrará el resaltado de sintaxis:
 
@@ -28,7 +28,7 @@ Pero puedes desactivarlo estableciendo `syntaxHighlight` en `False`:
 
 De la misma manera, podrías configurar el tema del resaltado de sintaxis con la clave `"syntaxHighlight.theme"` (ten en cuenta que tiene un punto en el medio):
 
-{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
 
 Esa configuración cambiaría el tema de color del resaltado de sintaxis:
 
@@ -46,7 +46,7 @@ Puedes sobrescribir cualquiera de ellos estableciendo un valor diferente en el a
 
 Por ejemplo, para desactivar `deepLinking` podrías pasar estas configuraciones a `swagger_ui_parameters`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
 
 ## Otros parámetros de Swagger UI { #other-swagger-ui-parameters }
 
index e9f97702657b9f582f1266ed65bad8698ed1c92c..acd3f8d6d66129717c0af2f4a8f178b4ff327c63 100644 (file)
@@ -18,7 +18,7 @@ El primer paso es desactivar la documentación automática, ya que por defecto,
 
 Para desactivarlos, establece sus URLs en `None` cuando crees tu aplicación de `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
 
 ### Incluye la documentación personalizada { #include-the-custom-docs }
 
@@ -34,7 +34,7 @@ Puedes reutilizar las funciones internas de FastAPI para crear las páginas HTML
 
 Y de manera similar para ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
 
 /// tip | Consejo
 
@@ -50,7 +50,7 @@ Swagger UI lo manejará detrás de escena para ti, pero necesita este auxiliar d
 
 Ahora, para poder probar que todo funciona, crea una *path operation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
 
 ### Pruébalo { #test-it }
 
@@ -118,7 +118,7 @@ Después de eso, tu estructura de archivos podría verse así:
 * Importa `StaticFiles`.
 * "Monta" una instance de `StaticFiles()` en un path específico.
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
 
 ### Prueba los archivos estáticos { #test-the-static-files }
 
@@ -144,7 +144,7 @@ Igual que cuando usas un CDN personalizado, el primer paso es desactivar la docu
 
 Para desactivarlos, establece sus URLs en `None` cuando crees tu aplicación de `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
 
 ### Incluye la documentación personalizada para archivos estáticos { #include-the-custom-docs-for-static-files }
 
@@ -160,7 +160,7 @@ Nuevamente, puedes reutilizar las funciones internas de FastAPI para crear las p
 
 Y de manera similar para ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
 
 /// tip | Consejo
 
@@ -176,7 +176,7 @@ Swagger UI lo manejará detrás de escena para ti, pero necesita este auxiliar d
 
 Ahora, para poder probar que todo funciona, crea una *path operation*:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
 
 ### Prueba la UI de Archivos Estáticos { #test-static-files-ui }
 
index 299c54124677fb2068b7ea59b793a7aba086e7cd..2611b6e1b67fbab566db9781f4e1d92d3de4a368 100644 (file)
@@ -43,19 +43,19 @@ Por ejemplo, vamos a añadir <a href="https://github.com/Rebilly/ReDoc/blob/mast
 
 Primero, escribe toda tu aplicación **FastAPI** como normalmente:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
 
 ### Generar el esquema de OpenAPI { #generate-the-openapi-schema }
 
 Luego, usa la misma función de utilidad para generar el esquema de OpenAPI, dentro de una función `custom_openapi()`:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
 
 ### Modificar el esquema de OpenAPI { #modify-the-openapi-schema }
 
 Ahora puedes añadir la extensión de ReDoc, agregando un `x-logo` personalizado al "objeto" `info` en el esquema de OpenAPI:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
 
 ### Cachear el esquema de OpenAPI { #cache-the-openapi-schema }
 
@@ -65,13 +65,13 @@ De esa forma, tu aplicación no tendrá que generar el esquema cada vez que un u
 
 Se generará solo una vez, y luego se usará el mismo esquema cacheado para las siguientes requests.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
 
 ### Sobrescribir el método { #override-the-method }
 
 Ahora puedes reemplazar el método `.openapi()` por tu nueva función.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
 
 ### Revisa { #check-it }
 
index 76031b67128160e294a4ad632e8c3e4563c6f985..2ebfb3dd081f5063550ebccc283742915c98e71c 100644 (file)
@@ -35,7 +35,7 @@ Dependiendo de tu caso de uso, podrías preferir usar un paquete diferente, pero
 
 Aquí tienes una pequeña vista previa de cómo podrías integrar Strawberry con FastAPI:
 
-{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *}
+{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *}
 
 Puedes aprender más sobre Strawberry en la <a href="https://strawberry.rocks/" class="external-link" target="_blank">documentación de Strawberry</a>.
 
index e51c2352c5d0a3c8351c13811d6bf4cf7c102b09..60b50a08ff6d90073af61c8aabcabfc2a7ab61cc 100644 (file)
@@ -22,7 +22,7 @@ Si eres un experto en Python, y ya sabes todo sobre las anotaciones de tipos, sa
 
 Comencemos con un ejemplo simple:
 
-{* ../../docs_src/python_types/tutorial001.py *}
+{* ../../docs_src/python_types/tutorial001_py39.py *}
 
 Llamar a este programa genera:
 
@@ -36,7 +36,7 @@ La función hace lo siguiente:
 * Convierte la primera letra de cada uno a mayúsculas con `title()`.
 * <abbr title="Los une, como uno. Con el contenido de uno después del otro.">Concatena</abbr> ambos con un espacio en el medio.
 
-{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
 
 ### Edítalo { #edit-it }
 
@@ -78,7 +78,7 @@ Eso es todo.
 
 Esas son las "anotaciones de tipos":
 
-{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
 
 Eso no es lo mismo que declarar valores predeterminados como sería con:
 
@@ -106,7 +106,7 @@ Con eso, puedes desplazarte, viendo las opciones, hasta que encuentres la que "t
 
 Revisa esta función, ya tiene anotaciones de tipos:
 
-{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
 
 Porque el editor conoce los tipos de las variables, no solo obtienes autocompletado, también obtienes chequeo de errores:
 
@@ -114,7 +114,7 @@ Porque el editor conoce los tipos de las variables, no solo obtienes autocomplet
 
 Ahora sabes que debes corregirlo, convertir `age` a un string con `str(age)`:
 
-{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
 
 ## Declaración de tipos { #declaring-types }
 
@@ -133,7 +133,7 @@ Puedes usar, por ejemplo:
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
 
 ### Tipos genéricos con parámetros de tipo { #generic-types-with-type-parameters }
 
@@ -161,56 +161,24 @@ Si puedes usar las **últimas versiones de Python**, utiliza los ejemplos para l
 
 Por ejemplo, vamos a definir una variable para ser una `list` de `str`.
 
-//// tab | Python 3.9+
-
 Declara la variable, con la misma sintaxis de dos puntos (`:`).
 
 Como tipo, pon `list`.
 
 Como la lista es un tipo que contiene algunos tipos internos, los pones entre corchetes:
 
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-De `typing`, importa `List` (con una `L` mayúscula):
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-Declara la variable, con la misma sintaxis de dos puntos (`:`).
-
-Como tipo, pon el `List` que importaste de `typing`.
-
-Como la lista es un tipo que contiene algunos tipos internos, los pones entre corchetes:
-
-```Python hl_lines="4"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
 
 /// info | Información
 
 Esos tipos internos en los corchetes se denominan "parámetros de tipo".
 
-En este caso, `str` es el parámetro de tipo pasado a `List` (o `list` en Python 3.9 y superior).
+En este caso, `str` es el parámetro de tipo pasado a `list`.
 
 ///
 
 Eso significa: "la variable `items` es una `list`, y cada uno de los ítems en esta lista es un `str`".
 
-/// tip | Consejo
-
-Si usas Python 3.9 o superior, no tienes que importar `List` de `typing`, puedes usar el mismo tipo `list` regular en su lugar.
-
-///
-
 Al hacer eso, tu editor puede proporcionar soporte incluso mientras procesa elementos de la lista:
 
 <img src="/img/python-types/image05.png">
@@ -225,21 +193,7 @@ Y aún así, el editor sabe que es un `str` y proporciona soporte para eso.
 
 Harías lo mismo para declarar `tuple`s y `set`s:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial007_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
 
 Esto significa:
 
@@ -254,21 +208,7 @@ El primer parámetro de tipo es para las claves del `dict`.
 
 El segundo parámetro de tipo es para los valores del `dict`:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial008_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
 
 Esto significa:
 
@@ -292,10 +232,10 @@ En Python 3.10 también hay una **nueva sintaxis** donde puedes poner los posibl
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008b.py!}
+{!> ../../docs_src/python_types/tutorial008b_py39.py!}
 ```
 
 ////
@@ -309,7 +249,7 @@ Puedes declarar que un valor podría tener un tipo, como `str`, pero que tambié
 En Python 3.6 y posteriores (incluyendo Python 3.10) puedes declararlo importando y usando `Optional` del módulo `typing`.
 
 ```Python hl_lines="1  4"
-{!../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 Usar `Optional[str]` en lugar de solo `str` te permitirá al editor ayudarte a detectar errores donde podrías estar asumiendo que un valor siempre es un `str`, cuando en realidad también podría ser `None`.
@@ -326,18 +266,18 @@ Esto también significa que en Python 3.10, puedes usar `Something | None`:
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009.py!}
+{!> ../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 ////
 
-//// tab | Python 3.8+ alternativa
+//// tab | Python 3.9+ alternativa
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009b.py!}
+{!> ../../docs_src/python_types/tutorial009b_py39.py!}
 ```
 
 ////
@@ -357,7 +297,7 @@ Se trata solo de las palabras y nombres. Pero esas palabras pueden afectar cómo
 
 Como ejemplo, tomemos esta función:
 
-{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
 
 El parámetro `name` está definido como `Optional[str]`, pero **no es opcional**, no puedes llamar a la función sin el parámetro:
 
@@ -390,10 +330,10 @@ Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos d
 * `set`
 * `dict`
 
-Y lo mismo que con Python 3.8, desde el módulo `typing`:
+Y, como con versiones anteriores de Python, desde el módulo `typing`:
 
 * `Union`
-* `Optional` (lo mismo que con Python 3.8)
+* `Optional`
 * ...y otros.
 
 En Python 3.10, como alternativa a usar los genéricos `Union` y `Optional`, puedes usar la <abbr title='también llamado "operador OR a nivel de bits", pero ese significado no es relevante aquí'>barra vertical (`|`)</abbr> para declarar uniones de tipos, eso es mucho mejor y más simple.
@@ -409,7 +349,7 @@ Puedes usar los mismos tipos integrados como genéricos (con corchetes y tipos d
 * `set`
 * `dict`
 
-Y lo mismo que con Python 3.8, desde el módulo `typing`:
+Y generics desde el módulo `typing`:
 
 * `Union`
 * `Optional`
@@ -417,29 +357,17 @@ Y lo mismo que con Python 3.8, desde el módulo `typing`:
 
 ////
 
-//// tab | Python 3.8+
-
-* `List`
-* `Tuple`
-* `Set`
-* `Dict`
-* `Union`
-* `Optional`
-* ...y otros.
-
-////
-
 ### Clases como tipos { #classes-as-types }
 
 También puedes declarar una clase como el tipo de una variable.
 
 Digamos que tienes una clase `Person`, con un nombre:
 
-{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
 
 Luego puedes declarar una variable para que sea de tipo `Person`:
 
-{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
 
 Y luego, nuevamente, obtienes todo el soporte del editor:
 
@@ -463,29 +391,7 @@ Y obtienes todo el soporte del editor con ese objeto resultante.
 
 Un ejemplo de la documentación oficial de Pydantic:
 
-//// tab | Python 3.10+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial011_py310.py *}
 
 /// info | Información
 
@@ -507,27 +413,9 @@ Pydantic tiene un comportamiento especial cuando utilizas `Optional` o `Union[So
 
 Python también tiene una funcionalidad que permite poner **<abbr title="Datos sobre los datos, en este caso, información sobre el tipo, por ejemplo, una descripción.">metadatos</abbr> adicional** en estas anotaciones de tipos usando `Annotated`.
 
-//// tab | Python 3.9+
-
-En Python 3.9, `Annotated` es parte de la standard library, así que puedes importarlo desde `typing`.
+Desde Python 3.9, `Annotated` es parte de la standard library, así que puedes importarlo desde `typing`.
 
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-En versiones por debajo de Python 3.9, importas `Annotated` de `typing_extensions`.
-
-Ya estará instalado con **FastAPI**.
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
 
 Python en sí no hace nada con este `Annotated`. Y para los editores y otras herramientas, el tipo sigue siendo `str`.
 
index 8cd0767f8ebc7a8a19975a65afdb9c6c78a0a821..cc8a2c9cbe4d9a8f15a2c2e2fa54b28befc95b94 100644 (file)
@@ -15,7 +15,7 @@ Esto incluye, por ejemplo:
 
 Primero, importa `BackgroundTasks` y define un parámetro en tu *path operation function* con una declaración de tipo de `BackgroundTasks`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
 
 **FastAPI** creará el objeto de tipo `BackgroundTasks` por ti y lo pasará como ese parámetro.
 
@@ -31,13 +31,13 @@ En este caso, la función de tarea escribirá en un archivo (simulando el envío
 
 Y como la operación de escritura no usa `async` y `await`, definimos la función con un `def` normal:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
 
 ## Agregar la tarea en segundo plano { #add-the-background-task }
 
 Dentro de tu *path operation function*, pasa tu función de tarea al objeto de *background tasks* con el método `.add_task()`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
 
 `.add_task()` recibe como argumentos:
 
index 04f4b39c4a90f4a5397e54b3d3c72796c8fe24b2..0dfd6576f1e3aa3f64d65d47d7904fbbae84d005 100644 (file)
@@ -14,35 +14,15 @@ Esto hará que `tags` sea una lista, aunque no declare el tipo de los elementos
 
 Pero Python tiene una forma específica de declarar listas con tipos internos, o "parámetros de tipo":
 
-### Importar `List` de typing { #import-typings-list }
-
-En Python 3.9 y superior, puedes usar el `list` estándar para declarar estas anotaciones de tipo como veremos a continuación. 💡
-
-Pero en versiones de Python anteriores a 3.9 (desde 3.6 en adelante), primero necesitas importar `List` del módulo `typing` estándar de Python:
-
-{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
-
 ### Declarar una `list` con un parámetro de tipo { #declare-a-list-with-a-type-parameter }
 
-Para declarar tipos que tienen parámetros de tipo (tipos internos), como `list`, `dict`, `tuple`:
-
-* Si estás en una versión de Python inferior a 3.9, importa su versión equivalente del módulo `typing`
-* Pasa el/los tipo(s) interno(s) como "parámetros de tipo" usando corchetes: `[` y `]`
-
-En Python 3.9 sería:
+Para declarar tipos que tienen parámetros de tipo (tipos internos), como `list`, `dict`, `tuple`,
+pasa el/los tipo(s) interno(s) como "parámetros de tipo" usando corchetes: `[` y `]`
 
 ```Python
 my_list: list[str]
 ```
 
-En versiones de Python anteriores a 3.9, sería:
-
-```Python
-from typing import List
-
-my_list: List[str]
-```
-
 Eso es toda la sintaxis estándar de Python para declaraciones de tipo.
 
 Usa esa misma sintaxis estándar para atributos de modelos con tipos internos.
@@ -178,12 +158,6 @@ Observa cómo `Offer` tiene una lista de `Item`s, que a su vez tienen una lista
 
 Si el valor superior del cuerpo JSON que esperas es un `array` JSON (una `list` en Python), puedes declarar el tipo en el parámetro de la función, al igual que en los modelos Pydantic:
 
-```Python
-images: List[Image]
-```
-
-o en Python 3.9 y superior:
-
 ```Python
 images: list[Image]
 ```
index 58877c5c46e5963b96ccdd217dbf247b8de5c418..06a70dbc796fe7947aeac01225046e4b22250832 100644 (file)
@@ -161,7 +161,7 @@ Los parámetros de la función se reconocerán de la siguiente manera:
 
 FastAPI sabrá que el valor de `q` no es requerido debido al valor por defecto `= None`.
 
-El `str | None` (Python 3.10+) o `Union` en `Union[str, None]` (Python 3.8+) no es utilizado por FastAPI para determinar que el valor no es requerido, sabrá que no es requerido porque tiene un valor por defecto de `= None`.
+El `str | None` (Python 3.10+) o `Union` en `Union[str, None]` (Python 3.9+) no es utilizado por FastAPI para determinar que el valor no es requerido, sabrá que no es requerido porque tiene un valor por defecto de `= None`.
 
 Pero agregar las anotaciones de tipos permitirá que tu editor te brinde un mejor soporte y detecte errores.
 
index d6bc7ea61f50b4955a6152bce862cd1f75236b77..c1a23295e1d2523e6fe05093c40f41aeba684569 100644 (file)
@@ -46,7 +46,7 @@ También puedes especificar si tu backend permite:
 * Métodos HTTP específicos (`POST`, `PUT`) o todos ellos con el comodín `"*"`.
 * Headers HTTP específicos o todos ellos con el comodín `"*"`.
 
-{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
 
 Los parámetros predeterminados utilizados por la implementación de `CORSMiddleware` son restrictivos por defecto, por lo que necesitarás habilitar explícitamente orígenes, métodos o headers particulares para que los navegadores estén permitidos de usarlos en un contexto de Cross-Domain.
 
index 1e57df2092cd24cf788b89e0f7d094e619225a08..c31daf40f48047590b9d799168e35ac20380f991 100644 (file)
@@ -6,7 +6,7 @@ Puedes conectar el depurador en tu editor, por ejemplo con Visual Studio Code o
 
 En tu aplicación de FastAPI, importa y ejecuta `uvicorn` directamente:
 
-{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
 
 ### Acerca de `__name__ == "__main__"` { #about-name-main }
 
index 37cc2e213379d73dc7c0d2b83e1d0459d4bb17e1..a3a75efcd93675ac5e6440f17c6f9789f1d3b648 100644 (file)
@@ -101,7 +101,7 @@ Ahora puedes declarar tu dependencia usando esta clase.
 
 Nota cómo escribimos `CommonQueryParams` dos veces en el código anterior:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ sin `Annotated`
+//// tab | Python 3.9+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -137,7 +137,7 @@ Es a partir de este que **FastAPI** extraerá los parámetros declarados y es lo
 
 En este caso, el primer `CommonQueryParams`, en:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
 
 ////
 
-//// tab | Python 3.8+ sin `Annotated`
+//// tab | Python 3.9+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
 
 De hecho, podrías escribir simplemente:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ sin `Annotated`
+//// tab | Python 3.9+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -197,7 +197,7 @@ Pero declarar el tipo es recomendable, ya que de esa manera tu editor sabrá lo
 
 Pero ves que estamos teniendo algo de repetición de código aquí, escribiendo `CommonQueryParams` dos veces:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ sin `Annotated`
+//// tab | Python 3.9+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -225,7 +225,7 @@ Para esos casos específicos, puedes hacer lo siguiente:
 
 En lugar de escribir:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ sin `Annotated`
+//// tab | Python 3.9+ sin `Annotated`
 
 /// tip | Consejo
 
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 ...escribes:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
 
 ////
 
-//// tab | Python 3.8 sin `Annotated`
+//// tab | Python 3.9+ sin `Annotated`
 
 /// tip | Consejo
 
index e29c749a5f75490d90291b656a7f87f6f6ced0e4..aa645daa475813a510936c52a031f7ceefa6e1db 100644 (file)
@@ -29,15 +29,15 @@ Por ejemplo, podrías usar esto para crear una sesión de base de datos y cerrar
 
 Solo el código anterior e incluyendo la declaración `yield` se ejecuta antes de crear un response:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
 
 El valor generado es lo que se inyecta en *path operations* y otras dependencias:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
 
 El código posterior a la declaración `yield` se ejecuta después del response:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
 
 /// tip | Consejo
 
@@ -57,7 +57,7 @@ Por lo tanto, puedes buscar esa excepción específica dentro de la dependencia
 
 Del mismo modo, puedes usar `finally` para asegurarte de que los pasos de salida se ejecuten, sin importar si hubo una excepción o no.
 
-{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
 
 ## Sub-dependencias con `yield` { #sub-dependencies-with-yield }
 
@@ -270,7 +270,7 @@ En Python, puedes crear Context Managers <a href="https://docs.python.org/3/refe
 También puedes usarlos dentro de las dependencias de **FastAPI** con `yield` usando
 `with` o `async with` en la función de dependencia:
 
-{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
 
 /// tip | Consejo
 
index 25a14608e9056b8caafb42a7a0a6eae995206b17..ead949f1b6c6ca954ef15a5ecd16d489c6dd0681 100644 (file)
@@ -6,7 +6,7 @@ Similar a como puedes [agregar `dependencies` a los *path operation decorators*]
 
 En ese caso, se aplicarán a todas las *path operations* en la aplicación:
 
-{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
+{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
 
 Y todas las ideas en la sección sobre [agregar `dependencies` a los *path operation decorators*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} siguen aplicándose, pero en este caso, a todas las *path operations* en la app.
 
index ea91d14eae1cba19ca0c871b9320a0cf32ef8f4c..e74d65d7e95ac19dfcf01e203e054a46678e8211 100644 (file)
@@ -62,7 +62,7 @@ Y guardará el valor devuelto en un <abbr title="Una utilidad/sistema para almac
 
 En un escenario avanzado donde sabes que necesitas que la dependencia se llame en cada paso (posiblemente varias veces) en el mismo request en lugar de usar el valor "cache", puedes establecer el parámetro `use_cache=False` al usar `Depends`:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
 
 ////
 
-//// tab | Python 3.8+ sin Anotaciones
+//// tab | Python 3.9+ sin Anotaciones
 
 /// tip | Consejo
 
index 7df0450ac7ea93f42ac532c40e2c7b56c18cf4c0..789b2a0110641431d6c0c9d1e340fc232ca99bb2 100644 (file)
@@ -2,7 +2,7 @@
 
 El archivo FastAPI más simple podría verse así:
 
-{* ../../docs_src/first_steps/tutorial001.py *}
+{* ../../docs_src/first_steps/tutorial001_py39.py *}
 
 Copia eso en un archivo `main.py`.
 
@@ -183,7 +183,7 @@ Deploying to FastAPI Cloud...
 
 ### Paso 1: importa `FastAPI` { #step-1-import-fastapi }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
 
 `FastAPI` es una clase de Python que proporciona toda la funcionalidad para tu API.
 
@@ -197,7 +197,7 @@ Puedes usar toda la funcionalidad de <a href="https://www.starlette.dev/" class=
 
 ### Paso 2: crea una "instance" de `FastAPI` { #step-2-create-a-fastapi-instance }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
 
 Aquí la variable `app` será una "instance" de la clase `FastAPI`.
 
@@ -266,7 +266,7 @@ Vamos a llamarlas "**operaciones**" también.
 
 #### Define un *path operation decorator* { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
 
 El `@app.get("/")` le dice a **FastAPI** que la función justo debajo se encarga de manejar requests que vayan a:
 
@@ -320,7 +320,7 @@ Esta es nuestra "**path operation function**":
 * **operation**: es `get`.
 * **function**: es la función debajo del "decorador" (debajo de `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
 
 Esta es una función de Python.
 
@@ -332,7 +332,7 @@ En este caso, es una función `async`.
 
 También podrías definirla como una función normal en lugar de `async def`:
 
-{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
 
 /// note | Nota
 
@@ -342,7 +342,7 @@ Si no sabes la diferencia, Revisa la sección [Async: *"¿Tienes prisa?"*](../as
 
 ### Paso 5: retorna el contenido { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
 
 Puedes retornar un `dict`, `list`, valores singulares como `str`, `int`, etc.
 
index f64ede86c42c67211fcfba2a5440190494820884..71e0563203f86fa618d558b2583c74e7c6fe71f4 100644 (file)
@@ -25,7 +25,7 @@ Para devolver responses HTTP con errores al cliente, usa `HTTPException`.
 
 ### Importa `HTTPException` { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
 
 ### Lanza un `HTTPException` en tu código { #raise-an-httpexception-in-your-code }
 
@@ -39,7 +39,7 @@ El beneficio de lanzar una excepción en lugar de `return`ar un valor será más
 
 En este ejemplo, cuando el cliente solicita un ítem por un ID que no existe, lanza una excepción con un código de estado de `404`:
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
 
 ### El response resultante { #the-resulting-response }
 
@@ -77,7 +77,7 @@ Probablemente no necesitarás usarlos directamente en tu código.
 
 Pero en caso de que los necesites para un escenario avanzado, puedes agregar headers personalizados:
 
-{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
 
 ## Instalar manejadores de excepciones personalizados { #install-custom-exception-handlers }
 
@@ -89,7 +89,7 @@ Y quieres manejar esta excepción globalmente con FastAPI.
 
 Podrías agregar un manejador de excepciones personalizado con `@app.exception_handler()`:
 
-{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
 
 Aquí, si solicitas `/unicorns/yolo`, la *path operation* lanzará un `UnicornException`.
 
@@ -127,7 +127,7 @@ Para sobrescribirlo, importa el `RequestValidationError` y úsalo con `@app.exce
 
 El manejador de excepciones recibirá un `Request` y la excepción.
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
 
 Ahora, si vas a `/items/foo`, en lugar de obtener el error JSON por defecto con:
 
@@ -159,7 +159,7 @@ De la misma manera, puedes sobrescribir el manejador de `HTTPException`.
 
 Por ejemplo, podrías querer devolver un response de texto plano en lugar de JSON para estos errores:
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
 
 /// note | Nota Técnica
 
@@ -183,7 +183,7 @@ El `RequestValidationError` contiene el `body` que recibió con datos inválidos
 
 Podrías usarlo mientras desarrollas tu aplicación para registrar el body y depurarlo, devolverlo al usuario, etc.
 
-{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
 
 Ahora intenta enviar un ítem inválido como:
 
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
 
 Si quieres usar la excepción junto con los mismos manejadores de excepciones predeterminados de **FastAPI**, puedes importar y reutilizar los manejadores de excepciones predeterminados de `fastapi.exception_handlers`:
 
-{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
 
 En este ejemplo solo estás `print`eando el error con un mensaje muy expresivo, pero te haces una idea. Puedes usar la excepción y luego simplemente reutilizar los manejadores de excepciones predeterminados.
index 3b65666c48d467decb8192c9835ecd83eb01c803..a5d9b5eadca039cb34f0908c21c04edd133d0643 100644 (file)
@@ -18,7 +18,7 @@ Puedes establecer los siguientes campos que se usan en la especificación OpenAP
 
 Puedes configurarlos de la siguiente manera:
 
-{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *}
+{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
 
 /// tip | Consejo
 
@@ -36,7 +36,7 @@ Desde OpenAPI 3.1.0 y FastAPI 0.99.0, también puedes establecer la `license_inf
 
 Por ejemplo:
 
-{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
 
 ## Metadata para etiquetas { #metadata-for-tags }
 
@@ -58,7 +58,7 @@ Probemos eso en un ejemplo con etiquetas para `users` y `items`.
 
 Crea metadata para tus etiquetas y pásala al parámetro `openapi_tags`:
 
-{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
 
 Nota que puedes utilizar Markdown dentro de las descripciones, por ejemplo "login" se mostrará en negrita (**login**) y "fancy" se mostrará en cursiva (_fancy_).
 
@@ -72,7 +72,7 @@ No tienes que agregar metadata para todas las etiquetas que uses.
 
 Usa el parámetro `tags` con tus *path operations* (y `APIRouter`s) para asignarlas a diferentes etiquetas:
 
-{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
 
 /// info | Información
 
@@ -100,7 +100,7 @@ Pero puedes configurarlo con el parámetro `openapi_url`.
 
 Por ejemplo, para configurarlo para que se sirva en `/api/v1/openapi.json`:
 
-{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
 
 Si quieres deshabilitar el esquema OpenAPI completamente, puedes establecer `openapi_url=None`, eso también deshabilitará las interfaces de usuario de documentación que lo usan.
 
@@ -117,4 +117,4 @@ Puedes configurar las dos interfaces de usuario de documentación incluidas:
 
 Por ejemplo, para configurar Swagger UI para que se sirva en `/documentation` y deshabilitar ReDoc:
 
-{* ../../docs_src/metadata/tutorial003.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
index 0f943ec08c1339c675982c641a00026fdfe7a341..de636a48541eed1b8ca6238111856a543f1e6dbe 100644 (file)
@@ -31,7 +31,7 @@ La función middleware recibe:
     * Luego devuelve la `response` generada por la correspondiente *path operation*.
 * Puedes entonces modificar aún más la `response` antes de devolverla.
 
-{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
 
 /// tip | Consejo
 
@@ -57,7 +57,7 @@ Y también después de que se genere la `response`, antes de devolverla.
 
 Por ejemplo, podrías añadir un custom header `X-Process-Time` que contenga el tiempo en segundos que tomó procesar la request y generar una response:
 
-{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
 
 /// tip | Consejo
 
index 858d295be3073eb6183b5151e414ff30aa1c9e77..945574b9e880f528190d3258ac4df8bf26dfb8bf 100644 (file)
@@ -46,7 +46,7 @@ En estos casos, podría tener sentido almacenar las tags en un `Enum`.
 
 **FastAPI** soporta eso de la misma manera que con strings normales:
 
-{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
 
 ## Resumen y Descripción { #summary-and-description }
 
@@ -92,7 +92,7 @@ Entonces, si no proporcionas una, **FastAPI** generará automáticamente una de
 
 Si necesitas marcar una *path operation* como <abbr title="obsoleta, se recomienda no usarla">deprecated</abbr>, pero sin eliminarla, pasa el parámetro `deprecated`:
 
-{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
 
 Se marcará claramente como deprecado en la documentación interactiva:
 
index a6f0a4cd3d0c2f0ecf53978634df82f3086fa18a..569dd03dd08a87e46e6678b83d07d41c926d66eb 100644 (file)
@@ -54,7 +54,7 @@ No importa para **FastAPI**. Detectará los parámetros por sus nombres, tipos y
 
 Así que puedes declarar tu función como:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
 
 Pero ten en cuenta que si usas `Annotated`, no tendrás este problema, no importará ya que no estás usando los valores por defecto de los parámetros de la función para `Query()` o `Path()`.
 
@@ -83,7 +83,7 @@ Pasa `*`, como el primer parámetro de la función.
 
 Python no hará nada con ese `*`, pero sabrá que todos los parámetros siguientes deben ser llamados como argumentos de palabras clave (parejas key-value), también conocidos como <abbr title="De: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Incluso si no tienen un valor por defecto.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
 
 ### Mejor con `Annotated` { #better-with-annotated }
 
index c49b31c44eb5cc8afd7f6964bbfca0cb8da85627..7ba49f3b0b2ef0d1e814ea9275be1941be424a74 100644 (file)
@@ -2,7 +2,7 @@
 
 Puedes declarar "parámetros" o "variables" de path con la misma sintaxis que se usa en los format strings de Python:
 
-{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
 
 El valor del parámetro de path `item_id` se pasará a tu función como el argumento `item_id`.
 
@@ -16,7 +16,7 @@ Así que, si ejecutas este ejemplo y vas a <a href="http://127.0.0.1:8000/items/
 
 Puedes declarar el tipo de un parámetro de path en la función, usando anotaciones de tipos estándar de Python:
 
-{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
 
 En este caso, `item_id` se declara como un `int`.
 
@@ -118,13 +118,13 @@ Y luego también puedes tener un path `/users/{user_id}` para obtener datos sobr
 
 Debido a que las *path operations* se evalúan en orden, necesitas asegurarte de que el path para `/users/me` se declara antes que el de `/users/{user_id}`:
 
-{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
 
 De lo contrario, el path para `/users/{user_id}` también coincidiría para `/users/me`, "pensando" que está recibiendo un parámetro `user_id` con un valor de `"me"`.
 
 De manera similar, no puedes redefinir una path operation:
 
-{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
 
 La primera siempre será utilizada ya que el path coincide primero.
 
@@ -140,13 +140,7 @@ Al heredar de `str`, la documentación de la API podrá saber que los valores de
 
 Luego crea atributos de clase con valores fijos, que serán los valores válidos disponibles:
 
-{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
-
-/// info | Información
-
-<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Las enumeraciones (o enums) están disponibles en Python</a> desde la versión 3.4.
-
-///
+{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
 
 /// tip | Consejo
 
@@ -158,7 +152,7 @@ Si te estás preguntando, "AlexNet", "ResNet" y "LeNet" son solo nombres de <abb
 
 Luego crea un *path parameter* con una anotación de tipo usando la clase enum que creaste (`ModelName`):
 
-{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
 
 ### Revisa la documentación { #check-the-docs }
 
@@ -174,13 +168,13 @@ El valor del *path parameter* será un *miembro* de enumeración.
 
 Puedes compararlo con el *miembro* de enumeración en tu enum creada `ModelName`:
 
-{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
 
 #### Obtener el valor de *enumeración* { #get-the-enumeration-value }
 
 Puedes obtener el valor actual (un `str` en este caso) usando `model_name.value`, o en general, `your_enum_member.value`:
 
-{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
 
 /// tip | Consejo
 
@@ -194,7 +188,7 @@ Puedes devolver *miembros de enum* desde tu *path operation*, incluso anidados e
 
 Serán convertidos a sus valores correspondientes (cadenas en este caso) antes de devolverlos al cliente:
 
-{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
 
 En tu cliente recibirás un response JSON como:
 
@@ -233,7 +227,7 @@ En este caso, el nombre del parámetro es `file_path`, y la última parte, `:pat
 
 Así que, puedes usarlo con:
 
-{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
 
 /// tip | Consejo
 
index 22e70cf199f3870a77d54a519b0ded150d4e7f21..e3f8cb5944f96cc66bf1c372658629703cebaefe 100644 (file)
@@ -55,7 +55,7 @@ q: str | None = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Union[str, None] = None
@@ -73,7 +73,7 @@ q: Annotated[str | None] = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Annotated[Union[str, None]] = None
index 520134b1c37d2ac40ec4280d0f870ff03dac2232..2b58a2b4b6704942305385232610b958ed1a8179 100644 (file)
@@ -2,7 +2,7 @@
 
 Cuando declaras otros parámetros de función que no son parte de los parámetros de path, son automáticamente interpretados como parámetros de "query".
 
-{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
 
 La query es el conjunto de pares clave-valor que van después del `?` en una URL, separados por caracteres `&`.
 
@@ -127,7 +127,7 @@ Si no quieres agregar un valor específico pero solo hacer que sea opcional, est
 
 Pero cuando quieres hacer un parámetro de query requerido, simplemente no declares ningún valor por defecto:
 
-{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
 
 Aquí el parámetro de query `needy` es un parámetro de query requerido de tipo `str`.
 
index eeafe249e1b197db677bfa39015b426cc157195f..8f0ad5652757f1f6ec3fe64781dd158795b86ac1 100644 (file)
@@ -183,7 +183,7 @@ Podría haber casos en los que devuelvas algo que no es un campo válido de Pyda
 
 El caso más común sería [devolver un Response directamente como se explica más adelante en la documentación avanzada](../advanced/response-directly.md){.internal-link target=_blank}.
 
-{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
 
 Este caso simple es manejado automáticamente por FastAPI porque la anotación del tipo de retorno es la clase (o una subclase de) `Response`.
 
@@ -193,7 +193,7 @@ Y las herramientas también estarán felices porque tanto `RedirectResponse` com
 
 También puedes usar una subclase de `Response` en la anotación del tipo:
 
-{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
 
 Esto también funcionará porque `RedirectResponse` es una subclase de `Response`, y FastAPI manejará automáticamente este caso simple.
 
index 54fea9911ded77bef63234380454bdf7770fca2b..dce69f9bcee6ed0abcf10b0edd3aaa20d7d7404c 100644 (file)
@@ -8,7 +8,7 @@ De la misma manera que puedes especificar un modelo de response, también puedes
 * `@app.delete()`
 * etc.
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 /// note | Nota
 
@@ -74,7 +74,7 @@ Para saber más sobre cada código de estado y qué código es para qué, revisa
 
 Veamos de nuevo el ejemplo anterior:
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 `201` es el código de estado para "Created".
 
@@ -82,7 +82,7 @@ Pero no tienes que memorizar lo que significa cada uno de estos códigos.
 
 Puedes usar las variables de conveniencia de `fastapi.status`.
 
-{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
 
 Son solo una conveniencia, mantienen el mismo número, pero de esa manera puedes usar el autocompletado del editor para encontrarlos:
 
index 964009ae671cc47ac2f2eea8c2c8d486b7fdc686..f1badd2af69c998ad4350e0bf14450937c260fc5 100644 (file)
@@ -7,7 +7,7 @@ Puedes servir archivos estáticos automáticamente desde un directorio utilizand
 * Importa `StaticFiles`.
 * "Monta" una instance de `StaticFiles()` en un path específico.
 
-{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
 
 /// note | Detalles Técnicos
 
index 3cb7d56678c8293fe1390546c4f0a29e8d94531b..555da55bf6a0450ef271d8d4f98eddd45044daea 100644 (file)
@@ -30,7 +30,7 @@ Usa el objeto `TestClient` de la misma manera que con `httpx`.
 
 Escribe declaraciones `assert` simples con las expresiones estándar de Python que necesites revisar (otra vez, estándar de `pytest`).
 
-{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
 
 /// tip | Consejo
 
@@ -75,7 +75,7 @@ Digamos que tienes una estructura de archivos como se describe en [Aplicaciones
 
 En el archivo `main.py` tienes tu aplicación de **FastAPI**:
 
-{* ../../docs_src/app_testing/main.py *}
+{* ../../docs_src/app_testing/app_a_py39/main.py *}
 
 ### Archivo de prueba { #testing-file }
 
@@ -91,7 +91,7 @@ Entonces podrías tener un archivo `test_main.py` con tus pruebas. Podría estar
 
 Debido a que este archivo está en el mismo paquete, puedes usar importaciones relativas para importar el objeto `app` desde el módulo `main` (`main.py`):
 
-{* ../../docs_src/app_testing/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
 
 ...y tener el código para las pruebas tal como antes.
 
index a1c1cfab0fd5319c072949e102c1b3607c4ef501..688bc16967a65d7e65b1e9495d33b83c0c36cf4a 100644 (file)
@@ -26,7 +26,7 @@ O **FastAPI** pegará este modelo, gerará o esquema JSON dele e incluirá no lo
 
 Por exemplo, para declarar um outro retorno com o status code `404` e um modelo do Pydantic chamado `Message`, você pode escrever:
 
-{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
 
 /// note | Nota
 
@@ -203,7 +203,7 @@ Por exemplo, você pode declarar um retorno com o código de status `404` que ut
 
 E um retorno com o código de status `200` que utiliza o seu `response_model`, porém inclui um `example` customizado:
 
-{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
 
 Isso será combinado e incluído em seu OpenAPI, e disponibilizado na documentação da sua API:
 
index c5b2c3fbbc47d9549f0b217d38eec4db91af920e..953ebedd9c36a391a6e893a601e4bdd4c27846af 100644 (file)
@@ -32,11 +32,11 @@ Para um exemplos simples, vamos considerar uma estrutura de arquivos semelhante
 
 O arquivo `main.py` teria:
 
-{* ../../docs_src/async_tests/main.py *}
+{* ../../docs_src/async_tests/app_a_py39/main.py *}
 
 O arquivo `test_main.py` teria os testes para para o arquivo `main.py`, ele poderia ficar assim:
 
-{* ../../docs_src/async_tests/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
 
 ## Executá-lo { #run-it }
 
@@ -56,7 +56,7 @@ $ pytest
 
 O marcador `@pytest.mark.anyio` informa ao pytest que esta função de teste deve ser invocada de maneira assíncrona:
 
-{* ../../docs_src/async_tests/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
 
 /// tip | Dica
 
@@ -66,7 +66,7 @@ Note que a função de teste é `async def` agora, no lugar de apenas `def` como
 
 Então podemos criar um `AsyncClient` com a aplicação, e enviar requisições assíncronas para ela utilizando `await`.
 
-{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
 
 Isso é equivalente a:
 
index 97ac5c16f5f97a9efc4c2147c6f66b13d06c1f02..bf0d1242896049eeea8864d8519fbc79bb98daec 100644 (file)
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
 
 Por exemplo, suponha que você defina uma *operação de rota* `/items/`:
 
-{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
 
 Se o cliente tentar ir para `/items`, por padrão, ele seria redirecionado para `/items/`.
 
@@ -115,7 +115,7 @@ Nesse caso, o path original `/app` seria servido em `/api/v1/app`.
 
 Embora todo o seu código esteja escrito assumindo que existe apenas `/app`.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
 
 E o proxy estaria **"removendo"** o **prefixo de path** dinamicamente antes de transmitir a solicitação para o servidor da aplicação (provavelmente Uvicorn via CLI do FastAPI), mantendo sua aplicação convencida de que está sendo servida em `/app`, para que você não precise atualizar todo o seu código para incluir o prefixo `/api/v1`.
 
@@ -193,7 +193,7 @@ Você pode obter o `root_path` atual usado pela sua aplicação para cada solici
 
 Aqui estamos incluindo-o na mensagem apenas para fins de demonstração.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
 
 Então, se você iniciar o Uvicorn com:
 
@@ -220,7 +220,7 @@ A resposta seria algo como:
 
 Alternativamente, se você não tiver uma maneira de fornecer uma opção de linha de comando como `--root-path` ou equivalente, você pode definir o parâmetro `root_path` ao criar sua aplicação FastAPI:
 
-{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
 
 Passar o `root_path` para `FastAPI` seria o equivalente a passar a opção de linha de comando `--root-path` para Uvicorn ou Hypercorn.
 
@@ -400,7 +400,7 @@ Se você passar uma lista personalizada de `servers` e houver um `root_path` (po
 
 Por exemplo:
 
-{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
 
 Gerará um OpenAPI schema como:
 
@@ -455,7 +455,7 @@ Se você não especificar o parâmetro `servers` e `root_path` for igual a `/`,
 
 Se você não quiser que o **FastAPI** inclua um servidor automático usando o `root_path`, você pode usar o parâmetro `root_path_in_servers=False`:
 
-{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
 
 e então ele não será incluído no OpenAPI schema.
 
index 036cbb6351301d4323b6a9918cb29afb87e4f34a..5f26390c2816940fcc2721e88c9ba316a52677e5 100644 (file)
@@ -30,7 +30,7 @@ Isso ocorre por que, por padrão, o FastAPI irá verificar cada item dentro do d
 
 Mas se você tem certeza que o conteúdo que você está retornando é **serializável com JSON**, você pode passá-lo diretamente para a classe de resposta e evitar o trabalho extra que o FastAPI teria ao passar o conteúdo pelo `jsonable_encoder` antes de passar para a classe de resposta.
 
-{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
 
 /// info | Informação
 
@@ -55,7 +55,7 @@ Para retornar uma resposta com HTML diretamente do **FastAPI**, utilize `HTMLRes
 * Importe `HTMLResponse`
 * Passe `HTMLResponse` como o parâmetro de `response_class` do seu *decorador de operação de rota*.
 
-{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
 
 /// info | Informação
 
@@ -73,7 +73,7 @@ Como visto em [Retornando uma Resposta Diretamente](response-directly.md){.inter
 
 O mesmo exemplo de antes, retornando uma `HTMLResponse`, poderia parecer com:
 
-{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
 
 /// warning | Atenção
 
@@ -97,7 +97,7 @@ A `response_class` será usada apenas para documentar o OpenAPI da *operação d
 
 Por exemplo, poderia ser algo como:
 
-{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
 
 Neste exemplo, a função `generate_html_response()` já cria e retorna uma `Response` em vez de retornar o HTML em uma `str`.
 
@@ -136,7 +136,7 @@ Ela aceita os seguintes parâmetros:
 
 O FastAPI (Starlette, na verdade) irá incluir o cabeçalho Content-Length automaticamente. Ele também irá incluir o cabeçalho Content-Type, baseado no `media_type` e acrescentando uma codificação para tipos textuais.
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ### `HTMLResponse` { #htmlresponse }
 
@@ -146,7 +146,7 @@ Usa algum texto ou sequência de bytes e retorna uma resposta HTML. Como você l
 
 Usa algum texto ou sequência de bytes para retornar uma resposta de texto não formatado.
 
-{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
 
 ### `JSONResponse` { #jsonresponse }
 
@@ -180,7 +180,7 @@ Essa resposta requer a instalação do pacote `ujson`, com o comando `pip instal
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
 
 /// tip | Dica
 
@@ -194,13 +194,13 @@ Retorna um redirecionamento HTTP. Utiliza o código de status 307 (Redirecioname
 
 Você pode retornar uma `RedirectResponse` diretamente:
 
-{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
 
 ---
 
 Ou você pode utilizá-la no parâmetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
 
 Se você fizer isso, então você pode retornar a URL diretamente da sua *função de operação de rota*
 
@@ -210,13 +210,13 @@ Neste caso, o `status_code` utilizada será o padrão de `RedirectResponse`, que
 
 Você também pode utilizar o parâmetro `status_code` combinado com o parâmetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
 
 ### `StreamingResponse` { #streamingresponse }
 
 Recebe um gerador assíncrono ou um gerador/iterador comum e retorna o corpo da resposta de forma contínua (stream).
 
-{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
 
 #### Utilizando `StreamingResponse` com objetos semelhantes a arquivos { #using-streamingresponse-with-file-like-objects }
 
@@ -226,7 +226,7 @@ Dessa forma, você não precisa ler todo o arquivo na memória primeiro, e você
 
 Isso inclui muitas bibliotecas que interagem com armazenamento em nuvem, processamento de vídeos, entre outras.
 
-{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
 
 1. Essa é a função geradora. É definida como "função geradora" porque contém declarações `yield` nela.
 2. Ao utilizar o bloco `with`, nós garantimos que o objeto semelhante a um arquivo é fechado após a função geradora ser finalizada. Isto é, após a resposta terminar de ser enviada.
@@ -255,11 +255,11 @@ Recebe um conjunto de argumentos do construtor diferente dos outros tipos de res
 
 Respostas de Arquivos incluem o tamanho do arquivo, data da última modificação e ETags apropriados, nos cabeçalhos `Content-Length`, `Last-Modified` e `ETag`, respectivamente.
 
-{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
 
 Você também pode usar o parâmetro `response_class`:
 
-{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
 
 Nesse caso, você pode retornar o caminho do arquivo diretamente da sua *função de operação de rota*.
 
@@ -273,7 +273,7 @@ Vamos supor também que você queira retornar um JSON indentado e formatado, ent
 
 Você poderia criar uma classe `CustomORJSONResponse`. A principal coisa a ser feita é sobrecarregar o método render da classe Response, `Response.render(content)`, que retorna o conteúdo em bytes:
 
-{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
 
 Agora em vez de retornar:
 
@@ -299,7 +299,7 @@ O padrão que define isso é o `default_response_class`.
 
 No exemplo abaixo, o **FastAPI** irá utilizar `ORJSONResponse` por padrão, em todas as *operações de rota*, em vez de `JSONResponse`.
 
-{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
 
 /// tip | Dica
 
index e29ece8e3c83e5733906457bce3981e9e6f2da1d..8cdc3582890e291d1418bfb7e224cdd3101f1cf5 100644 (file)
@@ -30,7 +30,7 @@ Vamos começar com um exemplo e depois ver em detalhes.
 
 Nós criamos uma função assíncrona `lifespan()` com `yield` assim:
 
-{* ../../docs_src/events/tutorial003.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
 
 Aqui estamos simulando a operação de *inicialização* custosa de carregar o modelo, colocando a (falsa) função do modelo no dicionário com modelos de machine learning antes do `yield`. Esse código será executado **antes** de a aplicação **começar a receber requisições**, durante a *inicialização*.
 
@@ -48,7 +48,7 @@ Talvez você precise iniciar uma nova versão, ou apenas cansou de executá-la.
 
 A primeira coisa a notar é que estamos definindo uma função assíncrona com `yield`. Isso é muito semelhante a Dependências com `yield`.
 
-{* ../../docs_src/events/tutorial003.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
 
 A primeira parte da função, antes do `yield`, será executada **antes** de a aplicação iniciar.
 
@@ -60,7 +60,7 @@ Se você verificar, a função está decorada com um `@asynccontextmanager`.
 
 Isso converte a função em algo chamado "**gerenciador de contexto assíncrono**".
 
-{* ../../docs_src/events/tutorial003.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
 
 Um **gerenciador de contexto** em Python é algo que você pode usar em uma declaração `with`, por exemplo, `open()` pode ser usado como um gerenciador de contexto:
 
@@ -82,7 +82,7 @@ No nosso exemplo de código acima, não o usamos diretamente, mas passamos para
 
 O parâmetro `lifespan` da aplicação `FastAPI` aceita um **gerenciador de contexto assíncrono**, então podemos passar para ele nosso novo gerenciador de contexto assíncrono `lifespan`.
 
-{* ../../docs_src/events/tutorial003.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
 
 ## Eventos alternativos (descontinuados) { #alternative-events-deprecated }
 
@@ -104,7 +104,7 @@ Essas funções podem ser declaradas com `async def` ou `def` normal.
 
 Para adicionar uma função que deve rodar antes de a aplicação iniciar, declare-a com o evento `"startup"`:
 
-{* ../../docs_src/events/tutorial001.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
 
 Nesse caso, a função de manipulador do evento `startup` inicializará os itens do "banco de dados" (apenas um `dict`) com alguns valores.
 
@@ -116,7 +116,7 @@ E sua aplicação não começará a receber requisições até que todos os mani
 
 Para adicionar uma função que deve ser executada quando a aplicação estiver encerrando, declare-a com o evento `"shutdown"`:
 
-{* ../../docs_src/events/tutorial002.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
 
 Aqui, a função de manipulador do evento `shutdown` escreverá uma linha de texto `"Application shutdown"` no arquivo `log.txt`.
 
index 253a7e6cdd02c29f016c1e9a67d6a8627bd714d1..5134bc7cb56554f9abe19984b66e93df7b86f2e0 100644 (file)
@@ -167,7 +167,7 @@ Mas para o cliente gerado, poderíamos **modificar** os IDs de operação do Ope
 
 Poderíamos baixar o JSON do OpenAPI para um arquivo `openapi.json` e então poderíamos **remover essa tag prefixada** com um script como este:
 
-{* ../../docs_src/generate_clients/tutorial004.py *}
+{* ../../docs_src/generate_clients/tutorial004_py39.py *}
 
 //// tab | Node.js
 
index 9186bcb494f8e61a27303e0891a9dcae86d893cf..30c1834790507552615c0a471c774cb037597e92 100644 (file)
@@ -57,13 +57,13 @@ Garante que todas as requisições devem ser `https` ou `wss`.
 
 Qualquer requisição para `http` ou `ws` será redirecionada para o esquema seguro.
 
-{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
 
 ## `TrustedHostMiddleware` { #trustedhostmiddleware }
 
 Garante que todas as requisições recebidas tenham um cabeçalho `Host` corretamente configurado, a fim de proteger contra ataques de cabeçalho de host HTTP.
 
-{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
 
 Os seguintes argumentos são suportados:
 
@@ -78,7 +78,7 @@ Gerencia respostas GZip para qualquer requisição que inclua `"gzip"` no cabeç
 
 O middleware lidará com respostas padrão e de streaming.
 
-{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
 
 Os seguintes argumentos são suportados:
 
index fa3840fb35aef8bcc68e888cc965897bc340acfe..011898e8cd48f8a48897eb0338485b288b5000ef 100644 (file)
@@ -32,7 +32,7 @@ Webhooks estão disponíveis a partir do OpenAPI 3.1.0, e possui suporte do Fast
 
 Quando você cria uma aplicação com o **FastAPI**, existe um atributo chamado `webhooks`, que você utilizar para defini-los da mesma maneira que você definiria as suas **operações de rotas**, utilizando por exemplo `@app.webhooks.post()`.
 
-{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
 
 Os webhooks que você define aparecerão no esquema do **OpenAPI** e na **página de documentação** gerada automaticamente.
 
index 12505a9a87e4f027fb6e961a3e8726379d080f58..e1c3e5ab89e57a6027a3583dfc0e60149342f13f 100644 (file)
@@ -12,7 +12,7 @@ Você pode definir o `operationId` do OpenAPI que será utilizado na sua *opera
 
 Você precisa ter certeza que ele é único para cada operação.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
 
 ### Utilizando o nome da *função de operação de rota* como o operationId { #using-the-path-operation-function-name-as-the-operationid }
 
@@ -20,7 +20,7 @@ Se você quiser utilizar o nome das funções da sua API como `operationId`s, vo
 
 Você deve fazer isso depois de adicionar todas as suas *operações de rota*.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
 
 /// tip | Dica
 
@@ -40,7 +40,7 @@ Mesmo que elas estejam em módulos (arquivos Python) diferentes.
 
 Para excluir uma *operação de rota* do esquema OpenAPI gerado (e por consequência, dos sistemas de documentação automáticos), utilize o parâmetro `include_in_schema` e defina ele como `False`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
 
 ## Descrição avançada a partir de docstring { #advanced-description-from-docstring }
 
@@ -92,7 +92,7 @@ Você pode estender o esquema do OpenAPI para uma *operação de rota* utilizand
 
 Esse parâmetro `openapi_extra` pode ser útil, por exemplo, para declarar [Extensões do OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
 
 Se você abrir os documentos criados automaticamente para a API, sua extensão aparecerá no final da *operação de rota* específica.
 
@@ -139,7 +139,7 @@ Por exemplo, você poderia optar por ler e validar a requisição com seu própr
 
 Você pode fazer isso com `openapi_extra`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
 
 Nesse exemplo, nós não declaramos nenhum modelo do Pydantic. Na verdade, o corpo da requisição não está nem mesmo <abbr title="convertido de um formato plano, como bytes, para objetos Python">analisado</abbr> como JSON, ele é lido diretamente como `bytes` e a função `magic_data_reader()` seria a responsável por analisar ele de alguma forma.
 
index 0f08873f677e0031926aa7e488427596edb87efa..ee81f0bfc86b116dc4ffac7860e200ee4dc3a6c5 100644 (file)
@@ -20,7 +20,7 @@ Você pode declarar um parâmetro do tipo `Response` em sua *função de operaç
 
 E então você pode definir o `status_code` neste objeto de retorno temporal.
 
-{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
 
 E então você pode retornar qualquer objeto que você precise, como você faria normalmente (um `dict`, um modelo de banco de dados, etc.).
 
index 41fc000133bdf4bcd4915ed873eefe7b8e630ab0..67820b433ba8400676312e3ebbee667ae36c68e5 100644 (file)
@@ -6,7 +6,7 @@ Você pode declarar um parâmetro do tipo `Response` na sua *função de operaç
 
 E então você pode definir cookies nesse objeto de resposta *temporário*.
 
-{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
 
 Em seguida, você pode retornar qualquer objeto que precise, como normalmente faria (um `dict`, um modelo de banco de dados, etc).
 
@@ -24,7 +24,7 @@ Para fazer isso, você pode criar uma resposta como descrito em [Retorne uma Res
 
 Então, defina os cookies nela e a retorne:
 
-{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
 
 /// tip | Dica
 
index 0c0144e9a19845a9e1d094c4adbeb6562311caa9..bbbef2f9131dc3b7e74e138592064bc24e1c0df1 100644 (file)
@@ -54,7 +54,7 @@ Vamos dizer que você quer retornar uma resposta <a href="https://en.wikipedia.o
 
 Você pode colocar o seu conteúdo XML em uma string, colocar em uma `Response`, e retorná-lo:
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ## Notas { #notes }
 
index 1add453f458d9c46932bc499c05cf859c47a8800..14c3fb1869a12c60e89361d719e3bd73176b3b8e 100644 (file)
@@ -6,7 +6,7 @@ Você pode declarar um parâmetro do tipo `Response` na sua *função de operaç
 
 Então você pode definir os cabeçalhos nesse objeto de resposta *temporário*.
 
-{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
 
 Em seguida você pode retornar qualquer objeto que precisar, da maneira que faria normalmente (um `dict`, um modelo de banco de dados, etc.).
 
@@ -22,7 +22,7 @@ Você também pode adicionar cabeçalhos quando retornar uma `Response` diretame
 
 Crie uma resposta conforme descrito em [Retornar uma resposta diretamente](response-directly.md){.internal-link target=_blank} e passe os cabeçalhos como um parâmetro adicional:
 
-{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
 
 /// note | Detalhes Técnicos
 
index cbde3a27c0cb0c67b3f75c01b334ee47081a49a2..6f5b7feae74c1e84d60a2d524a8ecd44e7d0896f 100644 (file)
@@ -62,7 +62,7 @@ Você pode usar as mesmas funcionalidades e ferramentas de validação que usa e
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -74,7 +74,7 @@ No Pydantic v1 você importaria `BaseSettings` diretamente de `pydantic` em vez
 
 ///
 
-{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -92,7 +92,7 @@ Em seguida, ele converterá e validará os dados. Assim, quando você usar esse
 
 Depois você pode usar o novo objeto `settings` na sua aplicação:
 
-{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
 
 ### Executar o servidor { #run-the-server }
 
@@ -126,11 +126,11 @@ Você pode colocar essas configurações em outro arquivo de módulo como visto
 
 Por exemplo, você poderia ter um arquivo `config.py` com:
 
-{* ../../docs_src/settings/app01/config.py *}
+{* ../../docs_src/settings/app01_py39/config.py *}
 
 E então usá-lo em um arquivo `main.py`:
 
-{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
 
 /// tip | Dica
 
index 2298029057662d09b455c639af8bca7f43803d11..c61d1e92a083fe7609171f4d0eac6b0fd3bd1009 100644 (file)
@@ -10,7 +10,7 @@ Se você precisar ter duas aplicações FastAPI independentes, cada uma com seu
 
 Primeiro, crie a aplicação principal, de nível superior, **FastAPI**, e suas *operações de rota*:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
 
 ### Sub-aplicação { #sub-application }
 
@@ -18,7 +18,7 @@ Em seguida, crie sua sub-aplicação e suas *operações de rota*.
 
 Essa sub-aplicação é apenas outra aplicação FastAPI padrão, mas esta é a que será "montada":
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
 
 ### Monte a sub-aplicação { #mount-the-sub-application }
 
@@ -26,7 +26,7 @@ Na sua aplicação de nível superior, `app`, monte a sub-aplicação, `subapi`.
 
 Neste caso, ela será montada no path `/subapi`:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
 
 ### Verifique a documentação automática da API { #check-the-automatic-api-docs }
 
index 00493d635474207ed06f4a5abdb7735b96960f74..eb64e72bb850be56644c0fd34b6ee4c420642564 100644 (file)
@@ -27,7 +27,7 @@ $ pip install jinja2
 * Declare um parâmetro `Request` no *path operation* que retornará um template.
 * Use o `templates` que você criou para renderizar e retornar uma `TemplateResponse`, passe o nome do template, o objeto `request` e um dicionário "context" com pares chave-valor a serem usados dentro do template do Jinja2.
 
-{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
 
 /// note | Nota
 
index fb62ad2e23170c573645bd672f539251cd94199b..971b4376301ac8866caa6d70a0d0a16ea50df9e6 100644 (file)
@@ -2,10 +2,10 @@
 
 Quando você precisa que o `lifespan` seja executado em seus testes, você pode utilizar o `TestClient` com a instrução `with`:
 
-{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
 
 Você pode ler mais detalhes sobre o ["Executando lifespan em testes no site oficial da documentação do Starlette."](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
 
 Para os eventos `startup` e `shutdown` descontinuados, você pode usar o `TestClient` da seguinte forma:
 
-{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
index ccd7582c73521b5b9b4117f8a7b5eab087474d23..d9d1723a644258712742875012961046a6bd0a77 100644 (file)
@@ -4,7 +4,7 @@ Você pode usar o mesmo `TestClient` para testar WebSockets.
 
 Para isso, você utiliza o `TestClient` dentro de uma instrução `with`, conectando com o WebSocket:
 
-{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
 
 /// note | Nota
 
index 3653b4d37a045a43330262f284bd7a4420bacbd6..ab1ef9ff4d7bdd787a287c9db984a68b05796fc2 100644 (file)
@@ -29,7 +29,7 @@ Vamos imaginar que você deseja obter o endereço de IP/host do cliente dentro d
 
 Para isso você precisa acessar a requisição diretamente.
 
-{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
 
 Ao declarar o parâmetro com o tipo sendo um `Request` em sua *função de operação de rota*, o **FastAPI** saberá como passar o `Request` neste parâmetro.
 
index c31bb94b68fcf0131a088fb26587e8d1851dd8ea..021a73bed327140cee7c113e89f4380ca8b92a1e 100644 (file)
@@ -38,13 +38,13 @@ Na produção, você teria uma das opções acima.
 
 Mas é a maneira mais simples de focar no lado do servidor de WebSockets e ter um exemplo funcional:
 
-{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
 
 ## Crie um `websocket` { #create-a-websocket }
 
 Em sua aplicação **FastAPI**, crie um `websocket`:
 
-{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
 
 /// note | Detalhes Técnicos
 
@@ -58,7 +58,7 @@ A **FastAPI** fornece o mesmo `WebSocket` diretamente apenas como uma conveniên
 
 Em sua rota WebSocket você pode esperar (`await`) por mensagens e enviar mensagens.
 
-{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
 
 Você pode receber e enviar dados binários, de texto e JSON.
 
index ee21b2501018d22d61c3f2b4c50865624db83093..c3c21d430a30494fc353f0f89475fb3b54db6d86 100644 (file)
@@ -12,7 +12,7 @@ Em seguida, encapsule a aplicação WSGI (e.g. Flask) com o middleware.
 
 E então monte isso sob um path.
 
-{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
+{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
 
 ## Confira { #check-it }
 
index da4f5f76426b29bac50013fa3b1371b65dd25004..b475dae6d61217c582a2986bb702b17bd51c338a 100644 (file)
@@ -29,7 +29,7 @@ Você pode usar facilmente as mesmas configurações do Pydantic para configurar
 
 Por exemplo:
 
-{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
 
 Aqui declaramos a configuração `openapi_url` com o mesmo padrão de `"/openapi.json"`.
 
index 163316932fdff4bd8348cfb3922db4e9486bf540..2d1863c64c43b3b9f253854d1a07449628bdc753 100644 (file)
@@ -18,7 +18,7 @@ Sem alterar as configurações, o destaque de sintaxe é habilitado por padrão:
 
 Mas você pode desabilitá-lo definindo `syntaxHighlight` como `False`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
 
 ...e então o Swagger UI não mostrará mais o destaque de sintaxe:
 
@@ -28,7 +28,7 @@ Mas você pode desabilitá-lo definindo `syntaxHighlight` como `False`:
 
 Da mesma forma que você pode definir o tema de destaque de sintaxe com a chave `"syntaxHighlight.theme"` (observe que há um ponto no meio):
 
-{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
 
 Essa configuração alteraria o tema de cores de destaque de sintaxe:
 
@@ -46,7 +46,7 @@ Você pode substituir qualquer um deles definindo um valor diferente no argument
 
 Por exemplo, para desabilitar `deepLinking` você pode passar essas configurações para `swagger_ui_parameters`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
 
 ## Outros parâmetros da UI do Swagger { #other-swagger-ui-parameters }
 
index 30224c72bbf9f3df9921e040ce329be7ffb41e07..adda9eca50b813792e86bfaf3c3f55792a879b2d 100644 (file)
@@ -18,7 +18,7 @@ O primeiro passo é desativar a documentação automática, pois por padrão, el
 
 Para desativá-los, defina suas URLs como `None` ao criar sua aplicação FastAPI:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
 
 ### Incluir a documentação personalizada { #include-the-custom-docs }
 
@@ -34,7 +34,7 @@ Você pode reutilizar as funções internas do FastAPI para criar as páginas HT
 
 E de forma semelhante para o ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
 
 /// tip | Dica
 
@@ -50,7 +50,7 @@ Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse aux
 
 Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
 
 ### Teste { #test-it }
 
@@ -118,7 +118,7 @@ Depois disso, sua estrutura de arquivos deve se parecer com:
 * Importe `StaticFiles`.
 * "Monte" a instância `StaticFiles()` em um caminho específico.
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
 
 ### Teste os arquivos estáticos { #test-the-static-files }
 
@@ -144,7 +144,7 @@ Da mesma forma que ao usar um CDN personalizado, o primeiro passo é desativar a
 
 Para desativá-los, defina suas URLs como `None` ao criar sua aplicação FastAPI:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
 
 ### Incluir a documentação personalizada para arquivos estáticos { #include-the-custom-docs-for-static-files }
 
@@ -160,7 +160,7 @@ Novamente, você pode reutilizar as funções internas do FastAPI para criar as
 
 E de forma semelhante para o ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
 
 /// tip | Dica
 
@@ -176,7 +176,7 @@ Swagger UI lidará com isso nos bastidores para você, mas ele precisa desse aux
 
 Agora, para poder testar se tudo funciona, crie uma *operação de rota*:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
 
 ### Teste a UI de Arquivos Estáticos { #test-static-files-ui }
 
index 54d56b95aeb8dd4d9ea6cf73cbce2580042501a1..b1b50ce65474a6a11b1847987e16056a3b04e96e 100644 (file)
@@ -43,19 +43,19 @@ Por exemplo, vamos adicionar <a href="https://github.com/Rebilly/ReDoc/blob/mast
 
 Primeiro, escreva toda a sua aplicação **FastAPI** normalmente:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
 
 ### Gerar o esquema OpenAPI { #generate-the-openapi-schema }
 
 Em seguida, use a mesma função utilitária para gerar o esquema OpenAPI, dentro de uma função `custom_openapi()`:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
 
 ### Modificar o esquema OpenAPI { #modify-the-openapi-schema }
 
 Agora, você pode adicionar a extensão do ReDoc, incluindo um `x-logo` personalizado ao "objeto" `info` no esquema OpenAPI:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
 
 ### Armazenar em cache o esquema OpenAPI { #cache-the-openapi-schema }
 
@@ -65,13 +65,13 @@ Dessa forma, sua aplicação não precisará gerar o esquema toda vez que um usu
 
 Ele será gerado apenas uma vez, e o mesmo esquema armazenado em cache será utilizado nas próximas requisições.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
 
 ### Sobrescrever o método { #override-the-method }
 
 Agora, você pode substituir o método `.openapi()` pela sua nova função.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
 
 ### Verificar { #check-it }
 
index b1e782c4f02d95d42f260c4f9507a9ac73d028e3..7af4c6b7546752d4d58d75262687a1e28792cd81 100644 (file)
@@ -35,7 +35,7 @@ Dependendo do seu caso de uso, você pode preferir usar uma biblioteca diferente
 
 Aqui está uma pequena prévia de como você poderia integrar Strawberry com FastAPI:
 
-{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *}
+{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *}
 
 Você pode aprender mais sobre Strawberry na <a href="https://strawberry.rocks/" class="external-link" target="_blank">documentação do Strawberry</a>.
 
index 3e2d1ccb302d95c0b1fa02a1edfc5ce9df493036..fc983d1df1078ffc276794eca7fdf11179920bf7 100644 (file)
@@ -22,7 +22,7 @@ Se você é um especialista em Python e já sabe tudo sobre type hints, pule par
 
 Vamos começar com um exemplo simples:
 
-{* ../../docs_src/python_types/tutorial001.py *}
+{* ../../docs_src/python_types/tutorial001_py39.py *}
 
 A chamada deste programa gera:
 
@@ -36,7 +36,7 @@ A função faz o seguinte:
 * Converte a primeira letra de cada uma em maiúsculas com `title()`.
 * <abbr title = "Agrupa-os, como um. Com o conteúdo de um após o outro.">Concatena</abbr> com um espaço no meio.
 
-{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
 
 ### Edite-o { #edit-it }
 
@@ -78,7 +78,7 @@ para:
 
 Esses são os "type hints":
 
-{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
 
 Isso não é o mesmo que declarar valores padrão como seria com:
 
@@ -106,7 +106,7 @@ Com isso, você pode rolar, vendo as opções, até encontrar o que "soa familia
 
 Verifique esta função, ela já possui type hints:
 
-{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
 
 Como o editor conhece os tipos de variáveis, você não obtém apenas o preenchimento automático, mas também as verificações de erro:
 
@@ -114,7 +114,7 @@ Como o editor conhece os tipos de variáveis, você não obtém apenas o preench
 
 Agora você sabe que precisa corrigí-lo, converta `age` em uma string com `str(age)`:
 
-{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
 
 ## Declarando Tipos { #declaring-types }
 
@@ -133,7 +133,7 @@ Você pode usar, por exemplo:
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
 
 ### Tipos genéricos com parâmetros de tipo { #generic-types-with-type-parameters }
 
@@ -161,56 +161,24 @@ Se você pode utilizar a **versão mais recente do Python**, utilize os exemplos
 
 Por exemplo, vamos definir uma variável para ser uma `list` de `str`.
 
-//// tab | Python 3.9+
-
-Declare uma variável com a mesma sintaxe com dois pontos (`:`)
-
-Como tipo, coloque `list`.
-
-Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006_py39.py!}
-```
-
-////
+Declare a variável, com a mesma sintaxe com dois pontos (`:`).
 
-//// tab | Python 3.8+
+Como o tipo, coloque `list`.
 
-De `typing`, importe `List` (com o `L` maiúsculo):
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
+Como a lista é um tipo que contém tipos internos, você os coloca entre colchetes:
 
-Declare uma variável com a mesma sintaxe com dois pontos (`:`)
-
-Como tipo, coloque o `List` que você importou de `typing`.
-
-Como a lista é o tipo que contém algum tipo interno, você coloca o tipo dentro de colchetes:
-
-```Python hl_lines="4"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
 
 /// info | Informação
 
 Estes tipos internos dentro dos colchetes são chamados "parâmetros de tipo" (type parameters).
 
-Neste caso, `str` é o parâmetro de tipo passado para `List` (ou `list` no Python 3.9 ou superior).
+Neste caso, `str` é o parâmetro de tipo passado para `list`.
 
 ///
 
 Isso significa: "a variável `items` é uma `list`, e cada um dos itens desta lista é uma `str`".
 
-/// tip | Dica
-
-Se você usa o Python 3.9 ou superior, você não precisa importar `List` de `typing`. Você pode utilizar o mesmo tipo `list` no lugar.
-
-///
-
 Ao fazer isso, seu editor pode fornecer suporte mesmo durante o processamento de itens da lista:
 
 <img src="/img/python-types/image05.png">
@@ -225,21 +193,7 @@ E, ainda assim, o editor sabe que é um `str` e fornece suporte para isso.
 
 Você faria o mesmo para declarar `tuple`s e `set`s:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial007_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
 
 Isso significa que:
 
@@ -254,21 +208,7 @@ O primeiro parâmetro de tipo é para as chaves do `dict`.
 
 O segundo parâmetro de tipo é para os valores do `dict`:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial008_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
 
 Isso significa que:
 
@@ -292,10 +232,10 @@ No Python 3.10 também existe uma **nova sintaxe** onde você pode colocar os po
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008b.py!}
+{!> ../../docs_src/python_types/tutorial008b_py39.py!}
 ```
 
 ////
@@ -309,7 +249,7 @@ Você pode declarar que um valor pode ter um tipo, como `str`, mas que ele tamb
 No Python 3.6 e superior (incluindo o Python 3.10) você pode declará-lo importando e utilizando `Optional` do módulo `typing`.
 
 ```Python hl_lines="1  4"
-{!../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 O uso de `Optional[str]` em vez de apenas `str` permitirá que o editor o ajude a detectar erros, onde você pode estar assumindo que um valor é sempre um `str`, quando na verdade também pode ser `None`.
@@ -326,18 +266,18 @@ Isso também significa que no Python 3.10, você pode utilizar `Something | None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009.py!}
+{!> ../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 ////
 
-//// tab | Python 3.8+ alternativa
+//// tab | Python 3.9+ alternativa
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009b.py!}
+{!> ../../docs_src/python_types/tutorial009b_py39.py!}
 ```
 
 ////
@@ -357,7 +297,7 @@ Isso é apenas sobre palavras e nomes. Mas estas palavras podem afetar como os s
 
 Por exemplo, vamos pegar esta função:
 
-{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
 
 O parâmetro `name` é definido como `Optional[str]`, mas ele **não é opcional**, você não pode chamar a função sem o parâmetro:
 
@@ -390,10 +330,10 @@ Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e ti
 * `set`
 * `dict`
 
-E o mesmo como no Python 3.8, do módulo `typing`:
+E o mesmo que com versões anteriores do Python, do módulo `typing`:
 
 * `Union`
-* `Optional` (o mesmo que com o 3.8)
+* `Optional`
 * ...entre outros.
 
 No Python 3.10, como uma alternativa para a utilização dos genéricos `Union` e `Optional`, você pode usar a <abbr title='também chamado de "bitwise ou operador", mas o significado não é relevante aqui'>barra vertical (`|`)</abbr> para declarar uniões de tipos. Isso é muito melhor e mais simples.
@@ -409,20 +349,8 @@ Você pode utilizar os mesmos tipos internos como genéricos (com colchetes e ti
 * `set`
 * `dict`
 
-E o mesmo como no Python 3.8, do módulo `typing`:
-
-* `Union`
-* `Optional`
-* ...entre outros.
-
-////
-
-//// tab | Python 3.8+
+E genéricos do módulo `typing`:
 
-* `List`
-* `Tuple`
-* `Set`
-* `Dict`
 * `Union`
 * `Optional`
 * ...entre outros.
@@ -435,13 +363,13 @@ Você também pode declarar uma classe como o tipo de uma variável.
 
 Digamos que você tenha uma classe `Person`, com um nome:
 
-{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
 
 Então você pode declarar que uma variável é do tipo `Person`:
 
-{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
 
-E então, novamente, você recebe todo o suporte do editor:
+E então, novamente, você recebe todo o apoio do editor:
 
 <img src="/img/python-types/image06.png">
 
@@ -461,31 +389,9 @@ Em seguida, você cria uma instância dessa classe com alguns valores e ela os v
 
 E você recebe todo o suporte do editor com esse objeto resultante.
 
-Retirado dos documentos oficiais dos Pydantic:
+Um exemplo da documentação oficial do Pydantic:
 
-//// tab | Python 3.10+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial011_py310.py *}
 
 /// info | Informação
 
@@ -507,27 +413,9 @@ O Pydantic tem um comportamento especial quando você usa `Optional` ou `Union[S
 
 O Python possui uma funcionalidade que nos permite incluir **<abbr title="Informação sobre a informação, neste caso, informação sobre o tipo, e.g. uma descrição.">metadados</abbr> adicionais** nos type hints utilizando `Annotated`.
 
-//// tab | Python 3.9+
-
-No Python 3.9, `Annotated` é parte da biblioteca padrão, então você pode importá-lo de `typing`.
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-Em versões abaixo do Python 3.9, você importa `Annotated` de `typing_extensions`.
+Desde o Python 3.9, `Annotated` faz parte da biblioteca padrão, então você pode importá-lo de `typing`.
 
-Ele já estará instalado com o **FastAPI**.
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
 
 O Python em si não faz nada com este `Annotated`. E para editores e outras ferramentas, o tipo ainda é `str`.
 
index af0c8b2acdd8fea4f4f623c53ccd678bb7ab96fa..34805364b4eafcc7f27daef71148458a2ea9075d 100644 (file)
@@ -15,7 +15,7 @@ Isso inclui, por exemplo:
 
 Primeiro, importe `BackgroundTasks` e defina um parâmetro na sua *função de operação de rota* com uma declaração de tipo `BackgroundTasks`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
 
 O **FastAPI** criará o objeto do tipo `BackgroundTasks` para você e o passará como esse parâmetro.
 
@@ -31,13 +31,13 @@ Neste caso, a função da tarefa escreverá em um arquivo (simulando o envio de
 
 E como a operação de escrita não usa `async` e `await`, definimos a função com um `def` normal:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
 
 ## Adicione a tarefa em segundo plano { #add-the-background-task }
 
 Dentro da sua *função de operação de rota*, passe sua função de tarefa para o objeto de *tarefas em segundo plano* com o método `.add_task()`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
 
 O `.add_task()` recebe como argumentos:
 
index 4f3ca661fbebe4e37d41f18fd2b49e85518563f4..f2bec19a2fc4a11b22455deb0d8ff77f1daac8e1 100644 (file)
@@ -14,35 +14,15 @@ Isso fará com que tags seja uma lista de itens mesmo sem declarar o tipo dos el
 
 Mas o Python tem uma maneira específica de declarar listas com tipos internos ou "parâmetros de tipo":
 
-### Importe `List` do typing { #import-typings-list }
-
-No Python 3.9 e superior você pode usar a `list` padrão para declarar essas anotações de tipo, como veremos abaixo. 💡
-
-Mas nas versões do Python anteriores à 3.9 (3.6 e superiores), primeiro é necessário importar `List` do módulo padrão `typing` do Python:
-
-{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
-
 ### Declare uma `list` com um parâmetro de tipo { #declare-a-list-with-a-type-parameter }
 
-Para declarar tipos que têm parâmetros de tipo (tipos internos), como `list`, `dict`, `tuple`:
-
-* Se você estiver em uma versão do Python inferior a 3.9, importe a versão equivalente do módulo `typing`
-* Passe o(s) tipo(s) interno(s) como "parâmetros de tipo" usando colchetes: `[` e `]`
-
-No Python 3.9, seria:
+Para declarar tipos que têm parâmetros de tipo (tipos internos), como `list`, `dict`, `tuple`,
+passe o(s) tipo(s) interno(s) como "parâmetros de tipo" usando colchetes: `[` e `]`
 
 ```Python
 my_list: list[str]
 ```
 
-Em versões do Python anteriores à 3.9, seria:
-
-```Python
-from typing import List
-
-my_list: List[str]
-```
-
 Essa é a sintaxe padrão do Python para declarações de tipo.
 
 Use a mesma sintaxe padrão para atributos de modelo com tipos internos.
@@ -178,12 +158,6 @@ Observe como `Offer` tem uma lista de `Item`s, que por sua vez têm uma lista op
 
 Se o valor de primeiro nível do corpo JSON que você espera for um `array` do JSON (uma` lista` do Python), você pode declarar o tipo no parâmetro da função, da mesma forma que nos modelos do Pydantic:
 
-```Python
-images: List[Image]
-```
-
-ou no Python 3.9 e superior:
-
 ```Python
 images: list[Image]
 ```
index ef00b9a7a70560665e5799a94f2023bf55dcd4db..1330f4458f69721cd555f13a37cae4cdb5012849 100644 (file)
@@ -161,7 +161,7 @@ Os parâmetros da função serão reconhecidos conforme abaixo:
 
 O FastAPI saberá que o valor de `q` não é obrigatório por causa do valor padrão `= None`.
 
-O `str | None` (Python 3.10+) ou o `Union` em `Union[str, None]` (Python 3.8+) não é utilizado pelo FastAPI para determinar que o valor não é obrigatório, ele saberá que não é obrigatório porque tem um valor padrão `= None`.
+O `str | None` (Python 3.10+) ou o `Union` em `Union[str, None]` (Python 3.9+) não é utilizado pelo FastAPI para determinar que o valor não é obrigatório, ele saberá que não é obrigatório porque tem um valor padrão `= None`.
 
 Mas adicionar as anotações de tipo permitirá ao seu editor oferecer um suporte melhor e detectar erros.
 
index c08191db148734cff455c2bf14de30a13f67ef10..0f99db888e16df12c4dcfe4f879123f3a78bdabd 100644 (file)
@@ -46,7 +46,7 @@ Você também pode especificar se o seu backend permite:
 * Métodos HTTP específicos (`POST`, `PUT`) ou todos eles com o curinga `"*"`.
 * Cabeçalhos HTTP específicos ou todos eles com o curinga `"*"`.
 
-{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
 
 Os parâmetros padrão usados ​​pela implementação `CORSMiddleware` são restritivos por padrão, então você precisará habilitar explicitamente as origens, métodos ou cabeçalhos específicos para que os navegadores tenham permissão para usá-los em um contexto cross domain.
 
index 21d1d527bd53a526b7c73721fcab1ad801561f8c..e39c7d12801ed5d358bcf02d040af6d0f2ad24e9 100644 (file)
@@ -6,7 +6,7 @@ Você pode conectar o depurador no seu editor, por exemplo, com o Visual Studio
 
 Em sua aplicação FastAPI, importe e execute `uvicorn` diretamente:
 
-{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
 
 ### Sobre `__name__ == "__main__"` { #about-name-main }
 
index aa26d158f44b17e589dcd3517ee003fd99d257e8..c30d0b5f08c2d435cd44524d608f45953135d15d 100644 (file)
@@ -101,7 +101,7 @@ O **FastAPI** chama a classe `CommonQueryParams`. Isso cria uma "instância" des
 
 Perceba como escrevemos `CommonQueryParams` duas vezes no código abaixo:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Dica
 
@@ -137,7 +137,7 @@ O último `CommonQueryParams`, em:
 
 Nesse caso, o primeiro `CommonQueryParams`, em:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Dica
 
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
 
 Na verdade você poderia escrever apenas:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Dica
 
@@ -197,7 +197,7 @@ Mas declarar o tipo é encorajado por que é a forma que o seu editor de texto s
 
 Mas você pode ver que temos uma repetição do código neste exemplo, escrevendo `CommonQueryParams` duas vezes:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Dica
 
@@ -225,7 +225,7 @@ Para esses casos específicos, você pode fazer o seguinte:
 
 Em vez de escrever:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Dica
 
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 ...escreva:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
 
 ////
 
-//// tab | Python 3.8 non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Dica
 
index 0aedcfb31e4cf7576ffda4b6f4cc6db6659c77c9..3678730139b720dc1004f348fd960b5209b3054e 100644 (file)
@@ -29,15 +29,15 @@ Por exemplo, você poderia utilizar isso para criar uma sessão do banco de dado
 
 Apenas o código anterior à declaração com `yield` e o código contendo essa declaração são executados antes de criar uma resposta:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
 
 O valor gerado (yielded) é o que é injetado nas *operações de rota* e outras dependências:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
 
 O código após o `yield` é executado após a resposta:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
 
 /// tip | Dica
 
@@ -57,7 +57,7 @@ Então, você pode procurar por essa exceção específica dentro da dependênci
 
 Da mesma forma, você pode utilizar `finally` para garantir que os passos de saída são executados, com ou sem exceções.
 
-{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
 
 ## Subdependências com `yield` { #sub-dependencies-with-yield }
 
@@ -269,7 +269,7 @@ Em Python, você pode criar Gerenciadores de Contexto ao <a href="https://docs.p
 Você também pode usá-los dentro de dependências com `yield` do **FastAPI** ao utilizar
 `with` ou `async with` dentro da função da dependência:
 
-{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
 
 /// tip | Dica
 
index cf0f908020992c56293a0694747003bbdb23c1b3..4d6e8a69a01c360ae816730f29483ee8ac141cf6 100644 (file)
@@ -6,7 +6,7 @@ De forma semelhante a [adicionar `dependencies` aos *decoradores de operação d
 
 Nesse caso, elas serão aplicadas a todas as *operações de rota* da aplicação:
 
-{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
+{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
 
 
 E todos os conceitos apresentados na seção sobre [adicionar `dependencies` aos *decoradores de operação de rota*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} ainda se aplicam, mas nesse caso, para todas as *operações de rota* da aplicação.
index fa746d5a1f1f9ab586ba544f8ecdf2b2925126ca..e2dc9bbf9aea40e1f0295f7a97ec42093da731d5 100644 (file)
@@ -62,7 +62,7 @@ E o valor retornado é salvo em um <abbr title="Um utilitário/sistema para arma
 
 Em um cenário avançado onde você precise que a dependência seja calculada em cada passo (possivelmente várias vezes) de uma requisição em vez de utilizar o valor em "cache", você pode definir o parâmetro `use_cache=False` em `Depends`:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Dica
 
index 40813c21e257946aa1764470bf55bcb766ef38aa..86cddde5da1654db13db2fe03f6c78d1e506e8d2 100644 (file)
@@ -2,7 +2,7 @@
 
 O arquivo FastAPI mais simples pode se parecer com:
 
-{* ../../docs_src/first_steps/tutorial001.py *}
+{* ../../docs_src/first_steps/tutorial001_py39.py *}
 
 Copie o conteúdo para um arquivo `main.py`.
 
@@ -183,7 +183,7 @@ Deploying to FastAPI Cloud...
 
 ### Passo 1: importe `FastAPI` { #step-1-import-fastapi }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
 
 `FastAPI` é uma classe Python que fornece todas as funcionalidades para sua API.
 
@@ -197,7 +197,7 @@ Você pode usar todas as funcionalidades do <a href="https://www.starlette.dev/"
 
 ### Passo 2: crie uma "instância" de `FastAPI` { #step-2-create-a-fastapi-instance }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
 
 Aqui, a variável `app` será uma "instância" da classe `FastAPI`.
 
@@ -266,7 +266,7 @@ Vamos chamá-los de "**operações**" também.
 
 #### Defina um decorador de operação de rota { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
 
 O `@app.get("/")` diz ao **FastAPI** que a função logo abaixo é responsável por tratar as requisições que vão para:
 
@@ -320,7 +320,7 @@ Esta é a nossa "**função de operação de rota**":
 * **operação**: é `get`.
 * **função**: é a função abaixo do "decorador" (abaixo do `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
 
 Esta é uma função Python.
 
@@ -332,7 +332,7 @@ Neste caso, é uma função `async`.
 
 Você também pode defini-la como uma função normal em vez de `async def`:
 
-{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
 
 /// note | Nota
 
@@ -342,7 +342,7 @@ Se você não sabe a diferença, verifique o [Async: *"Com pressa?"*](../async.m
 
 ### Passo 5: retorne o conteúdo { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
 
 Você pode retornar um `dict`, `list` e valores singulares como `str`, `int`, etc.
 
index 456fd0b4e967e9c65aecd630792029eaae97b432..1c162c205fa6cc116daee5568e0a0c5fd259ab6b 100644 (file)
@@ -25,7 +25,7 @@ Para retornar ao cliente *responses* HTTP com erros, use o `HTTPException`.
 
 ### Import `HTTPException` { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
 
 ### Lance o `HTTPException` no seu código { #raise-an-httpexception-in-your-code }
 
@@ -39,7 +39,7 @@ O benefício de lançar uma exceção em vez de retornar um valor ficará mais e
 
 Neste exemplo, quando o cliente pede, na requisição, por um item cujo ID não existe, a exceção com o status code `404` é lançada:
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
 
 ### A response resultante { #the-resulting-response }
 
@@ -77,7 +77,7 @@ Você provavelmente não precisará utilizar esses headers diretamente no seu c
 
 Mas caso você precise, para um cenário mais complexo, você pode adicionar headers customizados:
 
-{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
 
 ## Instale manipuladores de exceções customizados { #install-custom-exception-handlers }
 
@@ -87,7 +87,7 @@ Digamos que você tenha uma exceção customizada `UnicornException` que você (
 
 Nesse cenário, se você precisa manipular essa exceção de modo global com o FastAPI, você pode adicionar um manipulador de exceção customizada com `@app.exception_handler()`.
 
-{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
 
 Nesse cenário, se você fizer uma requisição para `/unicorns/yolo`, a *operação de caminho* vai lançar (`raise`) o `UnicornException`.
 
@@ -125,7 +125,7 @@ Para sobrescrevê-lo, importe o `RequestValidationError` e use-o com o `@app.exc
 
 O manipulador de exceções receberá um `Request` e a exceção.
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
 
 Se você for ao `/items/foo`, em vez de receber o JSON padrão com o erro:
 
@@ -157,7 +157,7 @@ Do mesmo modo, você pode sobrescrever o `HTTPException`.
 
 Por exemplo, você pode querer retornar uma *response* em *plain text* ao invés de um JSON para os seguintes erros:
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
 
 /// note | Detalhes Técnicos
 
@@ -181,7 +181,7 @@ O `RequestValidationError` contém o `body` que ele recebeu de dados inválidos.
 
 Você pode utilizá-lo enquanto desenvolve seu app para registrar o *body* e debugá-lo, e assim retorná-lo ao usuário, etc.
 
-{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
 
 Tente enviar um item inválido como este:
 
@@ -237,6 +237,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
 
 Se você quer usar a exceção em conjunto com o mesmo manipulador de exceção *default* do **FastAPI**, você pode importar e re-usar esses manipuladores de exceção do `fastapi.exception_handlers`:
 
-{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
 
 Nesse exemplo você apenas imprime (`print`) o erro com uma mensagem expressiva. Mesmo assim, dá para pegar a ideia. Você pode usar a exceção e então apenas re-usar o manipulador de exceção *default*.
index 06b2e6b9e428da89ea1577433b3b940680182442..df77e5648478258ada6fa35e0bb0a9733137adaf 100644 (file)
@@ -18,7 +18,7 @@ Você pode definir os seguintes campos que são usados na especificação OpenAP
 
 Você pode defini-los da seguinte maneira:
 
-{* ../../docs_src/metadata/tutorial001.py hl[3:16,19:32] *}
+{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
 
 /// tip | Dica
 
@@ -36,7 +36,7 @@ Desde o OpenAPI 3.1.0 e FastAPI 0.99.0, você também pode definir o license_inf
 
 Por exemplo:
 
-{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
 
 ## Metadados para tags { #metadata-for-tags }
 
@@ -58,7 +58,7 @@ Vamos tentar isso em um exemplo com tags para `users` e `items`.
 
 Crie metadados para suas tags e passe-os para o parâmetro `openapi_tags`:
 
-{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
 
 Observe que você pode usar Markdown dentro das descrições. Por exemplo, "login" será exibido em negrito (**login**) e "fancy" será exibido em itálico (_fancy_).
 
@@ -72,7 +72,7 @@ Você não precisa adicionar metadados para todas as tags que você usa.
 
 Use o parâmetro `tags` com suas *operações de rota* (e `APIRouter`s) para atribuí-los a diferentes tags:
 
-{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
 
 /// info | Informação
 
@@ -100,7 +100,7 @@ Mas você pode configurá-lo com o parâmetro `openapi_url`.
 
 Por exemplo, para defini-lo para ser servido em `/api/v1/openapi.json`:
 
-{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
 
 Se você quiser desativar completamente o esquema OpenAPI, pode definir `openapi_url=None`, o que também desativará as interfaces de documentação que o utilizam.
 
@@ -117,4 +117,4 @@ Você pode configurar as duas interfaces de documentação incluídas:
 
 Por exemplo, para definir o Swagger UI para ser servido em `/documentation` e desativar o ReDoc:
 
-{* ../../docs_src/metadata/tutorial003.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
index e1eb2f528fbf8cf9fe053dcab23261f58dbe42c4..b49c1eaa1188edf2101fd7398ee659e56ea04bd5 100644 (file)
@@ -31,7 +31,7 @@ A função middleware recebe:
     * Então ela retorna a `response` gerada pela *operação de rota* correspondente.
 * Você pode então modificar ainda mais o `response` antes de retorná-lo.
 
-{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
 
 /// tip | Dica
 
@@ -57,7 +57,7 @@ E também depois que a `response` é gerada, antes de retorná-la.
 
 Por exemplo, você pode adicionar um cabeçalho personalizado `X-Process-Time` contendo o tempo em segundos que levou para processar a solicitação e gerar uma resposta:
 
-{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
 
 /// tip | Dica
 
index 5b4c82aa89c2361edfa5431e219b70e4daca1df3..84eebc1285411cb42ecb4e3df55c3378edbeca9d 100644 (file)
@@ -46,7 +46,7 @@ Nestes casos, pode fazer sentido armazenar as tags em um `Enum`.
 
 **FastAPI** suporta isso da mesma maneira que com strings simples:
 
-{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
 
 ## Resumo e descrição { #summary-and-description }
 
@@ -92,7 +92,7 @@ Então, se você não fornecer uma, o **FastAPI** irá gerar automaticamente uma
 
 Se você precisar marcar uma *operação de rota* como <abbr title="obsoleta, recomendada não usá-la">descontinuada</abbr>, mas sem removê-la, passe o parâmetro `deprecated`:
 
-{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
 
 Ela será claramente marcada como descontinuada nas documentações interativas:
 
index cec744fd5edd1e0a24516b8ac6809870988b6553..9f12ba38fe64af290583633e45a8e48923629b1b 100644 (file)
@@ -54,7 +54,7 @@ Isso não faz diferença para o **FastAPI**. Ele vai detectar os parâmetros pel
 
 Então, você pode declarar sua função assim:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
 
 Mas tenha em mente que, se você usar `Annotated`, você não terá esse problema, não fará diferença, pois você não está usando valores padrão de parâmetros de função para `Query()` ou `Path()`.
 
@@ -83,7 +83,7 @@ Passe `*`, como o primeiro parâmetro da função.
 
 O Python não fará nada com esse `*`, mas saberá que todos os parâmetros seguintes devem ser chamados como argumentos nomeados (pares chave-valor), também conhecidos como <abbr title="Do inglês: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>. Mesmo que eles não tenham um valor padrão.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
 
 ### Melhor com `Annotated` { #better-with-annotated }
 
index d795d5b2a0d213b0feef6c8f912331a43223121b..1f47ca6e59d7445e97186fdf0f35a0bd461f562c 100644 (file)
@@ -2,7 +2,7 @@
 
 Você pode declarar "parâmetros" ou "variáveis" de path com a mesma sintaxe usada por strings de formatação do Python:
 
-{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
 
 O valor do parâmetro de path `item_id` será passado para a sua função como o argumento `item_id`.
 
@@ -16,7 +16,7 @@ Então, se você executar este exemplo e acessar <a href="http://127.0.0.1:8000/
 
 Você pode declarar o tipo de um parâmetro de path na função, usando as anotações de tipo padrão do Python:
 
-{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
 
 Neste caso, `item_id` é declarado como um `int`.
 
@@ -110,13 +110,13 @@ E então você também pode ter um path `/users/{user_id}` para obter dados sobr
 
 Como as *operações de rota* são avaliadas em ordem, você precisa garantir que o path para `/users/me` seja declarado antes do de `/users/{user_id}`:
 
-{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
 
 Caso contrário, o path para `/users/{user_id}` também corresponderia a `/users/me`, "achando" que está recebendo um parâmetro `user_id` com o valor `"me"`.
 
 Da mesma forma, você não pode redefinir uma operação de rota:
 
-{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
 
 A primeira sempre será usada, já que o path corresponde primeiro.
 
@@ -132,11 +132,7 @@ Ao herdar de `str`, a documentação da API saberá que os valores devem ser do
 
 Em seguida, crie atributos de classe com valores fixos, que serão os valores válidos disponíveis:
 
-{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
-
-/// info | Informação
-<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Enumerations (ou enums) estão disponíveis no Python</a> desde a versão 3.4.
-///
+{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
 
 /// tip | Dica
 Se você está se perguntando, "AlexNet", "ResNet" e "LeNet" são apenas nomes de <abbr title="Tecnicamente, arquiteturas de modelos de Deep Learning">modelos</abbr> de Aprendizado de Máquina.
@@ -146,7 +142,7 @@ Se você está se perguntando, "AlexNet", "ResNet" e "LeNet" são apenas nomes d
 
 Em seguida, crie um *parâmetro de path* com anotação de tipo usando a classe enum que você criou (`ModelName`):
 
-{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
 
 ### Verifique a documentação { #check-the-docs }
 
@@ -162,13 +158,13 @@ O valor do *parâmetro de path* será um *membro de enumeração*.
 
 Você pode compará-lo com o *membro de enumeração* no seu enum `ModelName` criado:
 
-{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
 
 #### Obtenha o valor da enumeração { #get-the-enumeration-value }
 
 Você pode obter o valor real (um `str` neste caso) usando `model_name.value`, ou, em geral, `your_enum_member.value`:
 
-{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
 
 /// tip | Dica
 Você também pode acessar o valor `"lenet"` com `ModelName.lenet.value`.
@@ -180,7 +176,7 @@ Você pode retornar *membros de enum* da sua *operação de rota*, até mesmo an
 
 Eles serão convertidos para seus valores correspondentes (strings neste caso) antes de serem retornados ao cliente:
 
-{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
 
 No seu cliente, você receberá uma resposta JSON como:
 
@@ -219,7 +215,7 @@ Nesse caso, o nome do parâmetro é `file_path`, e a última parte, `:path`, diz
 
 Então, você pode usá-lo com:
 
-{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
 
 /// tip | Dica
 Você pode precisar que o parâmetro contenha `/home/johndoe/myfile.txt`, com uma barra inicial (`/`).
index 948f8ca8faa379d32691ad68ee644974f96ab2db..5ec1b1b55e1d91707a07f4677e612d6872b17be1 100644 (file)
@@ -55,7 +55,7 @@ q: str | None = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Union[str, None] = None
@@ -73,7 +73,7 @@ q: Annotated[str | None] = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Annotated[Union[str, None]] = None
index 5a3fed0359834804487009d9e1f09a0ebe76dc2a..8826602a25d7e4a5ed4cbeb2b2e4734e21f9fe7e 100644 (file)
@@ -2,7 +2,7 @@
 
 Quando você declara outros parâmetros na função que não fazem parte dos parâmetros da rota, esses parâmetros são automaticamente interpretados como parâmetros de "consulta".
 
-{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
 
 A consulta é o conjunto de pares chave-valor que vai depois de `?` na URL, separado pelo caractere `&`.
 
@@ -127,7 +127,7 @@ Caso você não queira adicionar um valor específico mas queira apenas torná-l
 
 Porém, quando você quiser fazer com que o parâmetro de consulta seja obrigatório, você pode simplesmente não declarar nenhum valor como padrão.
 
-{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
 
 Aqui o parâmetro de consulta `needy` é um valor obrigatório, do tipo `str`.
 
index 5958240e4cc586c4cf1d252a5efb0005862d0653..dc66bb46c49364e893b09348c105b086eadad8a9 100644 (file)
@@ -183,7 +183,7 @@ Pode haver casos em que você retorna algo que não é um campo Pydantic válido
 
 O caso mais comum seria [retornar uma Response diretamente, conforme explicado posteriormente na documentação avançada](../advanced/response-directly.md){.internal-link target=_blank}.
 
-{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
 
 Este caso simples é tratado automaticamente pelo FastAPI porque a anotação do tipo de retorno é a classe (ou uma subclasse de) `Response`.
 
@@ -193,7 +193,7 @@ E as ferramentas também ficarão felizes porque `RedirectResponse` e ​​`JSO
 
 Você também pode usar uma subclasse de `Response` na anotação de tipo:
 
-{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
 
 Isso também funcionará porque `RedirectResponse` é uma subclasse de `Response`, e o FastAPI tratará automaticamente este caso simples.
 
index 854bf57c9d823d65134e2b1a0a7aedf2a9e13f00..756c86dada73deac940848d9764059dc926e0fd1 100644 (file)
@@ -8,7 +8,7 @@ Da mesma forma que você pode especificar um modelo de resposta, você também p
 * `@app.delete()`
 * etc.
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 /// note | Nota
 
@@ -74,7 +74,7 @@ Para saber mais sobre cada código de status e qual código serve para quê, ver
 
 Vamos ver o exemplo anterior novamente:
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 `201` é o código de status para "Criado".
 
@@ -82,7 +82,7 @@ Mas você não precisa memorizar o que cada um desses códigos significa.
 
 Você pode usar as variáveis de conveniência de `fastapi.status`.
 
-{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
 
 Eles são apenas uma conveniência, eles possuem o mesmo número, mas dessa forma você pode usar o preenchimento automático do editor para encontrá-los:
 
index 13313a909eca7d257fb4cc89deb75752e0adb7bc..04a02c7f96339206126d86edee5748f902fdd519 100644 (file)
@@ -7,7 +7,7 @@ Você pode servir arquivos estáticos automaticamente a partir de um diretório
 * Importe `StaticFiles`.
 * "Monte" uma instância de `StaticFiles()` em um path específico.
 
-{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
 
 /// note | Detalhes Técnicos
 
index 03f1981a3c2de02f224a0ddf1be9799a66c9cbd3..e56edcb8c29a2f8cd9166eef677b4e9021a20eae 100644 (file)
@@ -30,7 +30,7 @@ Use o objeto `TestClient` da mesma forma que você faz com `httpx`.
 
 Escreva instruções `assert` simples com as expressões Python padrão que você precisa verificar (novamente, `pytest` padrão).
 
-{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
 
 /// tip | Dica
 
@@ -76,7 +76,7 @@ Digamos que você tenha uma estrutura de arquivo conforme descrito em [Aplicaç
 No arquivo `main.py` você tem sua aplicação **FastAPI**:
 
 
-{* ../../docs_src/app_testing/main.py *}
+{* ../../docs_src/app_testing/app_a_py39/main.py *}
 
 ### Arquivo de teste { #testing-file }
 
@@ -92,7 +92,7 @@ Então você poderia ter um arquivo `test_main.py` com seus testes. Ele poderia
 
 Como esse arquivo está no mesmo pacote, você pode usar importações relativas para importar o objeto `app` do módulo `main` (`main.py`):
 
-{* ../../docs_src/app_testing/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
 
 ...e ter o código para os testes como antes.
 
index 01ce4143cbbc428c77fe072fb96391277102fe64..2374070cedc667540e32fdd3e129d65003b5cfcc 100644 (file)
@@ -47,7 +47,7 @@ For the next terms, use the following translations:
 * list (as in Python list): list
 * Machine Learning: Aprendizado de Máquina
 * media type: media type (do not translate to "tipo de mídia")
-* non-Annotated: non-Annotated (do not translate non-Annotated when it comes after a Python version.e.g., “Python 3.8+ non-Annotated”)
+* non-Annotated: non-Annotated (do not translate non-Annotated when it comes after a Python version.e.g., “Python 3.10+ non-Annotated”)
 * operation IDs: IDs de operação
 * path (as in URL path): path
 * path operation: operação de rota
index 1fc3715e4120d8bbf6315533cf27c0e68bd2fddf..fca4f072da44965961f9e17b3d7de9dc8d354241 100644 (file)
@@ -26,7 +26,7 @@
 
 Например, чтобы объявить ещё один ответ со статус-кодом `404` и Pydantic-моделью `Message`, можно написать:
 
-{* ../../docs_src/additional_responses/tutorial001.py hl[18,22] *}
+{* ../../docs_src/additional_responses/tutorial001_py39.py hl[18,22] *}
 
 /// note | Примечание
 
 
 А также ответ со статус-кодом `200`, который использует ваш `response_model`, но включает пользовательский `example`:
 
-{* ../../docs_src/additional_responses/tutorial003.py hl[20:31] *}
+{* ../../docs_src/additional_responses/tutorial003_py39.py hl[20:31] *}
 
 Всё это будет объединено и включено в ваш OpenAPI и отображено в документации API:
 
index 5062bc52e7788e7b4c8f02ce956071749ecba0e0..e689704066adb873062a030b0b5c635a4f83832c 100644 (file)
 
 Файл `main.py`:
 
-{* ../../docs_src/async_tests/main.py *}
+{* ../../docs_src/async_tests/app_a_py39/main.py *}
 
 Файл `test_main.py` содержит тесты для `main.py`, теперь он может выглядеть так:
 
-{* ../../docs_src/async_tests/test_main.py *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py *}
 
 ## Запуск тестов { #run-it }
 
@@ -56,7 +56,7 @@ $ pytest
 
 Маркер `@pytest.mark.anyio` говорит pytest, что тестовая функция должна быть вызвана асинхронно:
 
-{* ../../docs_src/async_tests/test_main.py hl[7] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[7] *}
 
 /// tip | Подсказка
 
@@ -66,7 +66,7 @@ $ pytest
 
 Затем мы можем создать `AsyncClient` со ссылкой на приложение и посылать асинхронные запросы, используя `await`.
 
-{* ../../docs_src/async_tests/test_main.py hl[9:12] *}
+{* ../../docs_src/async_tests/app_a_py39/test_main.py hl[9:12] *}
 
 Это эквивалентно следующему:
 
index 7119efe2dc18bd778a87632ffcaed9c44c815d6f..f78da01a095249224a929a52131d185de6cd9f61 100644 (file)
@@ -44,7 +44,7 @@ $ fastapi run --forwarded-allow-ips="*"
 
 Например, вы объявили операцию пути `/items/`:
 
-{* ../../docs_src/behind_a_proxy/tutorial001_01.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_01_py39.py hl[6] *}
 
 Если клиент обратится к `/items`, по умолчанию произойдёт редирект на `/items/`.
 
@@ -115,7 +115,7 @@ sequenceDiagram
 
 Хотя весь ваш код написан с расчётом, что путь один — `/app`.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[6] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[6] *}
 
 Прокси будет «обрезать» префикс пути на лету перед передачей запроса на сервер приложения (скорее всего Uvicorn, запущенный через FastAPI CLI), поддерживая у вашего приложения иллюзию, что его обслуживают по `/app`, чтобы вам не пришлось менять весь код и добавлять префикс `/api/v1`.
 
@@ -193,7 +193,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Здесь мы добавляем его в сообщение лишь для демонстрации.
 
-{* ../../docs_src/behind_a_proxy/tutorial001.py hl[8] *}
+{* ../../docs_src/behind_a_proxy/tutorial001_py39.py hl[8] *}
 
 Затем, если вы запустите Uvicorn так:
 
@@ -220,7 +220,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Если нет возможности передать опцию командной строки `--root-path` (или аналог), вы можете указать параметр `root_path` при создании приложения FastAPI:
 
-{* ../../docs_src/behind_a_proxy/tutorial002.py hl[3] *}
+{* ../../docs_src/behind_a_proxy/tutorial002_py39.py hl[3] *}
 
 Передача `root_path` в `FastAPI` эквивалентна опции командной строки `--root-path` для Uvicorn или Hypercorn.
 
@@ -400,7 +400,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Например:
 
-{* ../../docs_src/behind_a_proxy/tutorial003.py hl[4:7] *}
+{* ../../docs_src/behind_a_proxy/tutorial003_py39.py hl[4:7] *}
 
 Будет сгенерирована схема OpenAPI примерно такая:
 
@@ -455,7 +455,7 @@ $ fastapi run main.py --forwarded-allow-ips="*" --root-path /api/v1
 
 Если вы не хотите, чтобы FastAPI добавлял автоматический сервер, используя `root_path`, укажите параметр `root_path_in_servers=False`:
 
-{* ../../docs_src/behind_a_proxy/tutorial004.py hl[9] *}
+{* ../../docs_src/behind_a_proxy/tutorial004_py39.py hl[9] *}
 
 и тогда этот сервер не будет добавлен в схему OpenAPI.
 
index 2c238bd95bbb1a586e4dd59647a2f99061cdf763..49550b49ffa048208e23d84191282e41ac9ef715 100644 (file)
@@ -30,7 +30,7 @@
 
 Но если вы уверены, что содержимое, которое вы возвращаете, **сериализуемо в JSON**, вы можете передать его напрямую в класс ответа и избежать дополнительных накладных расходов, которые FastAPI понёс бы, пропуская возвращаемое содержимое через `jsonable_encoder` перед передачей в класс ответа.
 
-{* ../../docs_src/custom_response/tutorial001b.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001b_py39.py hl[2,7] *}
 
 /// info | Информация
 
@@ -55,7 +55,7 @@
 - Импортируйте `HTMLResponse`.
 - Передайте `HTMLResponse` в параметр `response_class` вашего декоратора операции пути.
 
-{* ../../docs_src/custom_response/tutorial002.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial002_py39.py hl[2,7] *}
 
 /// info | Информация
 
@@ -73,7 +73,7 @@
 
 Тот же пример сверху, возвращающий `HTMLResponse`, может выглядеть так:
 
-{* ../../docs_src/custom_response/tutorial003.py hl[2,7,19] *}
+{* ../../docs_src/custom_response/tutorial003_py39.py hl[2,7,19] *}
 
 /// warning | Предупреждение
 
@@ -97,7 +97,7 @@
 
 Например, это может быть что-то вроде:
 
-{* ../../docs_src/custom_response/tutorial004.py hl[7,21,23] *}
+{* ../../docs_src/custom_response/tutorial004_py39.py hl[7,21,23] *}
 
 В этом примере функция `generate_html_response()` уже генерирует и возвращает `Response` вместо возврата HTML в `str`.
 
 
 FastAPI (фактически Starlette) автоматически добавит заголовок Content-Length. Также будет добавлен заголовок Content-Type, основанный на `media_type` и с добавлением charset для текстовых типов.
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ### `HTMLResponse` { #htmlresponse }
 
@@ -146,7 +146,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 Принимает текст или байты и возвращает ответ в виде простого текста.
 
-{* ../../docs_src/custom_response/tutorial005.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial005_py39.py hl[2,7,9] *}
 
 ### `JSONResponse` { #jsonresponse }
 
@@ -180,7 +180,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 ///
 
-{* ../../docs_src/custom_response/tutorial001.py hl[2,7] *}
+{* ../../docs_src/custom_response/tutorial001_py39.py hl[2,7] *}
 
 /// tip | Совет
 
@@ -194,13 +194,13 @@ FastAPI (фактически Starlette) автоматически добави
 
 Вы можете вернуть `RedirectResponse` напрямую:
 
-{* ../../docs_src/custom_response/tutorial006.py hl[2,9] *}
+{* ../../docs_src/custom_response/tutorial006_py39.py hl[2,9] *}
 
 ---
 
 Или можно использовать его в параметре `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006b.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006b_py39.py hl[2,7,9] *}
 
 Если вы сделаете так, то сможете возвращать URL напрямую из своей функции-обработчика пути.
 
@@ -210,13 +210,13 @@ FastAPI (фактически Starlette) автоматически добави
 
 Также вы можете использовать параметр `status_code` в сочетании с параметром `response_class`:
 
-{* ../../docs_src/custom_response/tutorial006c.py hl[2,7,9] *}
+{* ../../docs_src/custom_response/tutorial006c_py39.py hl[2,7,9] *}
 
 ### `StreamingResponse` { #streamingresponse }
 
 Принимает асинхронный генератор или обычный генератор/итератор и отправляет тело ответа потоково.
 
-{* ../../docs_src/custom_response/tutorial007.py hl[2,14] *}
+{* ../../docs_src/custom_response/tutorial007_py39.py hl[2,14] *}
 
 #### Использование `StreamingResponse` с файлоподобными объектами { #using-streamingresponse-with-file-like-objects }
 
@@ -226,7 +226,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 Это включает многие библиотеки для работы с облачным хранилищем, обработки видео и т.д.
 
-{* ../../docs_src/custom_response/tutorial008.py hl[2,10:12,14] *}
+{* ../../docs_src/custom_response/tutorial008_py39.py hl[2,10:12,14] *}
 
 1. Это функция-генератор. Она является «функцией-генератором», потому что содержит оператор(ы) `yield` внутри.
 2. Используя блок `with`, мы гарантируем, что файлоподобный объект будет закрыт после завершения работы функции-генератора. То есть после того, как она закончит отправку ответа.
@@ -255,11 +255,11 @@ FastAPI (фактически Starlette) автоматически добави
 
 Файловые ответы будут содержать соответствующие заголовки `Content-Length`, `Last-Modified` и `ETag`.
 
-{* ../../docs_src/custom_response/tutorial009.py hl[2,10] *}
+{* ../../docs_src/custom_response/tutorial009_py39.py hl[2,10] *}
 
 Вы также можете использовать параметр `response_class`:
 
-{* ../../docs_src/custom_response/tutorial009b.py hl[2,8,10] *}
+{* ../../docs_src/custom_response/tutorial009b_py39.py hl[2,8,10] *}
 
 В этом случае вы можете возвращать путь к файлу напрямую из своей функции-обработчика пути.
 
@@ -273,7 +273,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 Вы могли бы создать `CustomORJSONResponse`. Главное, что вам нужно сделать — реализовать метод `Response.render(content)`, который возвращает содержимое как `bytes`:
 
-{* ../../docs_src/custom_response/tutorial009c.py hl[9:14,17] *}
+{* ../../docs_src/custom_response/tutorial009c_py39.py hl[9:14,17] *}
 
 Теперь вместо того, чтобы возвращать:
 
@@ -299,7 +299,7 @@ FastAPI (фактически Starlette) автоматически добави
 
 В примере ниже **FastAPI** будет использовать `ORJSONResponse` по умолчанию во всех операциях пути вместо `JSONResponse`.
 
-{* ../../docs_src/custom_response/tutorial010.py hl[2,4] *}
+{* ../../docs_src/custom_response/tutorial010_py39.py hl[2,4] *}
 
 /// tip | Совет
 
index 20d1df98a98668f305e5f269eeaa60ca28a34921..db73d9094ec119de2a5509aff60ebdc568e84a02 100644 (file)
@@ -30,7 +30,7 @@
 
 Мы создаём асинхронную функцию `lifespan()` с `yield` примерно так:
 
-{* ../../docs_src/events/tutorial003.py hl[16,19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[16,19] *}
 
 Здесь мы симулируем дорогую операцию startup по загрузке модели, помещая (фиктивную) функцию модели в словарь с моделями Машинного обучения до `yield`. Этот код будет выполнен до того, как приложение начнет принимать запросы, во время startup.
 
@@ -48,7 +48,7 @@
 
 Первое, на что стоит обратить внимание, — мы определяем асинхронную функцию с `yield`. Это очень похоже на Зависимости с `yield`.
 
-{* ../../docs_src/events/tutorial003.py hl[14:19] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[14:19] *}
 
 Первая часть функции, до `yield`, будет выполнена до запуска приложения.
 
@@ -60,7 +60,7 @@
 
 Это превращает функцию в «асинхронный менеджер контекста».
 
-{* ../../docs_src/events/tutorial003.py hl[1,13] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[1,13] *}
 
 Менеджер контекста в Python — это то, что можно использовать в операторе `with`. Например, `open()` можно использовать как менеджер контекста:
 
@@ -82,7 +82,7 @@ async with lifespan(app):
 
 Параметр `lifespan` приложения `FastAPI` принимает асинхронный менеджер контекста, поэтому мы можем передать ему наш новый асинхронный менеджер контекста `lifespan`.
 
-{* ../../docs_src/events/tutorial003.py hl[22] *}
+{* ../../docs_src/events/tutorial003_py39.py hl[22] *}
 
 ## Альтернативные события (устаревшие) { #alternative-events-deprecated }
 
@@ -104,7 +104,7 @@ async with lifespan(app):
 
 Чтобы добавить функцию, которую нужно запустить до старта приложения, объявите её как обработчик события `"startup"`:
 
-{* ../../docs_src/events/tutorial001.py hl[8] *}
+{* ../../docs_src/events/tutorial001_py39.py hl[8] *}
 
 В этом случае функция-обработчик события `startup` инициализирует «базу данных» items (это просто `dict`) некоторыми значениями.
 
@@ -116,7 +116,7 @@ async with lifespan(app):
 
 Чтобы добавить функцию, которую нужно запустить при завершении работы приложения, объявите её как обработчик события `"shutdown"`:
 
-{* ../../docs_src/events/tutorial002.py hl[6] *}
+{* ../../docs_src/events/tutorial002_py39.py hl[6] *}
 
 Здесь функция-обработчик события `shutdown` запишет строку текста `"Application shutdown"` в файл `log.txt`.
 
index ee52412c6d48522a9815186e1ee8944a38a1ce44..00bdd31fe8e720456736d10b3022ad6fba129951 100644 (file)
@@ -167,7 +167,7 @@ FastAPI использует **уникальный ID** для каждой *о
 
 Мы можем скачать OpenAPI JSON в файл `openapi.json`, а затем **убрать этот префикс‑тег** таким скриптом:
 
-{* ../../docs_src/generate_clients/tutorial004.py *}
+{* ../../docs_src/generate_clients/tutorial004_py39.py *}
 
 //// tab | Node.js
 
index 82c86b2317623108bc1f919afea0d63c5bb772f8..5ebe010782d0fc955c1fbd6d1e7a23b881088701 100644 (file)
@@ -57,13 +57,13 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
 
 Любой входящий запрос по `http` или `ws` будет перенаправлен на безопасную схему.
 
-{* ../../docs_src/advanced_middleware/tutorial001.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial001_py39.py hl[2,6] *}
 
 ## `TrustedHostMiddleware` { #trustedhostmiddleware }
 
 Гарантирует, что во всех входящих запросах корректно установлен `Host`‑заголовок, чтобы защититься от атак на HTTP‑заголовок Host.
 
-{* ../../docs_src/advanced_middleware/tutorial002.py hl[2,6:8] *}
+{* ../../docs_src/advanced_middleware/tutorial002_py39.py hl[2,6:8] *}
 
 Поддерживаются следующие аргументы:
 
@@ -78,7 +78,7 @@ app.add_middleware(UnicornMiddleware, some_config="rainbow")
 
 Это middleware обрабатывает как обычные, так и потоковые ответы.
 
-{* ../../docs_src/advanced_middleware/tutorial003.py hl[2,6] *}
+{* ../../docs_src/advanced_middleware/tutorial003_py39.py hl[2,6] *}
 
 Поддерживаются следующие аргументы:
 
index d38cf315f7f13730847a9df9b8fad7ac7be7894b..3a2b9fff7464fcba7951b94732c4bcf24fc400e0 100644 (file)
@@ -32,7 +32,7 @@
 
 При создании приложения на **FastAPI** есть атрибут `webhooks`, с помощью которого можно объявлять вебхуки так же, как вы объявляете операции пути (обработчики пути), например с `@app.webhooks.post()`.
 
-{* ../../docs_src/openapi_webhooks/tutorial001.py hl[9:13,36:53] *}
+{* ../../docs_src/openapi_webhooks/tutorial001_py39.py hl[9:13,36:53] *}
 
 Определенные вами вебхуки попадут в схему **OpenAPI** и в автоматический **интерфейс документации**.
 
index 78a16a5583f54398a018eac313535aefc9262cc8..eaf9ad0528785812c25943051cc8bdea15191999 100644 (file)
@@ -12,7 +12,7 @@
 
 Нужно убедиться, что он уникален для каждой операции.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial001.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial001_py39.py hl[6] *}
 
 ### Использование имени функции-обработчика пути как operationId { #using-the-path-operation-function-name-as-the-operationid }
 
@@ -20,7 +20,7 @@
 
 Делать это следует после добавления всех *операций пути*.
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial002.py hl[2, 12:21, 24] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial002_py39.py hl[2, 12:21, 24] *}
 
 /// tip | Совет
 
@@ -40,7 +40,7 @@
 
 Чтобы исключить *операцию пути* из генерируемой схемы OpenAPI (а значит, и из автоматической документации), используйте параметр `include_in_schema` и установите его в `False`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial003.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial003_py39.py hl[6] *}
 
 ## Расширенное описание из docstring { #advanced-description-from-docstring }
 
@@ -92,7 +92,7 @@
 
 `openapi_extra` может пригодиться, например, чтобы объявить [Расширения OpenAPI](https://github.com/OAI/OpenAPI-Specification/blob/main/versions/3.0.3.md#specificationExtensions):
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial005.py hl[6] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial005_py39.py hl[6] *}
 
 Если вы откроете автоматическую документацию API, ваше расширение появится внизу страницы конкретной *операции пути*.
 
 
 Это можно сделать с помощью `openapi_extra`:
 
-{* ../../docs_src/path_operation_advanced_configuration/tutorial006.py hl[19:36, 39:40] *}
+{* ../../docs_src/path_operation_advanced_configuration/tutorial006_py39.py hl[19:36, 39:40] *}
 
 В этом примере мы не объявляли никакую Pydantic-модель. Фактически тело запроса даже не <abbr title="преобразовано из простого формата, например байтов, в объекты Python">распарсено</abbr> как JSON, оно читается напрямую как `bytes`, а функция `magic_data_reader()` будет отвечать за его парсинг каким-то способом.
 
index e9e1c9470f47a8286b0424f17ea3084395862ff6..85d9050ffc5c557e15b637b33c962e9329979124 100644 (file)
@@ -20,7 +20,7 @@
 
 И затем вы можете установить `status_code` в этом *временном* объекте ответа.
 
-{* ../../docs_src/response_change_status_code/tutorial001.py hl[1,9,12] *}
+{* ../../docs_src/response_change_status_code/tutorial001_py39.py hl[1,9,12] *}
 
 После этого вы можете вернуть любой объект, который вам нужен, как обычно (`dict`, модель базы данных и т.д.).
 
index 9319aba6e207fd98435dd12f2bce2dd6612b5060..2872d6c0ade52085b701a8986b49dec7be94d1df 100644 (file)
@@ -6,7 +6,7 @@
 
 Затем установить cookies в этом временном объекте ответа.
 
-{* ../../docs_src/response_cookies/tutorial002.py hl[1, 8:9] *}
+{* ../../docs_src/response_cookies/tutorial002_py39.py hl[1, 8:9] *}
 
 После этого можно вернуть любой объект, как и раньше (например, `dict`, объект модели базы данных и так далее).
 
@@ -24,7 +24,7 @@
 
 Затем установите cookies и верните этот объект:
 
-{* ../../docs_src/response_cookies/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_cookies/tutorial001_py39.py hl[10:12] *}
 
 /// tip | Совет
 
index 3c10633e91249a0a189a8953ba7cdd4aa70b5fe7..b452810714739dee486769875a2122391a974c78 100644 (file)
@@ -54,7 +54,7 @@
 
 Вы можете поместить ваш XML-контент в строку, поместить её в `Response` и вернуть:
 
-{* ../../docs_src/response_directly/tutorial002.py hl[1,18] *}
+{* ../../docs_src/response_directly/tutorial002_py39.py hl[1,18] *}
 
 ## Примечания { #notes }
 
index 1c9360b31dbbb86f1f679c5ae182517fa5c55887..8f24f05b0789389d1e1b960efb0c0f72b9968e58 100644 (file)
@@ -6,7 +6,7 @@
 
 А затем вы можете устанавливать HTTP-заголовки в этом *временном* объекте ответа.
 
-{* ../../docs_src/response_headers/tutorial002.py hl[1, 7:8] *}
+{* ../../docs_src/response_headers/tutorial002_py39.py hl[1, 7:8] *}
 
 После этого вы можете вернуть любой нужный объект, как обычно (например, `dict`, модель из базы данных и т.д.).
 
@@ -22,7 +22,7 @@
 
 Создайте ответ, как описано в [Вернуть Response напрямую](response-directly.md){.internal-link target=_blank}, и передайте заголовки как дополнительный параметр:
 
-{* ../../docs_src/response_headers/tutorial001.py hl[10:12] *}
+{* ../../docs_src/response_headers/tutorial001_py39.py hl[10:12] *}
 
 /// note | Технические детали
 
index 0ef46fb13c17e4e442a20d5dec789e45b0dfbb88..b96ee44a3a1b63b661284b6b17644ce4aa1b7e19 100644 (file)
@@ -62,7 +62,7 @@ $ pip install "fastapi[all]"
 
 //// tab | Pydantic v2
 
-{* ../../docs_src/settings/tutorial001.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -74,7 +74,7 @@ $ pip install "fastapi[all]"
 
 ///
 
-{* ../../docs_src/settings/tutorial001_pv1.py hl[2,5:8,11] *}
+{* ../../docs_src/settings/tutorial001_pv1_py39.py hl[2,5:8,11] *}
 
 ////
 
@@ -92,7 +92,7 @@ $ pip install "fastapi[all]"
 
 Затем вы можете использовать новый объект `settings` в вашем приложении:
 
-{* ../../docs_src/settings/tutorial001.py hl[18:20] *}
+{* ../../docs_src/settings/tutorial001_py39.py hl[18:20] *}
 
 ### Запуск сервера { #run-the-server }
 
@@ -126,11 +126,11 @@ $ ADMIN_EMAIL="deadpool@example.com" APP_NAME="ChimichangApp" fastapi run main.p
 
 Например, у вас может быть файл `config.py` со следующим содержимым:
 
-{* ../../docs_src/settings/app01/config.py *}
+{* ../../docs_src/settings/app01_py39/config.py *}
 
 А затем использовать его в файле `main.py`:
 
-{* ../../docs_src/settings/app01/main.py hl[3,11:13] *}
+{* ../../docs_src/settings/app01_py39/main.py hl[3,11:13] *}
 
 /// tip | Совет
 
index 3464f170408c6dc4611d75cbccc7a6c52c7a7903..fa5a683f45f0c00fb3fdb308511fb607e907ea4e 100644 (file)
@@ -10,7 +10,7 @@
 
 Сначала создайте основное, верхнего уровня, приложение **FastAPI** и его *операции пути*:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[3, 6:8] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[3, 6:8] *}
 
 ### Подприложение { #sub-application }
 
@@ -18,7 +18,7 @@
 
 Это подприложение — обычное стандартное приложение FastAPI, но именно оно будет «смонтировано»:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 14:16] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 14:16] *}
 
 ### Смонтируйте подприложение { #mount-the-sub-application }
 
@@ -26,7 +26,7 @@
 
 В этом случае оно будет смонтировано по пути `/subapi`:
 
-{* ../../docs_src/sub_applications/tutorial001.py hl[11, 19] *}
+{* ../../docs_src/sub_applications/tutorial001_py39.py hl[11, 19] *}
 
 ### Проверьте автоматическую документацию API { #check-the-automatic-api-docs }
 
index 204e8876053436f93d0188d4ad67ff7ea9dcf3d2..460e2e4660ebd4f01eff4fb36c247f7dbe825411 100644 (file)
@@ -27,7 +27,7 @@ $ pip install jinja2
 - Объявите параметр `Request` в *операции пути*, которая будет возвращать шаблон.
 - Используйте созданный `templates`, чтобы отрендерить и вернуть `TemplateResponse`; передайте имя шаблона, объект `request` и словарь «context» с парами ключ-значение для использования внутри шаблона Jinja2.
 
-{* ../../docs_src/templates/tutorial001.py hl[4,11,15:18] *}
+{* ../../docs_src/templates/tutorial001_py39.py hl[4,11,15:18] *}
 
 /// note | Примечание
 
index e0ec7743994348df1768cd14a5c7fcc16779a95d..82caea845b8a49a8ad29b14d7ff9d623f803b7dd 100644 (file)
@@ -2,11 +2,11 @@
 
 Если вам нужно, чтобы `lifespan` выполнялся в ваших тестах, вы можете использовать `TestClient` вместе с оператором `with`:
 
-{* ../../docs_src/app_testing/tutorial004.py hl[9:15,18,27:28,30:32,41:43] *}
+{* ../../docs_src/app_testing/tutorial004_py39.py hl[9:15,18,27:28,30:32,41:43] *}
 
 
 Вы можете узнать больше подробностей в статье [Запуск lifespan в тестах на официальном сайте документации Starlette.](https://www.starlette.dev/lifespan/#running-lifespan-in-tests)
 
 Для устаревших событий `startup` и `shutdown` вы можете использовать `TestClient` следующим образом:
 
-{* ../../docs_src/app_testing/tutorial003.py hl[9:12,20:24] *}
+{* ../../docs_src/app_testing/tutorial003_py39.py hl[9:12,20:24] *}
index e840a03f28b32587cfd2d7a43f039987a94cde98..b6626679e4b05e9ff502dea307c9361ebb805917 100644 (file)
@@ -4,7 +4,7 @@
 
 Для этого используйте `TestClient` с менеджером контекста `with`, подключаясь к WebSocket:
 
-{* ../../docs_src/app_testing/tutorial002.py hl[27:31] *}
+{* ../../docs_src/app_testing/tutorial002_py39.py hl[27:31] *}
 
 /// note | Примечание
 
index b922216105de86e687bef133d2fa4a422a5fa549..cdf500c0e2c8c50da5e86b5993f02e770fcd0d4a 100644 (file)
@@ -29,7 +29,7 @@
 
 Для этого нужно обратиться к запросу напрямую.
 
-{* ../../docs_src/using_request_directly/tutorial001.py hl[1,7:8] *}
+{* ../../docs_src/using_request_directly/tutorial001_py39.py hl[1,7:8] *}
 
 Если объявить параметр *функции-обработчика пути* с типом `Request`, **FastAPI** поймёт, что нужно передать объект `Request` в этот параметр.
 
index f26185bea5c4e128056338203cd65ee7bd6d8ba8..fa5e4738eb69ef62bf00f45d8563023bba79a63d 100644 (file)
@@ -38,13 +38,13 @@ $ pip install websockets
 
 Для примера нам нужен наиболее простой способ, который позволит сосредоточиться на серверной части веб‑сокетов и получить рабочий код:
 
-{* ../../docs_src/websockets/tutorial001.py hl[2,6:38,41:43] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[2,6:38,41:43] *}
 
 ## Создание `websocket` { #create-a-websocket }
 
 Создайте `websocket` в своем **FastAPI** приложении:
 
-{* ../../docs_src/websockets/tutorial001.py hl[1,46:47] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[1,46:47] *}
 
 /// note | Технические детали
 
@@ -58,7 +58,7 @@ $ pip install websockets
 
 Через эндпоинт веб-сокета вы можете получать и отправлять сообщения.
 
-{* ../../docs_src/websockets/tutorial001.py hl[48:52] *}
+{* ../../docs_src/websockets/tutorial001_py39.py hl[48:52] *}
 
 Вы можете получать и отправлять двоичные, текстовые и JSON данные.
 
index 1c5bf0a62630977f6c9f7f9a9cfa5814987724d7..64d7c7a2894c9cf0bae387c11830461300e2dbd4 100644 (file)
@@ -12,7 +12,7 @@
 
 После этого смонтируйте его на путь.
 
-{* ../../docs_src/wsgi/tutorial001.py hl[2:3,3] *}
+{* ../../docs_src/wsgi/tutorial001_py39.py hl[2:3,3] *}
 
 ## Проверьте { #check-it }
 
index dc987ae26b96497d9cbdc5217302e38843b6c423..d0845b91e27420d01f3a520111be9c9924624e37 100644 (file)
@@ -29,7 +29,7 @@
 
 Например:
 
-{* ../../docs_src/conditional_openapi/tutorial001.py hl[6,11] *}
+{* ../../docs_src/conditional_openapi/tutorial001_py39.py hl[6,11] *}
 
 Здесь мы объявляем настройку `openapi_url` с тем же значением по умолчанию — `"/openapi.json"`.
 
index 9d104423d7fd9a666483b0eaef8216f57ac7230d..b3b1c1ba6241e8153946a1c5d5f05bc26802d076 100644 (file)
@@ -18,7 +18,7 @@ FastAPI преобразует эти настройки в **JSON**, чтобы
 
 Но вы можете отключить её, установив `syntaxHighlight` в `False`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial001.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial001_py39.py hl[3] *}
 
 …и после этого Swagger UI больше не будет показывать подсветку синтаксиса:
 
@@ -28,7 +28,7 @@ FastAPI преобразует эти настройки в **JSON**, чтобы
 
 Аналогично вы можете задать тему подсветки синтаксиса с ключом "syntaxHighlight.theme" (обратите внимание, что посередине стоит точка):
 
-{* ../../docs_src/configure_swagger_ui/tutorial002.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial002_py39.py hl[3] *}
 
 Эта настройка изменит цветовую тему подсветки синтаксиса:
 
@@ -46,7 +46,7 @@ FastAPI включает некоторые параметры конфигур
 
 Например, чтобы отключить `deepLinking`, можно передать такие настройки в `swagger_ui_parameters`:
 
-{* ../../docs_src/configure_swagger_ui/tutorial003.py hl[3] *}
+{* ../../docs_src/configure_swagger_ui/tutorial003_py39.py hl[3] *}
 
 ## Другие параметры Swagger UI { #other-swagger-ui-parameters }
 
index c07a9695b95451164203926bd729b78e984d4f1d..f524911e65129c6f435a5cded5713f891148fa5c 100644 (file)
@@ -18,7 +18,7 @@
 
 Чтобы отключить её, установите их URL в значение `None` при создании вашего приложения `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[8] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[8] *}
 
 ### Подключить пользовательскую документацию { #include-the-custom-docs }
 
@@ -34,7 +34,7 @@
 
 Аналогично и для ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[2:6,11:19,22:24,27:33] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[2:6,11:19,22:24,27:33] *}
 
 /// tip | Совет
 
@@ -50,7 +50,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Чтобы убедиться, что всё работает, создайте *операцию пути*:
 
-{* ../../docs_src/custom_docs_ui/tutorial001.py hl[36:38] *}
+{* ../../docs_src/custom_docs_ui/tutorial001_py39.py hl[36:38] *}
 
 ### Тестирование { #test-it }
 
@@ -118,7 +118,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 * Импортируйте `StaticFiles`.
 * Смонтируйте экземпляр `StaticFiles()` в определённый путь.
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[7,11] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[7,11] *}
 
 ### Протестируйте статические файлы { #test-the-static-files }
 
@@ -144,7 +144,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Чтобы отключить её, установите их URL в значение `None` при создании вашего приложения `FastAPI`:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[9] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[9] *}
 
 ### Подключить пользовательскую документацию со статическими файлами { #include-the-custom-docs-for-static-files }
 
@@ -160,7 +160,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Аналогично и для ReDoc...
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[2:6,14:22,25:27,30:36] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[2:6,14:22,25:27,30:36] *}
 
 /// tip | Совет
 
@@ -176,7 +176,7 @@ Swagger UI сделает это за вас «за кулисами», но д
 
 Чтобы убедиться, что всё работает, создайте *операцию пути*:
 
-{* ../../docs_src/custom_docs_ui/tutorial002.py hl[39:41] *}
+{* ../../docs_src/custom_docs_ui/tutorial002_py39.py hl[39:41] *}
 
 ### Тестирование UI со статическими файлами { #test-static-files-ui }
 
index 2897fb89bad9a95b54a175ca9ad035b7d2c0279b..1d69cbdb3a9c43baf2b4a1ab115226a66ef71581 100644 (file)
 
 Сначала напишите приложение **FastAPI** как обычно:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[1,4,7:9] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[1,4,7:9] *}
 
 ### Сгенерируйте схему OpenAPI { #generate-the-openapi-schema }
 
 Затем используйте ту же вспомогательную функцию для генерации схемы OpenAPI внутри функции `custom_openapi()`:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[2,15:21] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[2,15:21] *}
 
 ### Измените схему OpenAPI { #modify-the-openapi-schema }
 
 Теперь можно добавить расширение ReDoc, добавив кастомный `x-logo` в «объект» `info` в схеме OpenAPI:
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[22:24] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[22:24] *}
 
 ### Кэшируйте схему OpenAPI { #cache-the-openapi-schema }
 
 
 Она будет создана один раз, а затем тот же кэшированный вариант будет использоваться для последующих запросов.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[13:14,25:26] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[13:14,25:26] *}
 
 ### Переопределите метод { #override-the-method }
 
 Теперь вы можете заменить метод `.openapi()` на вашу новую функцию.
 
-{* ../../docs_src/extending_openapi/tutorial001.py hl[29] *}
+{* ../../docs_src/extending_openapi/tutorial001_py39.py hl[29] *}
 
 ### Проверьте { #check-it }
 
index 9ed6d95ca12af656baf688bc8c79cbba12453aa7..97278069ad642147a26885224b8587dcb8b9f008 100644 (file)
@@ -35,7 +35,7 @@
 
 Вот небольшой пример того, как можно интегрировать Strawberry с FastAPI:
 
-{* ../../docs_src/graphql/tutorial001.py hl[3,22,25] *}
+{* ../../docs_src/graphql/tutorial001_py39.py hl[3,22,25] *}
 
 Подробнее о Strawberry можно узнать в <a href="https://strawberry.rocks/" class="external-link" target="_blank">документации Strawberry</a>.
 
index 84a901f547c659eabbecce44a0afa4b20def4250..ae4a1e2b79c519a6931a3cff6a0cc99f1fe99d9b 100644 (file)
@@ -22,7 +22,7 @@ Python поддерживает необязательные «подсказк
 
 Давайте начнем с простого примера:
 
-{* ../../docs_src/python_types/tutorial001.py *}
+{* ../../docs_src/python_types/tutorial001_py39.py *}
 
 Вызов этой программы выводит:
 
@@ -36,7 +36,7 @@ John Doe
 * Преобразует первую букву каждого значения в верхний регистр с помощью `title()`.
 * <abbr title="Объединяет в одно целое. Содержимое одного — сразу после другого.">Соединяет</abbr> их пробелом посередине.
 
-{* ../../docs_src/python_types/tutorial001.py hl[2] *}
+{* ../../docs_src/python_types/tutorial001_py39.py hl[2] *}
 
 ### Отредактируем пример { #edit-it }
 
@@ -78,7 +78,7 @@ John Doe
 
 Это и есть «подсказки типов»:
 
-{* ../../docs_src/python_types/tutorial002.py hl[1] *}
+{* ../../docs_src/python_types/tutorial002_py39.py hl[1] *}
 
 Это не то же самое, что объявление значений по умолчанию, как, например:
 
@@ -106,7 +106,7 @@ John Doe
 
 Посмотрите на эту функцию — у неё уже есть подсказки типов:
 
-{* ../../docs_src/python_types/tutorial003.py hl[1] *}
+{* ../../docs_src/python_types/tutorial003_py39.py hl[1] *}
 
 Так как редактор кода знает типы переменных, вы получаете не только автозавершение, но и проверки ошибок:
 
@@ -114,7 +114,7 @@ John Doe
 
 Теперь вы знаете, что нужно исправить — преобразовать `age` в строку с помощью `str(age)`:
 
-{* ../../docs_src/python_types/tutorial004.py hl[2] *}
+{* ../../docs_src/python_types/tutorial004_py39.py hl[2] *}
 
 ## Объявление типов { #declaring-types }
 
@@ -133,7 +133,7 @@ John Doe
 * `bool`
 * `bytes`
 
-{* ../../docs_src/python_types/tutorial005.py hl[1] *}
+{* ../../docs_src/python_types/tutorial005_py39.py hl[1] *}
 
 ### Generic-типы с параметрами типов { #generic-types-with-type-parameters }
 
@@ -161,56 +161,24 @@ John Doe
 
 Например, давайте определим переменную как `list` из `str`.
 
-//// tab | Python 3.9+
-
 Объявите переменную с тем же синтаксисом двоеточия (`:`).
 
 В качестве типа укажите `list`.
 
 Так как список — это тип, содержащий внутренние типы, укажите их в квадратных скобках:
 
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-Из `typing` импортируйте `List` (с заглавной `L`):
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-Объявите переменную с тем же синтаксисом двоеточия (`:`).
-
-В качестве типа используйте `List`, который вы импортировали из `typing`.
-
-Так как список — это тип, содержащий внутренние типы, укажите их в квадратных скобках:
-
-```Python hl_lines="4"
-{!> ../../docs_src/python_types/tutorial006.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial006_py39.py hl[1] *}
 
 /// info | Информация
 
 Эти внутренние типы в квадратных скобках называются «параметрами типов».
 
-В данном случае `str` — это параметр типа, передаваемый в `List` (или `list` в Python 3.9 и выше).
+В данном случае `str` — это параметр типа, передаваемый в `list`.
 
 ///
 
 Это означает: «переменная `items` — это `list`, и каждый элемент этого списка — `str`».
 
-/// tip | Совет
-
-Если вы используете Python 3.9 или выше, вам не нужно импортировать `List` из `typing`, можно использовать обычный встроенный тип `list`.
-
-///
-
 Таким образом, ваш редактор кода сможет помогать даже при обработке элементов списка:
 
 <img src="/img/python-types/image05.png">
@@ -225,21 +193,7 @@ John Doe
 
 Аналогично вы бы объявили `tuple` и `set`:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial007_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial007.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial007_py39.py hl[1] *}
 
 Это означает:
 
@@ -254,21 +208,7 @@ John Doe
 
 Второй параметр типа — для значений `dict`:
 
-//// tab | Python 3.9+
-
-```Python hl_lines="1"
-{!> ../../docs_src/python_types/tutorial008_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial008_py39.py hl[1] *}
 
 Это означает:
 
@@ -292,10 +232,10 @@ John Doe
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial008b.py!}
+{!> ../../docs_src/python_types/tutorial008b_py39.py!}
 ```
 
 ////
@@ -309,7 +249,7 @@ John Doe
 В Python 3.6 и выше (включая Python 3.10) это можно объявить, импортировав и используя `Optional` из модуля `typing`.
 
 ```Python hl_lines="1  4"
-{!../../docs_src/python_types/tutorial009.py!}
+{!../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 Использование `Optional[str]` вместо просто `str` позволит редактору кода помочь вам обнаружить ошибки, когда вы предполагаете, что значение всегда `str`, хотя на самом деле оно может быть и `None`.
@@ -326,18 +266,18 @@ John Doe
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009.py!}
+{!> ../../docs_src/python_types/tutorial009_py39.py!}
 ```
 
 ////
 
-//// tab | Python 3.8+ альтернативный вариант
+//// tab | Python 3.9+ альтернативный вариант
 
 ```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial009b.py!}
+{!> ../../docs_src/python_types/tutorial009b_py39.py!}
 ```
 
 ////
@@ -357,7 +297,7 @@ John Doe
 
 В качестве примера возьмём эту функцию:
 
-{* ../../docs_src/python_types/tutorial009c.py hl[1,4] *}
+{* ../../docs_src/python_types/tutorial009c_py39.py hl[1,4] *}
 
 Параметр `name` определён как `Optional[str]`, но он **не необязательный** — вы не можете вызвать функцию без этого параметра:
 
@@ -390,10 +330,10 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 * `set`
 * `dict`
 
-И, как и в Python 3.8, из модуля `typing`:
+И, как и в предыдущих версиях Python, из модуля `typing`:
 
 * `Union`
-* `Optional` (так же, как в Python 3.8)
+* `Optional`
 * ...и другие.
 
 В Python 3.10, как альтернативу generics `Union` и `Optional`, можно использовать <abbr title='также называется «побитовый оператор OR», но это значение здесь нерелевантно'>вертикальную черту (`|`)</abbr> для объявления объединений типов — это гораздо лучше и проще.
@@ -409,7 +349,7 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 * `set`
 * `dict`
 
, как и в Python 3.8, из модуля `typing`:
 generics из модуля `typing`:
 
 * `Union`
 * `Optional`
@@ -417,29 +357,17 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 
 ////
 
-//// tab | Python 3.8+
-
-* `List`
-* `Tuple`
-* `Set`
-* `Dict`
-* `Union`
-* `Optional`
-* ...и другие.
-
-////
-
 ### Классы как типы { #classes-as-types }
 
 Вы также можете объявлять класс как тип переменной.
 
 Допустим, у вас есть класс `Person` с именем:
 
-{* ../../docs_src/python_types/tutorial010.py hl[1:3] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[1:3] *}
 
 Тогда вы можете объявить переменную типа `Person`:
 
-{* ../../docs_src/python_types/tutorial010.py hl[6] *}
+{* ../../docs_src/python_types/tutorial010_py39.py hl[6] *}
 
 И снова вы получите полную поддержку редактора кода:
 
@@ -463,29 +391,7 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 
 Пример из официальной документации Pydantic:
 
-//// tab | Python 3.10+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py310.py!}
-```
-
-////
-
-//// tab | Python 3.9+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-```Python
-{!> ../../docs_src/python_types/tutorial011.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial011_py310.py *}
 
 /// info | Информация
 
@@ -507,27 +413,9 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 
 В Python также есть возможность добавлять **дополнительные <abbr title="Данные о данных, в данном случае — информация о типе, например описание.">метаданные</abbr>** к подсказкам типов с помощью `Annotated`.
 
-//// tab | Python 3.9+
-
-В Python 3.9 `Annotated` входит в стандартную библиотеку, поэтому вы можете импортировать его из `typing`.
+Начиная с Python 3.9, `Annotated` входит в стандартную библиотеку, поэтому вы можете импортировать его из `typing`.
 
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013_py39.py!}
-```
-
-////
-
-//// tab | Python 3.8+
-
-В версиях ниже Python 3.9 импортируйте `Annotated` из `typing_extensions`.
-
-Он уже будет установлен вместе с **FastAPI**.
-
-```Python hl_lines="1  4"
-{!> ../../docs_src/python_types/tutorial013.py!}
-```
-
-////
+{* ../../docs_src/python_types/tutorial013_py39.py hl[1,4] *}
 
 Сам Python ничего не делает с `Annotated`. А для редакторов кода и других инструментов тип по-прежнему `str`.
 
@@ -558,7 +446,7 @@ say_hi(name=None)  # Это работает, None допустим 🎉
 
 ...и **FastAPI** использует эти же объявления для:
 
-* **Определения требований**: из path-параметров, query-параметров, HTTP-заголовков, тел запросов, зависимостей и т.д.
+* **Определения требований**: из path-параметров пути запроса, query-параметров, HTTP-заголовков, тел запросов, зависимостей и т.д.
 * **Преобразования данных**: из HTTP-запроса к требуемому типу.
 * **Валидации данных**: приходящих с каждого HTTP-запроса:
     * Генерации **автоматических ошибок**, возвращаемых клиенту, когда данные некорректны.
index 1ed8522d69444edd2843b2283ab73bd9a65811a8..8d7b7442f91d910e8ec4ba94513a42e0f1eb1b26 100644 (file)
@@ -15,7 +15,7 @@
 
 Сначала импортируйте `BackgroundTasks` и объявите параметр в вашей функции‑обработчике пути с типом `BackgroundTasks`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[1,13] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[1,13] *}
 
 **FastAPI** создаст объект типа `BackgroundTasks` для вас и передаст его через этот параметр.
 
 
 Так как операция записи не использует `async` и `await`, мы определим функцию как обычную `def`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[6:9] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[6:9] *}
 
 ## Добавление фоновой задачи { #add-the-background-task }
 
 Внутри вашей функции‑обработчика пути передайте функцию задачи объекту фоновых задач методом `.add_task()`:
 
-{* ../../docs_src/background_tasks/tutorial001.py hl[14] *}
+{* ../../docs_src/background_tasks/tutorial001_py39.py hl[14] *}
 
 `.add_task()` принимает следующие аргументы:
 
index 5bb5abbe6397d9b0dd369dfcdc085d7f1124de1f..4c914b97f0d831d700e7ec26f8e9660b3daf916f 100644 (file)
 
 В Python есть специальный способ объявлять списки с внутренними типами, или «параметрами типа»:
 
-### Импортируйте `List` из модуля typing { #import-typings-list }
-
-В Python 3.9 и выше вы можете использовать стандартный тип `list` для объявления аннотаций типов, как мы увидим ниже. 💡
-
-Но в версиях Python до 3.9 (начиная с 3.6) сначала вам необходимо импортировать `List` из стандартного модуля `typing`:
-
-{* ../../docs_src/body_nested_models/tutorial002.py hl[1] *}
-
 ### Объявите `list` с параметром типа { #declare-a-list-with-a-type-parameter }
 
-Для объявления типов, у которых есть параметры типа (внутренние типы), таких как `list`, `dict`, `tuple`:
-
-* Если у вас Python версии ниже 3.9, импортируйте их аналоги из модуля `typing`
-* Передайте внутренний(ие) тип(ы) как «параметры типа», используя квадратные скобки: `[` и `]`
-
-В Python 3.9 это будет:
+Для объявления типов, у которых есть параметры типа (внутренние типы), таких как `list`, `dict`, `tuple`, передайте внутренний(ие) тип(ы) как «параметры типа», используя квадратные скобки: `[` и `]`
 
 ```Python
 my_list: list[str]
 ```
 
-В версиях Python до 3.9 это будет:
-
-```Python
-from typing import List
-
-my_list: List[str]
-```
-
 Это всё стандартный синтаксис Python для объявления типов.
 
 Используйте этот же стандартный синтаксис для атрибутов модели с внутренними типами.
@@ -107,7 +86,7 @@ my_list: List[str]
 
 Ещё раз: сделав такое объявление, с помощью **FastAPI** вы получите:
 
-* Поддержку редактора кода (автозавершение и т. д.), даже для вложенных моделей
+* Поддержку редактора кода (автозавершение и т.д.), даже для вложенных моделей
 * Преобразование данных
 * Валидацию данных
 * Автоматическую документацию
@@ -178,12 +157,6 @@ my_list: List[str]
 
 Если верхний уровень значения тела JSON-объекта представляет собой JSON `array` (в Python — `list`), вы можете объявить тип в параметре функции, так же как в моделях Pydantic:
 
-```Python
-images: List[Image]
-```
-
-или в Python 3.9 и выше:
-
 ```Python
 images: list[Image]
 ```
index 16ff6466c186edec37356eb9bde9b0bb359884b1..b61f3e7a0968ec400eab1d7a8983be992b040bbb 100644 (file)
@@ -161,7 +161,7 @@ JSON Schema ваших моделей будет частью сгенериро
 
 FastAPI понимает, что значение `q` не является обязательным из-за значения по умолчанию `= None`.
 
-Аннотации типов `str | None` (Python 3.10+) или `Union[str, None]` (Python 3.8+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`.
+Аннотации типов `str | None` (Python 3.10+) или `Union[str, None]` (Python 3.9+) не используются FastAPI для определения обязательности; он узнает, что параметр не обязателен, потому что у него есть значение по умолчанию `= None`.
 
 Но добавление аннотаций типов позволит вашему редактору кода лучше вас поддерживать и обнаруживать ошибки.
 
index b0704351a9b8ea5a8f56bc7bf46da287d561a31b..d09a31e2c3509fd78b33a1cdbed7a7769a2983eb 100644 (file)
@@ -46,7 +46,7 @@
 * Отдельных HTTP-методов (`POST`, `PUT`) или всех вместе, используя `"*"`.
 * Отдельных HTTP-заголовков или всех вместе, используя `"*"`.
 
-{* ../../docs_src/cors/tutorial001.py hl[2,6:11,13:19] *}
+{* ../../docs_src/cors/tutorial001_py39.py hl[2,6:11,13:19] *}
 
 `CORSMiddleware` использует "запрещающие" значения по умолчанию, поэтому вам нужно явным образом разрешить использование отдельных источников, методов или заголовков, чтобы браузеры могли использовать их в кросс-доменном контексте.
 
index a5340af08930e9ba59cb648c8614ac34a6805a55..51955835e6e879a02d7001c055d3ddd35f004321 100644 (file)
@@ -6,7 +6,7 @@
 
 В вашем FastAPI приложении, импортируйте и вызовите `uvicorn` напрямую:
 
-{* ../../docs_src/debugging/tutorial001.py hl[1,15] *}
+{* ../../docs_src/debugging/tutorial001_py39.py hl[1,15] *}
 
 ### Описание `__name__ == "__main__"` { #about-name-main }
 
index ec7770d960cb91f91be6fef6c663b9aa27de9705..a38e885d43f308857d758be8f0b75dd4b6b43e8d 100644 (file)
@@ -101,7 +101,7 @@ fluffy = Cat(name="Mr Fluffy")
 
 Обратите внимание, что в приведенном выше коде мы два раза пишем `CommonQueryParams`:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -109,7 +109,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Подсказка
 
@@ -137,7 +137,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 В этом случае первый `CommonQueryParams`, в:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, ...
@@ -145,7 +145,7 @@ commons: Annotated[CommonQueryParams, ...
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Подсказка
 
@@ -163,7 +163,7 @@ commons: CommonQueryParams ...
 
 На самом деле можно написать просто:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[Any, Depends(CommonQueryParams)]
@@ -171,7 +171,7 @@ commons: Annotated[Any, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Подсказка
 
@@ -197,7 +197,7 @@ commons = Depends(CommonQueryParams)
 
 Но вы видите, что здесь мы имеем некоторое повторение кода, дважды написав `CommonQueryParams`:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -205,7 +205,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Подсказка
 
@@ -225,7 +225,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 Вместо того чтобы писать:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
@@ -233,7 +233,7 @@ commons: Annotated[CommonQueryParams, Depends(CommonQueryParams)]
 
 ////
 
-//// tab | Python 3.8+ non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Подсказка
 
@@ -249,7 +249,7 @@ commons: CommonQueryParams = Depends(CommonQueryParams)
 
 ...следует написать:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 commons: Annotated[CommonQueryParams, Depends()]
@@ -257,7 +257,7 @@ commons: Annotated[CommonQueryParams, Depends()]
 
 ////
 
-//// tab | Python 3.8 non-Annotated
+//// tab | Python 3.9+ non-Annotated
 
 /// tip | Подсказка
 
index 7ff85246dcfd56cdcc92c64fe071ea05dd3eecc8..dc202db616b5be98bdfb3faf2f6a77674e9957cd 100644 (file)
@@ -29,15 +29,15 @@ FastAPI поддерживает зависимости, которые выпо
 
 Перед созданием ответа будет выполнен только код до и включая оператор `yield`:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[2:4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[2:4] *}
 
 Значение, полученное из `yield`, внедряется в *операции пути* и другие зависимости:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[4] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[4] *}
 
 Код, следующий за оператором `yield`, выполняется после ответа:
 
-{* ../../docs_src/dependencies/tutorial007.py hl[5:6] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[5:6] *}
 
 /// tip | Подсказка
 
@@ -57,7 +57,7 @@ FastAPI поддерживает зависимости, которые выпо
 
 Точно так же можно использовать `finally`, чтобы убедиться, что обязательные шаги при выходе выполнены независимо от того, было ли исключение или нет.
 
-{* ../../docs_src/dependencies/tutorial007.py hl[3,5] *}
+{* ../../docs_src/dependencies/tutorial007_py39.py hl[3,5] *}
 
 ## Подзависимости с `yield` { #sub-dependencies-with-yield }
 
@@ -269,7 +269,7 @@ with open("./somefile.txt") as f:
 Их также можно использовать внутри зависимостей **FastAPI** с `yield`, применяя операторы
 `with` или `async with` внутри функции зависимости:
 
-{* ../../docs_src/dependencies/tutorial010.py hl[1:9,13] *}
+{* ../../docs_src/dependencies/tutorial010_py39.py hl[1:9,13] *}
 
 /// tip | Подсказка
 
index 075d6b0baa32662fa1739c8392f03bb1bb601e4b..2347c6dd834741bd98ff1d34e859dddfb856d1e2 100644 (file)
@@ -6,7 +6,7 @@
 
 В этом случае они будут применяться ко всем *операциям пути* в приложении:
 
-{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[16] *}
+{* ../../docs_src/dependencies/tutorial012_an_py39.py hl[17] *}
 
 Все способы [добавления `dependencies` (зависимостей) в *декораторах операций пути*](dependencies-in-path-operation-decorators.md){.internal-link target=_blank} по-прежнему применимы, но в данном случае зависимости применяются ко всем *операциям пути* приложения.
 
index efe8d98c31ceeab5ae9ad275b190f7e390b83f1c..da31a6682f6215c3564857d4c7e53a4a95030471 100644 (file)
@@ -62,7 +62,7 @@ query_extractor --> query_or_cookie_extractor --> read_query
 
 В расширенном сценарии, когда вы знаете, что вам нужно, чтобы зависимость вызывалась на каждом шаге (возможно, несколько раз) в одном и том же запросе, вместо использования "кэшированного" значения, вы можете установить параметр `use_cache=False` при использовании `Depends`:
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python hl_lines="1"
 async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_cache=False)]):
@@ -71,7 +71,7 @@ async def needy_dependency(fresh_value: Annotated[str, Depends(get_value, use_ca
 
 ////
 
-//// tab | Python 3.8+ без Annotated
+//// tab | Python 3.9+ без Annotated
 
 /// tip | Подсказка
 
index 6f59d7205488803a48ba5b463333037056c92033..798c03d5175332aaa76c5aa131b5d0c093f88d2f 100644 (file)
@@ -2,7 +2,7 @@
 
 Самый простой файл FastAPI может выглядеть так:
 
-{* ../../docs_src/first_steps/tutorial001.py *}
+{* ../../docs_src/first_steps/tutorial001_py39.py *}
 
 Скопируйте это в файл `main.py`.
 
@@ -183,7 +183,7 @@ Deploying to FastAPI Cloud...
 
 ### Шаг 1: импортируйте `FastAPI` { #step-1-import-fastapi }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[1] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[1] *}
 
 `FastAPI` — это класс на Python, который предоставляет всю функциональность для вашего API.
 
@@ -197,7 +197,7 @@ Deploying to FastAPI Cloud...
 
 ### Шаг 2: создайте экземпляр `FastAPI` { #step-2-create-a-fastapi-instance }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[3] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[3] *}
 
 Здесь переменная `app` будет экземпляром класса `FastAPI`.
 
@@ -266,7 +266,7 @@ https://example.com/items/foo
 
 #### Определите *декоратор операции пути (path operation decorator)* { #define-a-path-operation-decorator }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[6] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[6] *}
 
 `@app.get("/")` сообщает **FastAPI**, что функция прямо под ним отвечает за обработку запросов, поступающих:
 
@@ -320,7 +320,7 @@ https://example.com/items/foo
 * **операция**: `get`.
 * **функция**: функция ниже «декоратора» (ниже `@app.get("/")`).
 
-{* ../../docs_src/first_steps/tutorial001.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[7] *}
 
 Это функция на Python.
 
@@ -332,7 +332,7 @@ https://example.com/items/foo
 
 Вы также можете определить её как обычную функцию вместо `async def`:
 
-{* ../../docs_src/first_steps/tutorial003.py hl[7] *}
+{* ../../docs_src/first_steps/tutorial003_py39.py hl[7] *}
 
 /// note | Примечание
 
@@ -342,7 +342,7 @@ https://example.com/items/foo
 
 ### Шаг 5: верните содержимое { #step-5-return-the-content }
 
-{* ../../docs_src/first_steps/tutorial001.py hl[8] *}
+{* ../../docs_src/first_steps/tutorial001_py39.py hl[8] *}
 
 Вы можете вернуть `dict`, `list`, отдельные значения `str`, `int` и т.д.
 
index 63ca8665efab14e278aced9272c375ff22e772c7..2e00d7075905b10b0591bcc98e9f47eca8c7f2fc 100644 (file)
@@ -25,7 +25,7 @@
 
 ### Импортируйте `HTTPException` { #import-httpexception }
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[1] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[1] *}
 
 ### Вызовите `HTTPException` в своем коде { #raise-an-httpexception-in-your-code }
 
@@ -39,7 +39,7 @@
 
 В данном примере, когда клиент запрашивает элемент по несуществующему ID, возникает исключение со статус-кодом `404`:
 
-{* ../../docs_src/handling_errors/tutorial001.py hl[11] *}
+{* ../../docs_src/handling_errors/tutorial001_py39.py hl[11] *}
 
 ### Возвращаемый ответ { #the-resulting-response }
 
@@ -77,7 +77,7 @@
 
 Но в случае, если это необходимо для продвинутого сценария, можно добавить пользовательские заголовки:
 
-{* ../../docs_src/handling_errors/tutorial002.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial002_py39.py hl[14] *}
 
 ## Установка пользовательских обработчиков исключений { #install-custom-exception-handlers }
 
@@ -89,7 +89,7 @@
 
 Можно добавить собственный обработчик исключений с помощью `@app.exception_handler()`:
 
-{* ../../docs_src/handling_errors/tutorial003.py hl[5:7,13:18,24] *}
+{* ../../docs_src/handling_errors/tutorial003_py39.py hl[5:7,13:18,24] *}
 
 Здесь, если запросить `/unicorns/yolo`, то *операция пути* вызовет `UnicornException`.
 
 
 Обработчик исключения получит объект `Request` и исключение.
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[2,14:19] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[2,14:19] *}
 
 Теперь, если перейти к `/items/foo`, то вместо стандартной JSON-ошибки с:
 
@@ -159,7 +159,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
 
 Например, для этих ошибок можно вернуть обычный текстовый ответ вместо JSON:
 
-{* ../../docs_src/handling_errors/tutorial004.py hl[3:4,9:11,25] *}
+{* ../../docs_src/handling_errors/tutorial004_py39.py hl[3:4,9:11,25] *}
 
 /// note | Технические детали
 
@@ -183,7 +183,7 @@ Field: ('path', 'item_id'), Error: Input should be a valid integer, unable to pa
 
 Вы можете использовать его при разработке приложения для регистрации тела и его отладки, возврата пользователю и т.д.
 
-{* ../../docs_src/handling_errors/tutorial005.py hl[14] *}
+{* ../../docs_src/handling_errors/tutorial005_py39.py hl[14] *}
 
 Теперь попробуйте отправить недействительный элемент, например:
 
@@ -239,6 +239,6 @@ from starlette.exceptions import HTTPException as StarletteHTTPException
 
 Если вы хотите использовать исключение вместе с теми же обработчиками исключений по умолчанию из **FastAPI**, вы можете импортировать и повторно использовать обработчики исключений по умолчанию из `fastapi.exception_handlers`:
 
-{* ../../docs_src/handling_errors/tutorial006.py hl[2:5,15,21] *}
+{* ../../docs_src/handling_errors/tutorial006_py39.py hl[2:5,15,21] *}
 
 В этом примере вы просто `выводите в терминал` ошибку с очень выразительным сообщением, но идея вам понятна. Вы можете использовать исключение, а затем просто повторно использовать стандартные обработчики исключений.
index 2e359752e1c0429a8f306e0f9a38248b4e22b579..e4fe5fb5443b42ab6751c6182a5c94658223aacb 100644 (file)
@@ -18,7 +18,7 @@
 
 Вы можете задать их следующим образом:
 
-{* ../../docs_src/metadata/tutorial001.py hl[3:16, 19:32] *}
+{* ../../docs_src/metadata/tutorial001_py39.py hl[3:16, 19:32] *}
 
 /// tip | Подсказка
 
@@ -36,7 +36,7 @@
 
 К примеру:
 
-{* ../../docs_src/metadata/tutorial001_1.py hl[31] *}
+{* ../../docs_src/metadata/tutorial001_1_py39.py hl[31] *}
 
 ## Метаданные для тегов { #metadata-for-tags }
 
@@ -58,7 +58,7 @@
 
 Создайте метаданные для ваших тегов и передайте их в параметре `openapi_tags`:
 
-{* ../../docs_src/metadata/tutorial004.py hl[3:16,18] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[3:16,18] *}
 
 Помните, что вы можете использовать Markdown внутри описания, к примеру "login" будет отображен жирным шрифтом (**login**) и "fancy" будет отображаться курсивом (_fancy_).
 
@@ -72,7 +72,7 @@
 
 Используйте параметр `tags` с вашими *операциями пути* (и `APIRouter`ами), чтобы присвоить им различные теги:
 
-{* ../../docs_src/metadata/tutorial004.py hl[21,26] *}
+{* ../../docs_src/metadata/tutorial004_py39.py hl[21,26] *}
 
 /// info | Дополнительная информация
 
 
 К примеру, чтобы задать её отображение по адресу `/api/v1/openapi.json`:
 
-{* ../../docs_src/metadata/tutorial002.py hl[3] *}
+{* ../../docs_src/metadata/tutorial002_py39.py hl[3] *}
 
 Если вы хотите отключить схему OpenAPI полностью, вы можете задать `openapi_url=None`, это также отключит пользовательские интерфейсы документации, которые её используют.
 
 
 К примеру, чтобы задать отображение Swagger UI по адресу `/documentation` и отключить ReDoc:
 
-{* ../../docs_src/metadata/tutorial003.py hl[3] *}
+{* ../../docs_src/metadata/tutorial003_py39.py hl[3] *}
index 5803b398b90c45ae029fbacb1a7b03ee800ca477..a83d3c0111f2b8e55eadd8cf6fbda10e162920d5 100644 (file)
@@ -33,7 +33,7 @@
     * Затем она возвращает ответ `response`, сгенерированный *операцией пути*.
 * Также имеется возможность видоизменить `response`, перед тем как его вернуть.
 
-{* ../../docs_src/middleware/tutorial001.py hl[8:9,11,14] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[8:9,11,14] *}
 
 /// tip | Примечание
 
@@ -59,7 +59,7 @@
 
 Например, вы можете добавить собственный заголовок `X-Process-Time`, содержащий время в секундах, необходимое для обработки запроса и генерации ответа:
 
-{* ../../docs_src/middleware/tutorial001.py hl[10,12:13] *}
+{* ../../docs_src/middleware/tutorial001_py39.py hl[10,12:13] *}
 
 /// tip | Примечание
 
index 63b48a394117e924103be545ed45caa6204af271..96a54ffea05e022c20a9f3a557b725dcb8c8df90 100644 (file)
@@ -46,7 +46,7 @@
 
 **FastAPI** поддерживает это так же, как и в случае с обычными строками:
 
-{* ../../docs_src/path_operation_configuration/tutorial002b.py hl[1,8:10,13,18] *}
+{* ../../docs_src/path_operation_configuration/tutorial002b_py39.py hl[1,8:10,13,18] *}
 
 ## Краткое и развёрнутое содержание { #summary-and-description }
 
@@ -92,7 +92,7 @@ OpenAPI указывает, что каждой *операции пути* не
 
 Если вам необходимо пометить *операцию пути* как <abbr title="устаревшее, не рекомендовано к использованию">устаревшую</abbr>, при этом не удаляя её, передайте параметр `deprecated`:
 
-{* ../../docs_src/path_operation_configuration/tutorial006.py hl[16] *}
+{* ../../docs_src/path_operation_configuration/tutorial006_py39.py hl[16] *}
 
 Он будет четко помечен как устаревший в интерактивной документации:
 
index ccea1945e42426c885cf57a05b0bfbdb39c19197..f0fe7880510cc1c998f79fa98379cfbeb52bb0e1 100644 (file)
@@ -54,7 +54,7 @@ Path-параметр всегда является обязательным, п
 
 Поэтому вы можете определить функцию так:
 
-{* ../../docs_src/path_params_numeric_validations/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial002_py39.py hl[7] *}
 
 Но имейте в виду, что если вы используете `Annotated`, вы не столкнётесь с этой проблемой, так как вы не используете значения по умолчанию параметров функции для `Query()` или `Path()`.
 
@@ -83,7 +83,7 @@ Path-параметр всегда является обязательным, п
 
 Python не будет ничего делать с `*`, но он будет знать, что все следующие параметры являются именованными аргументами (парами ключ-значение), также известными как <abbr title="От: K-ey W-ord Arg-uments"><code>kwargs</code></abbr>, даже если у них нет значений по умолчанию.
 
-{* ../../docs_src/path_params_numeric_validations/tutorial003.py hl[7] *}
+{* ../../docs_src/path_params_numeric_validations/tutorial003_py39.py hl[7] *}
 
 ### Лучше с `Annotated` { #better-with-annotated }
 
index f7d138afbec41a6ae348c215a65705fc0cecd5dc..83a7ed3ffe7842bf3906d3af4b85a59c2700195a 100644 (file)
@@ -2,7 +2,7 @@
 
 Вы можете определить "параметры" или "переменные" пути, используя синтаксис форматированных строк Python:
 
-{* ../../docs_src/path_params/tutorial001.py hl[6:7] *}
+{* ../../docs_src/path_params/tutorial001_py39.py hl[6:7] *}
 
 Значение параметра пути `item_id` будет передано в функцию в качестве аргумента `item_id`.
 
@@ -16,7 +16,7 @@
 
 Вы можете объявить тип параметра пути в функции, используя стандартные аннотации типов Python:
 
-{* ../../docs_src/path_params/tutorial002.py hl[7] *}
+{* ../../docs_src/path_params/tutorial002_py39.py hl[7] *}
 
 Здесь, `item_id` объявлен типом `int`.
 
 
 Поскольку *операции пути* выполняются в порядке их объявления, необходимо, чтобы путь для `/users/me` был объявлен раньше, чем путь для `/users/{user_id}`:
 
-{* ../../docs_src/path_params/tutorial003.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003_py39.py hl[6,11] *}
 
 Иначе путь для `/users/{user_id}` также будет соответствовать `/users/me`, "подразумевая", что он получает параметр `user_id` со значением `"me"`.
 
 Аналогично, вы не можете переопределить операцию с путем:
 
-{* ../../docs_src/path_params/tutorial003b.py hl[6,11] *}
+{* ../../docs_src/path_params/tutorial003b_py39.py hl[6,11] *}
 
 Первый будет выполняться всегда, так как путь совпадает первым.
 
 
 Затем создайте атрибуты класса с фиксированными допустимыми значениями:
 
-{* ../../docs_src/path_params/tutorial005.py hl[1,6:9] *}
-
-/// info | Дополнительная информация
-
-<a href="https://docs.python.org/3/library/enum.html" class="external-link" target="_blank">Перечисления (enum) доступны в Python</a> начиная с версии 3.4.
-
-///
+{* ../../docs_src/path_params/tutorial005_py39.py hl[1,6:9] *}
 
 /// tip | Подсказка
 
 
 Определите *параметр пути*, используя в аннотации типа класс перечисления (`ModelName`), созданный ранее:
 
-{* ../../docs_src/path_params/tutorial005.py hl[16] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[16] *}
 
 ### Проверьте документацию { #check-the-docs }
 
 
 Вы можете сравнить это значение с *элементом перечисления* класса `ModelName`:
 
-{* ../../docs_src/path_params/tutorial005.py hl[17] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[17] *}
 
 #### Получение *значения перечисления* { #get-the-enumeration-value }
 
 Можно получить фактическое значение (в данном случае - `str`) с помощью `model_name.value` или в общем случае `your_enum_member.value`:
 
-{* ../../docs_src/path_params/tutorial005.py hl[20] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[20] *}
 
 /// tip | Подсказка
 
 
 Они будут преобразованы в соответствующие значения (в данном случае - строки) перед их возвратом клиенту:
 
-{* ../../docs_src/path_params/tutorial005.py hl[18,21,23] *}
+{* ../../docs_src/path_params/tutorial005_py39.py hl[18,21,23] *}
 Вы отправите клиенту такой JSON-ответ:
 
 ```JSON
@@ -232,7 +226,7 @@ OpenAPI не поддерживает способов объявления *п
 
 Можете использовать так:
 
-{* ../../docs_src/path_params/tutorial004.py hl[6] *}
+{* ../../docs_src/path_params/tutorial004_py39.py hl[6] *}
 
 /// tip | Подсказка
 
index 302901d4ecdcd2f19cbe3de2e881c34f675b466c..3a4ecc37dca372a3168dc4e160fa6a8bc410b230 100644 (file)
@@ -55,7 +55,7 @@ q: str | None = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Union[str, None] = None
@@ -73,7 +73,7 @@ q: Annotated[str | None] = None
 
 ////
 
-//// tab | Python 3.8+
+//// tab | Python 3.9+
 
 ```Python
 q: Annotated[Union[str, None]] = None
index 5a84f9768c1bfa0433a92fa0be3fc61a1eadf6a6..be1c0e46e1300c5c8958835d0f294fe2aa1d3f3b 100644 (file)
@@ -2,7 +2,7 @@
 
 Когда вы объявляете параметры функции, которые не являются параметрами пути, они автоматически интерпретируются как "query"-параметры.
 
-{* ../../docs_src/query_params/tutorial001.py hl[9] *}
+{* ../../docs_src/query_params/tutorial001_py39.py hl[9] *}
 
 Query-параметры представляют из себя набор пар ключ-значение, которые идут после знака `?` в URL-адресе, разделенные символами `&`.
 
@@ -127,7 +127,7 @@ http://127.0.0.1:8000/items/foo?short=yes
 
 Но если вы хотите сделать query-параметр обязательным, вы можете просто не указывать значение по умолчанию:
 
-{* ../../docs_src/query_params/tutorial005.py hl[6:7] *}
+{* ../../docs_src/query_params/tutorial005_py39.py hl[6:7] *}
 
 Здесь параметр запроса `needy` является обязательным параметром с типом данных  `str`.
 
index c045f9ed788f0ad49a9bf33a1d4017388bc850ea..07308c1db291b44f0b795b424a028156704be47a 100644 (file)
@@ -183,7 +183,7 @@ FastAPI делает несколько вещей внутри вместе с
 
 Самый распространённый случай — [возвращать Response напрямую, как описано далее в разделах для продвинутых](../advanced/response-directly.md){.internal-link target=_blank}.
 
-{* ../../docs_src/response_model/tutorial003_02.py hl[8,10:11] *}
+{* ../../docs_src/response_model/tutorial003_02_py39.py hl[8,10:11] *}
 
 Этот простой случай обрабатывается FastAPI автоматически, потому что аннотация возвращаемого типа — это класс (или подкласс) `Response`.
 
@@ -193,7 +193,7 @@ FastAPI делает несколько вещей внутри вместе с
 
 Вы также можете использовать подкласс `Response` в аннотации типа:
 
-{* ../../docs_src/response_model/tutorial003_03.py hl[8:9] *}
+{* ../../docs_src/response_model/tutorial003_03_py39.py hl[8:9] *}
 
 Это тоже сработает, так как `RedirectResponse` — подкласс `Response`, и FastAPI автоматически обработает этот случай.
 
index f5b1ff6ad7f5fb1000b41d80593edaebfcfdad6f..30f642b6438baf5bc93758916ad66bda85852e12 100644 (file)
@@ -8,7 +8,7 @@
 * `@app.delete()`
 * и других.
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 /// note | Примечание
 
@@ -74,7 +74,7 @@ FastAPI знает об этом и создаст документацию Open
 
 Рассмотрим предыдущий пример еще раз:
 
-{* ../../docs_src/response_status_code/tutorial001.py hl[6] *}
+{* ../../docs_src/response_status_code/tutorial001_py39.py hl[6] *}
 
 `201` – это код статуса "Создано".
 
@@ -82,7 +82,7 @@ FastAPI знает об этом и создаст документацию Open
 
 Для удобства вы можете использовать переменные из `fastapi.status`.
 
-{* ../../docs_src/response_status_code/tutorial002.py hl[1,6] *}
+{* ../../docs_src/response_status_code/tutorial002_py39.py hl[1,6] *}
 
 Они содержат те же числовые значения, но позволяют использовать автозавершение редактора кода для выбора кода статуса:
 
index 8455aea0a2a56447ed00e8b0c4f4ea0fd7cf3401..f40cfe9b04b3e0376479db396bb2a03105beeb50 100644 (file)
@@ -7,7 +7,7 @@
 * Импортируйте `StaticFiles`.
 * "Примонтируйте" экземпляр `StaticFiles()` к определённому пути.
 
-{* ../../docs_src/static_files/tutorial001.py hl[2,6] *}
+{* ../../docs_src/static_files/tutorial001_py39.py hl[2,6] *}
 
 /// note | Технические детали
 
index 7354ed895fc4ddaedc644a3741e4c3727f56e3c8..ab58429c517099d9342ac92ebf8aeb28557de80d 100644 (file)
@@ -30,7 +30,7 @@ $ pip install httpx
 
 Напишите простое утверждение с `assert` дабы проверить истинность Python-выражения (это тоже стандарт `pytest`).
 
-{* ../../docs_src/app_testing/tutorial001.py hl[2,12,15:18] *}
+{* ../../docs_src/app_testing/tutorial001_py39.py hl[2,12,15:18] *}
 
 /// tip | Подсказка
 
@@ -76,7 +76,7 @@ $ pip install httpx
 В файле `main.py` находится Ваше приложение **FastAPI**:
 
 
-{* ../../docs_src/app_testing/main.py *}
+{* ../../docs_src/app_testing/app_a_py39/main.py *}
 
 ### Файл тестов { #testing-file }
 
@@ -92,7 +92,7 @@ $ pip install httpx
 
 Так как оба файла находятся в одной директории, для импорта объекта приложения из файла `main` в файл `test_main` Вы можете использовать относительный импорт:
 
-{* ../../docs_src/app_testing/test_main.py hl[3] *}
+{* ../../docs_src/app_testing/app_a_py39/test_main.py hl[3] *}
 
 
 ...и писать дальше тесты, как и раньше.
diff --git a/docs_src/additional_status_codes/tutorial001_an.py b/docs_src/additional_status_codes/tutorial001_an.py
deleted file mode 100644 (file)
index b5ad6a1..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI, status
-from fastapi.responses import JSONResponse
-from typing_extensions import Annotated
-
-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/app_testing/app_b_an/main.py b/docs_src/app_testing/app_b_an/main.py
deleted file mode 100644 (file)
index c66278f..0000000
+++ /dev/null
@@ -1,39 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header, HTTPException
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/", response_model=Item)
-async def create_item(item: Item, x_token: Annotated[str, Header()]):
-    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
-    return item
diff --git a/docs_src/app_testing/app_b_an/test_main.py b/docs_src/app_testing/app_b_an/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/authentication_error_status_code/tutorial001_an.py b/docs_src/authentication_error_status_code/tutorial001_an.py
deleted file mode 100644 (file)
index 40678e8..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from fastapi import Depends, FastAPI, HTTPException, status
-from fastapi.security import HTTPAuthorizationCredentials, HTTPBearer
-from typing_extensions import Annotated
-
-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/tutorial002_an.py b/docs_src/background_tasks/tutorial002_an.py
deleted file mode 100644 (file)
index f63502b..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Union
-
-from fastapi import BackgroundTasks, Depends, FastAPI
-from typing_extensions import Annotated
-
-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/bigger_applications/app_an/dependencies.py b/docs_src/bigger_applications/app_an/dependencies.py
deleted file mode 100644 (file)
index 1374c54..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from fastapi import Header, HTTPException
-from typing_extensions import Annotated
-
-
-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/internal/admin.py b/docs_src/bigger_applications/app_an/internal/admin.py
deleted file mode 100644 (file)
index 99d3da8..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-from fastapi import APIRouter
-
-router = APIRouter()
-
-
-@router.post("/")
-async def update_admin():
-    return {"message": "Admin getting schwifty"}
diff --git a/docs_src/bigger_applications/app_an/main.py b/docs_src/bigger_applications/app_an/main.py
deleted file mode 100644 (file)
index ae544a3..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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/routers/items.py b/docs_src/bigger_applications/app_an/routers/items.py
deleted file mode 100644 (file)
index bde9ff4..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from fastapi import APIRouter, Depends, HTTPException
-
-from ..dependencies import get_token_header
-
-router = APIRouter(
-    prefix="/items",
-    tags=["items"],
-    dependencies=[Depends(get_token_header)],
-    responses={404: {"description": "Not found"}},
-)
-
-
-fake_items_db = {"plumbus": {"name": "Plumbus"}, "gun": {"name": "Portal Gun"}}
-
-
-@router.get("/")
-async def read_items():
-    return fake_items_db
-
-
-@router.get("/{item_id}")
-async def read_item(item_id: str):
-    if item_id not in fake_items_db:
-        raise HTTPException(status_code=404, detail="Item not found")
-    return {"name": fake_items_db[item_id]["name"], "item_id": item_id}
-
-
-@router.put(
-    "/{item_id}",
-    tags=["custom"],
-    responses={403: {"description": "Operation forbidden"}},
-)
-async def update_item(item_id: str):
-    if item_id != "plumbus":
-        raise HTTPException(
-            status_code=403, detail="You can only update the item: plumbus"
-        )
-    return {"item_id": item_id, "name": "The great Plumbus"}
diff --git a/docs_src/bigger_applications/app_an/routers/users.py b/docs_src/bigger_applications/app_an/routers/users.py
deleted file mode 100644 (file)
index 39b3d7e..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from fastapi import APIRouter
-
-router = APIRouter()
-
-
-@router.get("/users/", tags=["users"])
-async def read_users():
-    return [{"username": "Rick"}, {"username": "Morty"}]
-
-
-@router.get("/users/me", tags=["users"])
-async def read_user_me():
-    return {"username": "fakecurrentuser"}
-
-
-@router.get("/users/{username}", tags=["users"])
-async def read_user(username: str):
-    return {"username": username}
diff --git a/docs_src/body_fields/tutorial001_an.py b/docs_src/body_fields/tutorial001_an.py
deleted file mode 100644 (file)
index 15ea1b5..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel, Field
-from typing_extensions import Annotated
-
-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_multiple_params/tutorial001_an.py b/docs_src/body_multiple_params/tutorial001_an.py
deleted file mode 100644 (file)
index 308eee8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Path
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial003_an.py b/docs_src/body_multiple_params/tutorial003_an.py
deleted file mode 100644 (file)
index 39ef734..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial004_an.py b/docs_src/body_multiple_params/tutorial004_an.py
deleted file mode 100644 (file)
index f6830f3..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial005_an.py b/docs_src/body_multiple_params/tutorial005_an.py
deleted file mode 100644 (file)
index dadde80..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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_nested_models/tutorial002.py b/docs_src/body_nested_models/tutorial002.py
deleted file mode 100644 (file)
index 155cff7..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import List, 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.py b/docs_src/body_nested_models/tutorial003.py
deleted file mode 100644 (file)
index 84ed18b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Set, 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.py b/docs_src/body_nested_models/tutorial004.py
deleted file mode 100644 (file)
index a07bfac..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Set, 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.py b/docs_src/body_nested_models/tutorial005.py
deleted file mode 100644 (file)
index 5a01264..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Set, 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.py b/docs_src/body_nested_models/tutorial006.py
deleted file mode 100644 (file)
index 75f1f30..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import List, Set, 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.py b/docs_src/body_nested_models/tutorial007.py
deleted file mode 100644 (file)
index 641f09d..0000000
+++ /dev/null
@@ -1,32 +0,0 @@
-from typing import List, Set, 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.py b/docs_src/body_nested_models/tutorial008.py
deleted file mode 100644 (file)
index 3431cc6..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from typing import List
-
-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.py b/docs_src/body_nested_models/tutorial009.py
deleted file mode 100644 (file)
index 41dce94..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Dict
-
-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.py b/docs_src/body_updates/tutorial001.py
deleted file mode 100644 (file)
index 4e65d77..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-from typing import List, 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.py b/docs_src/body_updates/tutorial002.py
deleted file mode 100644 (file)
index c3a0fe7..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-from typing import List, 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}", response_model=Item)
-async def update_item(item_id: str, item: Item):
-    stored_item_data = items[item_id]
-    stored_item_model = Item(**stored_item_data)
-    update_data = item.dict(exclude_unset=True)
-    updated_item = stored_item_model.copy(update=update_data)
-    items[item_id] = jsonable_encoder(updated_item)
-    return updated_item
diff --git a/docs_src/cookie_param_models/tutorial001_an.py b/docs_src/cookie_param_models/tutorial001_an.py
deleted file mode 100644 (file)
index e5839ff..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial002_an.py b/docs_src/cookie_param_models/tutorial002_an.py
deleted file mode 100644 (file)
index ce5644b..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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_pv1_an.py b/docs_src/cookie_param_models/tutorial002_pv1_an.py
deleted file mode 100644 (file)
index ddfda9b..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-class Cookies(BaseModel):
-    class 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_params/tutorial001_an.py b/docs_src/cookie_params/tutorial001_an.py
deleted file mode 100644 (file)
index 6d59312..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, FastAPI
-from typing_extensions import Annotated
-
-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/custom_request_and_route/tutorial001.py b/docs_src/custom_request_and_route/tutorial001.py
deleted file mode 100644 (file)
index 268ce90..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-import gzip
-from typing import Callable, List
-
-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/tutorial001_an.py b/docs_src/custom_request_and_route/tutorial001_an.py
deleted file mode 100644 (file)
index 6224ba8..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-import gzip
-from typing import Callable, List
-
-from fastapi import Body, FastAPI, Request, Response
-from fastapi.routing import APIRoute
-from typing_extensions import Annotated
-
-
-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/tutorial002.py b/docs_src/custom_request_and_route/tutorial002.py
deleted file mode 100644 (file)
index cee4a95..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from typing import Callable, List
-
-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/tutorial002_an.py b/docs_src/custom_request_and_route/tutorial002_an.py
deleted file mode 100644 (file)
index 127f7a9..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from typing import Callable, List
-
-from fastapi import Body, FastAPI, HTTPException, Request, Response
-from fastapi.exceptions import RequestValidationError
-from fastapi.routing import APIRoute
-from typing_extensions import Annotated
-
-
-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/dataclasses/tutorial002.py b/docs_src/dataclasses/tutorial002.py
deleted file mode 100644 (file)
index ece2f15..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from dataclasses import dataclass, field
-from typing import List, 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.py b/docs_src/dataclasses/tutorial003.py
deleted file mode 100644 (file)
index c613155..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-from dataclasses import field  # (1)
-from typing import List, 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/dependencies/tutorial001_02_an.py b/docs_src/dependencies/tutorial001_02_an.py
deleted file mode 100644 (file)
index 455d60c..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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.py b/docs_src/dependencies/tutorial001_an.py
deleted file mode 100644 (file)
index 81e24fe..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/tutorial002_an.py b/docs_src/dependencies/tutorial002_an.py
deleted file mode 100644 (file)
index 964ccf6..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/tutorial003_an.py b/docs_src/dependencies/tutorial003_an.py
deleted file mode 100644 (file)
index ba8e9f7..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Any, Union
-
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/tutorial004_an.py b/docs_src/dependencies/tutorial004_an.py
deleted file mode 100644 (file)
index 78881a3..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/tutorial005_an.py b/docs_src/dependencies/tutorial005_an.py
deleted file mode 100644 (file)
index 1d78c17..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import Union
-
-from fastapi import Cookie, Depends, FastAPI
-from typing_extensions import Annotated
-
-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/tutorial006_an.py b/docs_src/dependencies/tutorial006_an.py
deleted file mode 100644 (file)
index 5aaea04..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from fastapi import Depends, FastAPI, Header, HTTPException
-from typing_extensions import Annotated
-
-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/tutorial008_an.py b/docs_src/dependencies/tutorial008_an.py
deleted file mode 100644 (file)
index 2de86f0..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from fastapi import Depends
-from typing_extensions import Annotated
-
-
-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/tutorial008b_an.py b/docs_src/dependencies/tutorial008b_an.py
deleted file mode 100644 (file)
index 84d8f12..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-from fastapi import Depends, FastAPI, HTTPException
-from typing_extensions import Annotated
-
-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/tutorial008c_an.py b/docs_src/dependencies/tutorial008c_an.py
deleted file mode 100644 (file)
index 94f59f9..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from fastapi import Depends, FastAPI, HTTPException
-from typing_extensions import Annotated
-
-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/tutorial008d_an.py b/docs_src/dependencies/tutorial008d_an.py
deleted file mode 100644 (file)
index c354245..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from fastapi import Depends, FastAPI, HTTPException
-from typing_extensions import Annotated
-
-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/tutorial008e_an.py b/docs_src/dependencies/tutorial008e_an.py
deleted file mode 100644 (file)
index c8a0af2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/tutorial009.py b/docs_src/dependencies/tutorial009.py
deleted file mode 100644 (file)
index 8472f64..0000000
+++ /dev/null
@@ -1,25 +0,0 @@
-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/tutorial011_an.py b/docs_src/dependencies/tutorial011_an.py
deleted file mode 100644 (file)
index 6c13d90..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/tutorial012_an.py b/docs_src/dependencies/tutorial012_an.py
deleted file mode 100644 (file)
index 7541e6b..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from fastapi import Depends, FastAPI, Header, HTTPException
-from typing_extensions import Annotated
-
-
-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"}]
index 7541e6bf41ad00dcb851c852e8c0254fe7ba747c..6503591fc3174829e8a28e51741f9d8a12c591d9 100644 (file)
@@ -1,5 +1,6 @@
+from typing import Annotated
+
 from fastapi import Depends, FastAPI, Header, HTTPException
-from typing_extensions import Annotated
 
 
 async def verify_token(x_token: Annotated[str, Header()]):
diff --git a/docs_src/dependency_testing/tutorial001_an.py b/docs_src/dependency_testing/tutorial001_an.py
deleted file mode 100644 (file)
index 4c76a87..0000000
+++ /dev/null
@@ -1,60 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from fastapi.testclient import TestClient
-from typing_extensions import Annotated
-
-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/extra_data_types/tutorial001_an.py b/docs_src/extra_data_types/tutorial001_an.py
deleted file mode 100644 (file)
index 257d0c7..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from datetime import datetime, time, timedelta
-from typing import Union
-from uuid import UUID
-
-from fastapi import Body, FastAPI
-from typing_extensions import Annotated
-
-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_models/tutorial004.py b/docs_src/extra_models/tutorial004.py
deleted file mode 100644 (file)
index a8e0f7a..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import List
-
-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.py b/docs_src/extra_models/tutorial005.py
deleted file mode 100644 (file)
index a81cbc2..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import Dict
-
-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/tutorial002.py b/docs_src/first_steps/tutorial002.py
deleted file mode 100644 (file)
index ca7d48c..0000000
+++ /dev/null
@@ -1,8 +0,0 @@
-from fastapi import FastAPI
-
-my_awesome_api = FastAPI()
-
-
-@my_awesome_api.get("/")
-async def root():
-    return {"message": "Hello World"}
diff --git a/docs_src/generate_clients/tutorial001.py b/docs_src/generate_clients/tutorial001.py
deleted file mode 100644 (file)
index 2d1f91b..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import List
-
-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.py b/docs_src/generate_clients/tutorial002.py
deleted file mode 100644 (file)
index bd80449..0000000
+++ /dev/null
@@ -1,38 +0,0 @@
-from typing import List
-
-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.py b/docs_src/generate_clients/tutorial003.py
deleted file mode 100644 (file)
index 49eab73..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-from typing import List
-
-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/header_param_models/tutorial001.py b/docs_src/header_param_models/tutorial001.py
deleted file mode 100644 (file)
index 4caaba8..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import List, 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/tutorial001_an.py b/docs_src/header_param_models/tutorial001_an.py
deleted file mode 100644 (file)
index b55c6b5..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial002.py b/docs_src/header_param_models/tutorial002.py
deleted file mode 100644 (file)
index 3f9aac5..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import List, 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/tutorial002_an.py b/docs_src/header_param_models/tutorial002_an.py
deleted file mode 100644 (file)
index 771135d..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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_pv1.py b/docs_src/header_param_models/tutorial002_pv1.py
deleted file mode 100644 (file)
index 7e56cd9..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    class 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/tutorial002_pv1_an.py b/docs_src/header_param_models/tutorial002_pv1_an.py
deleted file mode 100644 (file)
index 2367782..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-class CommonHeaders(BaseModel):
-    class 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/tutorial003.py b/docs_src/header_param_models/tutorial003.py
deleted file mode 100644 (file)
index dc2eb74..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import List, 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_param_models/tutorial003_an.py b/docs_src/header_param_models/tutorial003_an.py
deleted file mode 100644 (file)
index e3edb11..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Header
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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_params/tutorial001_an.py b/docs_src/header_params/tutorial001_an.py
deleted file mode 100644 (file)
index 816c000..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-from typing_extensions import Annotated
-
-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/tutorial002_an.py b/docs_src/header_params/tutorial002_an.py
deleted file mode 100644 (file)
index 82fe49b..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Header
-from typing_extensions import Annotated
-
-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/tutorial003.py b/docs_src/header_params/tutorial003.py
deleted file mode 100644 (file)
index a61314a..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from typing import List, 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/header_params/tutorial003_an.py b/docs_src/header_params/tutorial003_an.py
deleted file mode 100644 (file)
index 5406fd1..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Header
-from typing_extensions import Annotated
-
-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/path_operation_advanced_configuration/tutorial004.py b/docs_src/path_operation_advanced_configuration/tutorial004.py
deleted file mode 100644 (file)
index a3aad4a..0000000
+++ /dev/null
@@ -1,30 +0,0 @@
-from typing import Set, 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/", response_model=Item, summary="Create an item")
-async def create_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/tutorial007.py b/docs_src/path_operation_advanced_configuration/tutorial007.py
deleted file mode 100644 (file)
index 54e2e93..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-from typing import List
-
-import yaml
-from fastapi import FastAPI, HTTPException, Request
-from pydantic import BaseModel, ValidationError
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    tags: List[str]
-
-
-@app.post(
-    "/items/",
-    openapi_extra={
-        "requestBody": {
-            "content": {"application/x-yaml": {"schema": Item.model_json_schema()}},
-            "required": True,
-        },
-    },
-)
-async def create_item(request: Request):
-    raw_body = await request.body()
-    try:
-        data = yaml.safe_load(raw_body)
-    except yaml.YAMLError:
-        raise HTTPException(status_code=422, detail="Invalid YAML")
-    try:
-        item = Item.model_validate(data)
-    except ValidationError as e:
-        raise HTTPException(status_code=422, detail=e.errors(include_url=False))
-    return item
diff --git a/docs_src/path_operation_advanced_configuration/tutorial007_pv1.py b/docs_src/path_operation_advanced_configuration/tutorial007_pv1.py
deleted file mode 100644 (file)
index d51752b..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-from typing import List
-
-import yaml
-from fastapi import FastAPI, HTTPException, Request
-from pydantic import BaseModel, ValidationError
-
-app = FastAPI()
-
-
-class Item(BaseModel):
-    name: str
-    tags: List[str]
-
-
-@app.post(
-    "/items/",
-    openapi_extra={
-        "requestBody": {
-            "content": {"application/x-yaml": {"schema": Item.schema()}},
-            "required": True,
-        },
-    },
-)
-async def create_item(request: Request):
-    raw_body = await request.body()
-    try:
-        data = yaml.safe_load(raw_body)
-    except yaml.YAMLError:
-        raise HTTPException(status_code=422, detail="Invalid YAML")
-    try:
-        item = Item.parse_obj(data)
-    except ValidationError as e:
-        raise HTTPException(status_code=422, detail=e.errors())
-    return item
diff --git a/docs_src/path_operation_configuration/tutorial001.py b/docs_src/path_operation_configuration/tutorial001.py
deleted file mode 100644 (file)
index 83fd837..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import Set, 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/", response_model=Item, status_code=status.HTTP_201_CREATED)
-async def create_item(item: Item):
-    return item
diff --git a/docs_src/path_operation_configuration/tutorial002.py b/docs_src/path_operation_configuration/tutorial002.py
deleted file mode 100644 (file)
index 798b0c2..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-from typing import Set, 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/", response_model=Item, tags=["items"])
-async def create_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/tutorial003.py b/docs_src/path_operation_configuration/tutorial003.py
deleted file mode 100644 (file)
index 26bf7da..0000000
+++ /dev/null
@@ -1,24 +0,0 @@
-from typing import Set, 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/",
-    response_model=Item,
-    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):
-    return item
diff --git a/docs_src/path_operation_configuration/tutorial004.py b/docs_src/path_operation_configuration/tutorial004.py
deleted file mode 100644 (file)
index 8f865c5..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import Set, 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/", response_model=Item, summary="Create an item")
-async def create_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.py b/docs_src/path_operation_configuration/tutorial005.py
deleted file mode 100644 (file)
index 2c1be4a..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from typing import Set, 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/",
-    response_model=Item,
-    summary="Create an item",
-    response_description="The created item",
-)
-async def create_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_params_numeric_validations/tutorial001_an.py b/docs_src/path_params_numeric_validations/tutorial001_an.py
deleted file mode 100644 (file)
index 621be7b..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Path, Query
-from typing_extensions import Annotated
-
-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,
-):
-    results = {"item_id": item_id}
-    if q:
-        results.update({"q": q})
-    return results
diff --git a/docs_src/path_params_numeric_validations/tutorial002_an.py b/docs_src/path_params_numeric_validations/tutorial002_an.py
deleted file mode 100644 (file)
index 322f8cf..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-from fastapi import FastAPI, Path
-from typing_extensions import Annotated
-
-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/tutorial003_an.py b/docs_src/path_params_numeric_validations/tutorial003_an.py
deleted file mode 100644 (file)
index d0fa8b3..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-from fastapi import FastAPI, Path
-from typing_extensions import Annotated
-
-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/tutorial004_an.py b/docs_src/path_params_numeric_validations/tutorial004_an.py
deleted file mode 100644 (file)
index ffc50f6..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-from fastapi import FastAPI, Path
-from typing_extensions import Annotated
-
-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/tutorial005_an.py b/docs_src/path_params_numeric_validations/tutorial005_an.py
deleted file mode 100644 (file)
index 433c691..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from fastapi import FastAPI, Path
-from typing_extensions import Annotated
-
-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/tutorial006_an.py b/docs_src/path_params_numeric_validations/tutorial006_an.py
deleted file mode 100644 (file)
index ac47325..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from fastapi import FastAPI, Path, Query
-from typing_extensions import Annotated
-
-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=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
diff --git a/docs_src/pydantic_v1_in_v2/tutorial004_an.py b/docs_src/pydantic_v1_in_v2/tutorial004_an.py
deleted file mode 100644 (file)
index cca8a9e..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI
-from fastapi.temp_pydantic_v1_params import Body
-from pydantic.v1 import BaseModel
-from typing_extensions import Annotated
-
-
-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/tutorial006.py b/docs_src/python_types/tutorial006.py
deleted file mode 100644 (file)
index 87394ec..0000000
+++ /dev/null
@@ -1,6 +0,0 @@
-from typing import List
-
-
-def process_items(items: List[str]):
-    for item in items:
-        print(item)
diff --git a/docs_src/python_types/tutorial007.py b/docs_src/python_types/tutorial007.py
deleted file mode 100644 (file)
index 5b13f15..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-from typing import Set, Tuple
-
-
-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.py b/docs_src/python_types/tutorial008.py
deleted file mode 100644 (file)
index 9fb1043..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-from typing import Dict
-
-
-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/tutorial011.py b/docs_src/python_types/tutorial011.py
deleted file mode 100644 (file)
index 297a84d..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from datetime import datetime
-from typing import List, 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/tutorial013.py b/docs_src/python_types/tutorial013.py
deleted file mode 100644 (file)
index 0ec7735..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-from typing_extensions 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.py b/docs_src/query_param_models/tutorial001.py
deleted file mode 100644 (file)
index 0c0ab31..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-from typing_extensions import Literal
-
-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/tutorial001_an.py b/docs_src/query_param_models/tutorial001_an.py
deleted file mode 100644 (file)
index 2837505..0000000
+++ /dev/null
@@ -1,19 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-from typing_extensions import Annotated, Literal
-
-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
index ba690d3e3fa59bc882ba4bcb2fab6449f3b1b2b8..71427acae12eeceeef9ee15f557d6203814235f3 100644 (file)
@@ -1,6 +1,7 @@
+from typing import Annotated, Literal
+
 from fastapi import FastAPI, Query
 from pydantic import BaseModel, Field
-from typing_extensions import Annotated, Literal
 
 app = FastAPI()
 
index 54b52a054cc92c793de9725795780816069ed14f..3ebf9f4d7000bbf37b3ce8f46c073b02f094b57d 100644 (file)
@@ -1,6 +1,7 @@
+from typing import Literal
+
 from fastapi import FastAPI, Query
 from pydantic import BaseModel, Field
-from typing_extensions import Literal
 
 app = FastAPI()
 
diff --git a/docs_src/query_param_models/tutorial002.py b/docs_src/query_param_models/tutorial002.py
deleted file mode 100644 (file)
index 1633bc4..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-from typing_extensions import Literal
-
-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_param_models/tutorial002_an.py b/docs_src/query_param_models/tutorial002_an.py
deleted file mode 100644 (file)
index 69705d4..0000000
+++ /dev/null
@@ -1,21 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-from typing_extensions import Annotated, Literal
-
-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
index 2d4c1a62b584745b0653a0ca061c8331acc2cd98..97595650234dd52e5a8c22855048920e09588dc8 100644 (file)
@@ -1,6 +1,7 @@
+from typing import Annotated, Literal
+
 from fastapi import FastAPI, Query
 from pydantic import BaseModel, Field
-from typing_extensions import Annotated, Literal
 
 app = FastAPI()
 
diff --git a/docs_src/query_param_models/tutorial002_pv1.py b/docs_src/query_param_models/tutorial002_pv1.py
deleted file mode 100644 (file)
index 71ccd96..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-from typing_extensions import Literal
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    class 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_param_models/tutorial002_pv1_an.py b/docs_src/query_param_models/tutorial002_pv1_an.py
deleted file mode 100644 (file)
index 1dd2915..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, Query
-from pydantic import BaseModel, Field
-from typing_extensions import Annotated, Literal
-
-app = FastAPI()
-
-
-class FilterParams(BaseModel):
-    class 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
index 494fef11fc2487ed61eb028c39790a7b9b6aabcc..d635aae88f387273f5166ba016e206ccf52c6364 100644 (file)
@@ -1,6 +1,7 @@
+from typing import Annotated, Literal
+
 from fastapi import FastAPI, Query
 from pydantic import BaseModel, Field
-from typing_extensions import Annotated, Literal
 
 app = FastAPI()
 
index 7fa456a7913d342e1714c0a8fce494188266588e..9ffdeefc06d65572e7c1a4eefe64084fccbc8112 100644 (file)
@@ -1,6 +1,7 @@
+from typing import Literal
+
 from fastapi import FastAPI, Query
 from pydantic import BaseModel, Field
-from typing_extensions import Literal
 
 app = FastAPI()
 
index f9bba028c230f6979ab94d1df93a3481258a1221..6ec418499136e4b12f51fe1d5a710b7ba8ef2bbc 100644 (file)
@@ -1,6 +1,7 @@
+from typing import Literal
+
 from fastapi import FastAPI, Query
 from pydantic import BaseModel, Field
-from typing_extensions import Literal
 
 app = FastAPI()
 
diff --git a/docs_src/query_params/tutorial006b.py b/docs_src/query_params/tutorial006b.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
similarity index 81%
rename from docs_src/query_params_str_validations/tutorial002_an.py
rename to docs_src/query_params_str_validations/tutorial002_an_py39.py
index cb1b38940c495f8a39c3b2dd1c4fe9601d8e07f0..2d8fc979851d2a7652c9504e944ad286a6caec1f 100644 (file)
@@ -1,7 +1,6 @@
-from typing import Union
+from typing import Annotated, Union
 
 from fastapi import FastAPI, Query
-from typing_extensions import Annotated
 
 app = FastAPI()
 
diff --git a/docs_src/query_params_str_validations/tutorial003_an.py b/docs_src/query_params_str_validations/tutorial003_an.py
deleted file mode 100644 (file)
index 0dd1408..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-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/tutorial004_an.py b/docs_src/query_params_str_validations/tutorial004_an.py
deleted file mode 100644 (file)
index c75d45d..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-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/tutorial005_an.py b/docs_src/query_params_str_validations/tutorial005_an.py
deleted file mode 100644 (file)
index 452d4d3..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-@app.get("/items/")
-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})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial006_an.py b/docs_src/query_params_str_validations/tutorial006_an.py
deleted file mode 100644 (file)
index 559480d..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-@app.get("/items/")
-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})
-    return results
diff --git a/docs_src/query_params_str_validations/tutorial006c_an.py b/docs_src/query_params_str_validations/tutorial006c_an.py
deleted file mode 100644 (file)
index 55c4f4a..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(q: Annotated[Union[str, None], Query(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/tutorial007_an.py b/docs_src/query_params_str_validations/tutorial007_an.py
deleted file mode 100644 (file)
index 4b3c8de..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-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/tutorial008_an.py b/docs_src/query_params_str_validations/tutorial008_an.py
deleted file mode 100644 (file)
index 01606a9..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-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/tutorial009_an.py b/docs_src/query_params_str_validations/tutorial009_an.py
deleted file mode 100644 (file)
index 2894e2d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-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.py b/docs_src/query_params_str_validations/tutorial010_an.py
deleted file mode 100644 (file)
index ed34323..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-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/tutorial011.py b/docs_src/query_params_str_validations/tutorial011.py
deleted file mode 100644 (file)
index 65bbce7..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Query
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(q: Union[List[str], None] = Query(default=None)):
-    query_items = {"q": q}
-    return query_items
diff --git a/docs_src/query_params_str_validations/tutorial011_an.py b/docs_src/query_params_str_validations/tutorial011_an.py
deleted file mode 100644 (file)
index 8ed6993..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(q: Annotated[Union[List[str], None], Query()] = None):
-    query_items = {"q": q}
-    return query_items
diff --git a/docs_src/query_params_str_validations/tutorial012.py b/docs_src/query_params_str_validations/tutorial012.py
deleted file mode 100644 (file)
index e77d569..0000000
+++ /dev/null
@@ -1,11 +0,0 @@
-from typing import List
-
-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
diff --git a/docs_src/query_params_str_validations/tutorial012_an.py b/docs_src/query_params_str_validations/tutorial012_an.py
deleted file mode 100644 (file)
index 261af25..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-@app.get("/items/")
-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/tutorial013_an.py b/docs_src/query_params_str_validations/tutorial013_an.py
deleted file mode 100644 (file)
index f12a250..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-@app.get("/items/")
-async def read_items(q: Annotated[list, Query()] = []):
-    query_items = {"q": q}
-    return query_items
diff --git a/docs_src/query_params_str_validations/tutorial014_an.py b/docs_src/query_params_str_validations/tutorial014_an.py
deleted file mode 100644 (file)
index 2eaa585..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, Query
-from typing_extensions import Annotated
-
-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/tutorial015_an.py b/docs_src/query_params_str_validations/tutorial015_an.py
deleted file mode 100644 (file)
index f2ec6db..0000000
+++ /dev/null
@@ -1,31 +0,0 @@
-import random
-from typing import Union
-
-from fastapi import FastAPI
-from pydantic import AfterValidator
-from typing_extensions import Annotated
-
-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.py b/docs_src/request_files/tutorial001_02_an.py
deleted file mode 100644 (file)
index 5007fef..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from typing import Union
-
-from fastapi import FastAPI, File, UploadFile
-from typing_extensions import Annotated
-
-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_03_an.py b/docs_src/request_files/tutorial001_03_an.py
deleted file mode 100644 (file)
index 8a6b0a2..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from fastapi import FastAPI, File, UploadFile
-from typing_extensions import Annotated
-
-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_an.py b/docs_src/request_files/tutorial001_an.py
deleted file mode 100644 (file)
index ca2f76d..0000000
+++ /dev/null
@@ -1,14 +0,0 @@
-from fastapi import FastAPI, File, UploadFile
-from typing_extensions import Annotated
-
-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/tutorial002.py b/docs_src/request_files/tutorial002.py
deleted file mode 100644 (file)
index b4d0acc..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from typing import List
-
-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/tutorial002_an.py b/docs_src/request_files/tutorial002_an.py
deleted file mode 100644 (file)
index eaa90da..0000000
+++ /dev/null
@@ -1,34 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, File, UploadFile
-from fastapi.responses import HTMLResponse
-from typing_extensions import Annotated
-
-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/tutorial003.py b/docs_src/request_files/tutorial003.py
deleted file mode 100644 (file)
index e3f805f..0000000
+++ /dev/null
@@ -1,37 +0,0 @@
-from typing import List
-
-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_files/tutorial003_an.py b/docs_src/request_files/tutorial003_an.py
deleted file mode 100644 (file)
index 2238e3c..0000000
+++ /dev/null
@@ -1,40 +0,0 @@
-from typing import List
-
-from fastapi import FastAPI, File, UploadFile
-from fastapi.responses import HTMLResponse
-from typing_extensions import Annotated
-
-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_form_models/tutorial001_an.py b/docs_src/request_form_models/tutorial001_an.py
deleted file mode 100644 (file)
index 30483d4..0000000
+++ /dev/null
@@ -1,15 +0,0 @@
-from fastapi import FastAPI, Form
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial002_an.py b/docs_src/request_form_models/tutorial002_an.py
deleted file mode 100644 (file)
index bcb0227..0000000
+++ /dev/null
@@ -1,16 +0,0 @@
-from fastapi import FastAPI, Form
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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_pv1_an.py b/docs_src/request_form_models/tutorial002_pv1_an.py
deleted file mode 100644 (file)
index fe9dbc3..0000000
+++ /dev/null
@@ -1,18 +0,0 @@
-from fastapi import FastAPI, Form
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-app = FastAPI()
-
-
-class FormData(BaseModel):
-    username: str
-    password: str
-
-    class Config:
-        extra = "forbid"
-
-
-@app.post("/login/")
-async def login(data: Annotated[FormData, Form()]):
-    return data
diff --git a/docs_src/request_forms/tutorial001_an.py b/docs_src/request_forms/tutorial001_an.py
deleted file mode 100644 (file)
index 677fbf2..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-from fastapi import FastAPI, Form
-from typing_extensions import Annotated
-
-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_and_files/tutorial001_an.py b/docs_src/request_forms_and_files/tutorial001_an.py
deleted file mode 100644 (file)
index 0ea285a..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-from fastapi import FastAPI, File, Form, UploadFile
-from typing_extensions import Annotated
-
-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/response_model/tutorial001.py b/docs_src/response_model/tutorial001.py
deleted file mode 100644 (file)
index fd1c902..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import Any, List, 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/tutorial001_01.py b/docs_src/response_model/tutorial001_01.py
deleted file mode 100644 (file)
index 98d30d5..0000000
+++ /dev/null
@@ -1,27 +0,0 @@
-from typing import List, 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/tutorial004.py b/docs_src/response_model/tutorial004.py
deleted file mode 100644 (file)
index 10b4803..0000000
+++ /dev/null
@@ -1,26 +0,0 @@
-from typing import List, 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/schema_extra_example/tutorial003_an.py b/docs_src/schema_extra_example/tutorial003_an.py
deleted file mode 100644 (file)
index 23675ab..0000000
+++ /dev/null
@@ -1,35 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial004_an.py b/docs_src/schema_extra_example/tutorial004_an.py
deleted file mode 100644 (file)
index e817302..0000000
+++ /dev/null
@@ -1,44 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial005_an.py b/docs_src/schema_extra_example/tutorial005_an.py
deleted file mode 100644 (file)
index 4b2d9c6..0000000
+++ /dev/null
@@ -1,55 +0,0 @@
-from typing import Union
-
-from fastapi import Body, FastAPI
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/security/tutorial001_an.py b/docs_src/security/tutorial001_an.py
deleted file mode 100644 (file)
index dac915b..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from fastapi import Depends, FastAPI
-from fastapi.security import OAuth2PasswordBearer
-from typing_extensions import Annotated
-
-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/tutorial002_an.py b/docs_src/security/tutorial002_an.py
deleted file mode 100644 (file)
index 291b3bf..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI
-from fastapi.security import OAuth2PasswordBearer
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial003_an.py b/docs_src/security/tutorial003_an.py
deleted file mode 100644 (file)
index 1b7056a..0000000
+++ /dev/null
@@ -1,95 +0,0 @@
-from typing import Union
-
-from fastapi import Depends, FastAPI, HTTPException, status
-from fastapi.security import OAuth2PasswordBearer, OAuth2PasswordRequestForm
-from pydantic import BaseModel
-from typing_extensions import Annotated
-
-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/tutorial004_an.py b/docs_src/security/tutorial004_an.py
deleted file mode 100644 (file)
index 018234e..0000000
+++ /dev/null
@@ -1,148 +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
-from typing_extensions import Annotated
-
-# 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/", response_model=User)
-async def read_users_me(
-    current_user: Annotated[User, Depends(get_current_active_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/tutorial005.py b/docs_src/security/tutorial005.py
deleted file mode 100644 (file)
index fdd73bc..0000000
+++ /dev/null
@@ -1,177 +0,0 @@
-from datetime import datetime, timedelta, timezone
-from typing import List, 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/", response_model=User)
-async def read_users_me(current_user: User = Depends(get_current_active_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/tutorial005_an.py b/docs_src/security/tutorial005_an.py
deleted file mode 100644 (file)
index e1d7b4f..0000000
+++ /dev/null
@@ -1,180 +0,0 @@
-from datetime import datetime, timedelta, timezone
-from typing import List, 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
-from typing_extensions import Annotated
-
-# 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/", response_model=User)
-async def read_users_me(
-    current_user: Annotated[User, Depends(get_current_active_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/tutorial006_an.py b/docs_src/security/tutorial006_an.py
deleted file mode 100644 (file)
index 985e4b2..0000000
+++ /dev/null
@@ -1,12 +0,0 @@
-from fastapi import Depends, FastAPI
-from fastapi.security import HTTPBasic, HTTPBasicCredentials
-from typing_extensions import Annotated
-
-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/tutorial007_an.py b/docs_src/security/tutorial007_an.py
deleted file mode 100644 (file)
index 0d211df..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-import secrets
-
-from fastapi import Depends, FastAPI, HTTPException, status
-from fastapi.security import HTTPBasic, HTTPBasicCredentials
-from typing_extensions import Annotated
-
-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/separate_openapi_schemas/tutorial001.py b/docs_src/separate_openapi_schemas/tutorial001.py
deleted file mode 100644 (file)
index 415eef8..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = 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.py b/docs_src/separate_openapi_schemas/tutorial002.py
deleted file mode 100644 (file)
index 7df9378..0000000
+++ /dev/null
@@ -1,28 +0,0 @@
-from typing import List, Union
-
-from fastapi import FastAPI
-from pydantic import BaseModel
-
-
-class Item(BaseModel):
-    name: str
-    description: Union[str, None] = 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/app02/__init__.py b/docs_src/settings/app02/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/docs_src/settings/app02_an/__init__.py b/docs_src/settings/app02_an/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/docs_src/settings/app02_an/config.py b/docs_src/settings/app02_an/config.py
deleted file mode 100644 (file)
index e17b503..0000000
+++ /dev/null
@@ -1,7 +0,0 @@
-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_an/main.py b/docs_src/settings/app02_an/main.py
deleted file mode 100644 (file)
index 3a578cc..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from functools import lru_cache
-
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/test_main.py b/docs_src/settings/app02_an/test_main.py
deleted file mode 100644 (file)
index 7a04d7e..0000000
+++ /dev/null
@@ -1,23 +0,0 @@
-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/__init__.py b/docs_src/settings/app03/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/docs_src/settings/app03_an/__init__.py b/docs_src/settings/app03_an/__init__.py
deleted file mode 100644 (file)
index e69de29..0000000
diff --git a/docs_src/settings/app03_an/config.py b/docs_src/settings/app03_an/config.py
deleted file mode 100644 (file)
index 08f8f88..0000000
+++ /dev/null
@@ -1,9 +0,0 @@
-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/config_pv1.py b/docs_src/settings/app03_an/config_pv1.py
deleted file mode 100644 (file)
index e1c3ee3..0000000
+++ /dev/null
@@ -1,10 +0,0 @@
-from pydantic 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/app03_an/main.py b/docs_src/settings/app03_an/main.py
deleted file mode 100644 (file)
index 62f3476..0000000
+++ /dev/null
@@ -1,22 +0,0 @@
-from functools import lru_cache
-
-from fastapi import Depends, FastAPI
-from typing_extensions import Annotated
-
-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/sql_databases/tutorial001.py b/docs_src/sql_databases/tutorial001.py
deleted file mode 100644 (file)
index be86ec0..0000000
+++ /dev/null
@@ -1,71 +0,0 @@
-from typing import List, 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/tutorial001_an.py b/docs_src/sql_databases/tutorial001_an.py
deleted file mode 100644 (file)
index 8c000d3..0000000
+++ /dev/null
@@ -1,74 +0,0 @@
-from typing import List, Union
-
-from fastapi import Depends, FastAPI, HTTPException, Query
-from sqlmodel import Field, Session, SQLModel, create_engine, select
-from typing_extensions import Annotated
-
-
-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/tutorial002.py b/docs_src/sql_databases/tutorial002.py
deleted file mode 100644 (file)
index 4350d19..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-from typing import List, 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/sql_databases/tutorial002_an.py b/docs_src/sql_databases/tutorial002_an.py
deleted file mode 100644 (file)
index 15e3d7c..0000000
+++ /dev/null
@@ -1,104 +0,0 @@
-from typing import List, Union
-
-from fastapi import Depends, FastAPI, HTTPException, Query
-from sqlmodel import Field, Session, SQLModel, create_engine, select
-from typing_extensions import Annotated
-
-
-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/websockets/tutorial002_an.py b/docs_src/websockets/tutorial002_an.py
deleted file mode 100644 (file)
index c838fbd..0000000
+++ /dev/null
@@ -1,93 +0,0 @@
-from typing import Union
-
-from fastapi import (
-    Cookie,
-    Depends,
-    FastAPI,
-    Query,
-    WebSocket,
-    WebSocketException,
-    status,
-)
-from fastapi.responses import HTMLResponse
-from typing_extensions import Annotated
-
-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/tutorial003.py b/docs_src/websockets/tutorial003.py
deleted file mode 100644 (file)
index d561633..0000000
+++ /dev/null
@@ -1,83 +0,0 @@
-from typing import List
-
-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")
index cabf48228380dbe05e8fb026438cf95f808b8ed1..c4dd54dec67b7f9488d3e8ada94b05d773b05cb0 100644 (file)
@@ -24,13 +24,7 @@ from starlette.datastructures import UploadFile
 from typing_extensions import Annotated, get_args, get_origin
 
 # Copy from Pydantic v2, compatible with v1
-if sys.version_info < (3, 9):
-    # Pydantic no longer supports Python 3.8, this might be incorrect, but the code
-    # this is used for is also never reached in this codebase, as it's a copy of
-    # Pydantic's lenient_issubclass, just for compatibility with v1
-    # TODO: remove when dropping support for Python 3.8
-    WithArgsTypes: Tuple[Any, ...] = ()
-elif sys.version_info < (3, 10):
+if sys.version_info < (3, 10):
     WithArgsTypes: tuple[Any, ...] = (typing._GenericAlias, types.GenericAlias)  # type: ignore[attr-defined]
 else:
     WithArgsTypes: tuple[Any, ...] = (
index ef4440b1b4f7af95a5476988f4096a58554a6931..ede080c5b3651bb0d8993a582d36aaa3fb311d27 100644 (file)
@@ -200,7 +200,7 @@ relative_files = true
 context = '${CONTEXT}'
 dynamic_context = "test_function"
 omit = [
-    "docs_src/response_model/tutorial003_04.py",
+    "docs_src/response_model/tutorial003_04_py39.py",
     "docs_src/response_model/tutorial003_04_py310.py",
 ]
 
@@ -230,41 +230,30 @@ ignore = [
 
 [tool.ruff.lint.per-file-ignores]
 "__init__.py" = ["F401"]
-"docs_src/dependencies/tutorial007.py" = ["F821"]
-"docs_src/dependencies/tutorial008.py" = ["F821"]
-"docs_src/dependencies/tutorial009.py" = ["F821"]
-"docs_src/dependencies/tutorial010.py" = ["F821"]
-"docs_src/custom_response/tutorial007.py" = ["B007"]
-"docs_src/dataclasses/tutorial003.py" = ["I001"]
-"docs_src/path_operation_advanced_configuration/tutorial007.py" = ["B904"]
+"docs_src/dependencies/tutorial007_py39.py" = ["F821"]
+"docs_src/dependencies/tutorial008_py39.py" = ["F821"]
+"docs_src/dependencies/tutorial009_py39.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.py" = ["B904"]
 "docs_src/path_operation_advanced_configuration/tutorial007_pv1_py39.py" = ["B904"]
-"docs_src/custom_request_and_route/tutorial002.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.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.py" = ["F821"]
 "docs_src/dependencies/tutorial008_an_py39.py" = ["F821"]
-"docs_src/query_params_str_validations/tutorial012_an.py" = ["B006"]
 "docs_src/query_params_str_validations/tutorial012_an_py39.py" = ["B006"]
-"docs_src/query_params_str_validations/tutorial013_an.py" = ["B006"]
 "docs_src/query_params_str_validations/tutorial013_an_py39.py" = ["B006"]
-"docs_src/security/tutorial004.py" = ["B904"]
-"docs_src/security/tutorial004_an.py" = ["B904"]
-"docs_src/security/tutorial004_an_py310.py" = ["B904"]
+"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_py310.py" = ["B904"]
-"docs_src/security/tutorial005.py" = ["B904"]
-"docs_src/security/tutorial005_an.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.py" = ["B904"]
-"docs_src/dependencies/tutorial008b_an.py" = ["B904"]
+"docs_src/dependencies/tutorial008b_py39.py" = ["B904"]
 "docs_src/dependencies/tutorial008b_an_py39.py" = ["B904"]
 
 
index 3afeaff8406918f6fa656eec4141fcb5b1b4ff14..1a18db75ce6411250cda8df85835579441075e23 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.additional_responses.tutorial001 import app
+from docs_src.additional_responses.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 91d6ff101f760e6ebb5e7cd054d895a1544b46db..bbcad8f294785338343ca92fca92fbefa76b1109 100644 (file)
@@ -12,7 +12,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002"),
+        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index bd34d2938c45532873fdd6d5531f6005ac0e4af3..90dc4e371e6f79806ccf1ff307f1c88b14c4477f 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.additional_responses.tutorial003 import app
+from docs_src.additional_responses.tutorial003_py39 import app
 
 client = TestClient(app)
 
index 2d9491467e321e662594d3114176dad7d8ded7a3..cbd4fff7d6be085322d18b64a75c826c6e8423ac 100644 (file)
@@ -12,7 +12,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004"),
+        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index b304f701534cde355002897fabfe83d0c4b39643..bced1f6dfe29a0cad73dfa944d861eadeb4b198e 100644 (file)
@@ -3,16 +3,15 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 157fa5caf1a033b570a8f0de4d943ce3031aa2b5..f17391956eb92bbd5923e1ade0af134f6832b49f 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.advanced_middleware.tutorial001 import app
+from docs_src.advanced_middleware.tutorial001_py39 import app
 
 
 def test_middleware():
index 79be52f4db58c3b537a9f75d7aa83342ceceda15..bae915406e72c8f1a48577685883de9417658942 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.advanced_middleware.tutorial002 import app
+from docs_src.advanced_middleware.tutorial002_py39 import app
 
 
 def test_middleware():
index 04a922ff7bd344c87c357054e15f527317905c3f..66697997c8459b2c58f9ca13746dff27d235f5a1 100644 (file)
@@ -1,7 +1,7 @@
 from fastapi.responses import PlainTextResponse
 from fastapi.testclient import TestClient
 
-from docs_src.advanced_middleware.tutorial003 import app
+from docs_src.advanced_middleware.tutorial003_py39 import app
 
 
 @app.get("/large")
similarity index 58%
rename from tests/test_tutorial/test_async_tests/test_main.py
rename to tests/test_tutorial/test_async_tests/test_main_a.py
index 1f5d7186cc016230e532d530eec1d01500189e48..f29acaa9a0a8def7906cf5ed30d14c3c50f7b0be 100644 (file)
@@ -1,6 +1,6 @@
 import pytest
 
-from docs_src.async_tests.test_main import test_root
+from docs_src.async_tests.app_a_py39.test_main import test_root
 
 
 @pytest.mark.anyio
index bbd7bff30faa2e12197079e63354db2b5c9e41db..6f58116313c557a6cd32454076307b0919df00cf 100644 (file)
@@ -4,14 +4,11 @@ import pytest
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 0602cd8aa451569ce0f2862436986c313ad702ad..c0ad27a6f566c2b4570479f7a6320b1dd4cc66a5 100644 (file)
@@ -3,7 +3,7 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.background_tasks.tutorial001 import app
+from docs_src.background_tasks.tutorial001_py39 import app
 
 client = TestClient(app)
 
index d5ef51ee2b8dab14ad6949dbccf6760fdad8c705..288a1c244e22f1dd80a741bfaaeb1f2bc613b7a9 100644 (file)
@@ -5,16 +5,15 @@ from pathlib import Path
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002",
+        "tutorial002_py39",
         pytest.param("tutorial002_py310", marks=needs_py310),
-        "tutorial002_an",
-        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        "tutorial002_an_py39",
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index a070f850f75930b10c5606d889cfc00e139c1535..00574b5b0fbf02e0cf492107f1e377882c3d2194 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.behind_a_proxy.tutorial001 import app
+from docs_src.behind_a_proxy.tutorial001_py39 import app
 
 client = TestClient(app, root_path="/api/v1")
 
index f13046e018a9d99d6a7c192cd55b1cc328841660..da4acb28cc6cac721939f657c354d098f332981a 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.behind_a_proxy.tutorial001_01 import app
+from docs_src.behind_a_proxy.tutorial001_01_py39 import app
 
 client = TestClient(
     app,
index ce791e2157b31984b88a99bdcbf0ea29daa8a34e..1a49c0dfebd78147da3f194283e48d863dad800e 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.behind_a_proxy.tutorial002 import app
+from docs_src.behind_a_proxy.tutorial002_py39 import app
 
 client = TestClient(app)
 
index ec17b4179001fb0475929933e4c37dddb0e247b9..2d1d1b03c81f89f05ff3f10bb56b962c3f78133d 100644 (file)
@@ -1,7 +1,7 @@
 from dirty_equals import IsOneOf
 from fastapi.testclient import TestClient
 
-from docs_src.behind_a_proxy.tutorial003 import app
+from docs_src.behind_a_proxy.tutorial003_py39 import app
 
 client = TestClient(app)
 
index 2f8eb46995b29a557bafb317e223753aa0303f67..e8a03e81124a08919f95f344da473c035ac6b3d3 100644 (file)
@@ -1,7 +1,7 @@
 from dirty_equals import IsOneOf
 from fastapi.testclient import TestClient
 
-from docs_src.behind_a_proxy.tutorial004 import app
+from docs_src.behind_a_proxy.tutorial004_py39 import app
 
 client = TestClient(app)
 
index fe40fad7d00beb77754797fc7531e8cb155a0e08..7493a9e66132b7b295de92171604cae1a9b5f7c1 100644 (file)
@@ -4,15 +4,12 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "app_an.main",
-        pytest.param("app_an_py39.main", marks=needs_py39),
-        "app.main",
+        "app_py39.main",
+        "app_an_py39.main",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index f8b5aee8d2932d87e589a7ebd548bc19b6f0dd7d..6aa9f2593e574495de1902f45c72472b87bc185a 100644 (file)
@@ -11,7 +11,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index fb68f286898a766e3ec062002c749fc037afb118..d54ec7191afa54242b64a51780c203da8a98e359 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 14240559529b3333d281543de56d9250def89417..2035cf9448d4865f224bc5d2a04dc0c6d34dec02 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index d18ceae4862c5b809ce67c315bf5889faff5956f..d3e6401af229413152651b21685e012142a0da47 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003",
+        "tutorial003_py39",
         pytest.param("tutorial003_py310", marks=needs_py310),
-        "tutorial003_an",
-        pytest.param("tutorial003_an_py39", marks=needs_py39),
+        "tutorial003_an_py39",
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index 38ba3c88751ec73825e0fc70a68459cb14d8df32..db9f04546e3a5866dd085d6d0631b30634d78230 100644 (file)
@@ -4,14 +4,11 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial009",
-        pytest.param("tutorial009_py39", marks=needs_py39),
+        "tutorial009_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index f874dc9bd6597dc2f65030b53e8c73ce8ba7d694..8bbc4d699253a0d9bd113fd7f5d12bbe4845b0ba 100644 (file)
@@ -3,15 +3,14 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_py39", marks=needs_py39),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index b098f259c2f1ae1fbbf0965237f4182f41d86d10..a425e893d85a24ff8fd26319d1c86986116c83f4 100644 (file)
@@ -6,11 +6,11 @@ from ...utils import needs_pydanticv2
 
 
 def get_client() -> TestClient:
-    from docs_src.conditional_openapi import tutorial001
+    from docs_src.conditional_openapi import tutorial001_py39
 
-    importlib.reload(tutorial001)
+    importlib.reload(tutorial001_py39)
 
-    client = TestClient(tutorial001.app)
+    client = TestClient(tutorial001_py39.app)
     return client
 
 
index a04dba2197b4cf217a7e41e4ab1158291cefef65..1fa9419a7670f4435d865190352ab9319b4ef482 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.configure_swagger_ui.tutorial001 import app
+from docs_src.configure_swagger_ui.tutorial001_py39 import app
 
 client = TestClient(app)
 
index ea56b6f21ca38b746b121c6063f33665b6384a9e..c218cc858cac57bd013f940780ac134881fb3729 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.configure_swagger_ui.tutorial002 import app
+from docs_src.configure_swagger_ui.tutorial002_py39 import app
 
 client = TestClient(app)
 
index 926bbb14f0a4db905d339a1d05906183e1971859..8b73685499a5a8a351509afc4efee839216a3b6c 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.configure_swagger_ui.tutorial003 import app
+from docs_src.configure_swagger_ui.tutorial003_py39 import app
 
 client = TestClient(app)
 
index 60643185a4fec39ee0ff0aa55c0a4b7b07826377..265dee944e8a6fba0d65a34083534269f8c46a00 100644 (file)
@@ -5,16 +5,15 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index cef6f66309df893de3165123757ea15e13721d27..4a826a53742e392d74ac84a5c85a6278471c5cd7 100644 (file)
@@ -6,7 +6,6 @@ from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
 from tests.utils import (
-    needs_py39,
     needs_py310,
     needs_pydanticv1,
     needs_pydanticv2,
@@ -17,15 +16,13 @@ from tests.utils import (
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002", marks=needs_pydanticv2),
+        pytest.param("tutorial002_py39", marks=needs_pydanticv2),
         pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_an", marks=needs_pydanticv2),
-        pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
+        pytest.param("tutorial002_an_py39", marks=needs_pydanticv2),
         pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
+        pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1),
         pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
+        pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1),
         pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
     ],
 )
index 90e8dfd37c8cf57d75b4e30e8fc3790c7e68416b..a65249d657c144795d5b94002f549a33d11744c4 100644 (file)
@@ -5,16 +5,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="mod",
     params=[
-        "tutorial001",
+        "tutorial001_py39",
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index f62c9df4f9c3a37c3cbf743939f4c9fddc8444a8..6a733693aed4eb3aa44dbc34b789c33c96813b22 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.cors.tutorial001 import app
+from docs_src.cors.tutorial001_py39 import app
 
 
 def test_cors():
index cb8e8c2248208eb5d08ad11b8727031d32baa487..1816e5d975f6d788392c1cdad0f691920ae56122 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 import app
+    from docs_src.custom_docs_ui.tutorial001_py39 import app
 
     with TestClient(app) as client:
         yield client
index 712618807c054694be2e3aa852f38f4e54eef7b3..e8b7eb7aa32b8fd9c74bce4df125f508eb63909f 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 import app
+    from docs_src.custom_docs_ui.tutorial002_py39 import app
 
     with TestClient(app) as client:
         yield client
index f9fd0d1af88e962616bac52dc4d8152cc530e3ff..b4ea537846c717efbe0523cb734f7ccab2f47a41 100644 (file)
@@ -6,17 +6,15 @@ import pytest
 from fastapi import Request
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001"),
-        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_an"),
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index c35752ed135b63738379901af60ac3f435495ea0..643011637ea0f347666994fcef38bbc29dbf3683 100644 (file)
@@ -4,17 +4,15 @@ import pytest
 from dirty_equals import IsDict, IsOneOf
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002"),
-        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_an"),
-        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 9e895b2dafc2d46fffb35e4f6547750c47249964..6cad7bd3f0287d6bb73bbc030092906dc614af3c 100644 (file)
@@ -9,7 +9,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003"),
+        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index fc8362467362eb72a0400bcb8fbf9287485ffe40..c81e991ebf05814c1be17d95beba6515f8882ce3 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial001 import app
+from docs_src.custom_response.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 91e5c501e3fad25746269a2ec7d8855363200e7f..3337f47d5f7f6084568fb1f2538c0f591007dc24 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial001b import app
+from docs_src.custom_response.tutorial001b_py39 import app
 
 client = TestClient(app)
 
index de60574f5e4ee3587b4b40ec52b7503c0431a183..0e7d69791b4ef393eba56124933061a61527df4b 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial004 import app
+from docs_src.custom_response.tutorial004_py39 import app
 
 client = TestClient(app)
 
index 889bf3e929f4b18723cae60cc160017e6cc71a6c..fea105c28ee317eb52bae386d0fc756fc079c767 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial005 import app
+from docs_src.custom_response.tutorial005_py39 import app
 
 client = TestClient(app)
 
index 2d0a2cd3f6517831152839b616484742a43feeb4..e9e6ca1086b9d5caf51ddd06313ee7ad2c19b2f6 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial006 import app
+from docs_src.custom_response.tutorial006_py39 import app
 
 client = TestClient(app)
 
index 1739fd457076cb85713e4c093b1c860da50a22b8..7ca727d2cd74a90a58194e623085289c2ab7cbaa 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial006b import app
+from docs_src.custom_response.tutorial006b_py39 import app
 
 client = TestClient(app)
 
index 2675f2a93c5ee3e9c363550a0aa05b40a0116eda..e3f76c8403c2e704e1a7c02d0d031feb675e4919 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial006c import app
+from docs_src.custom_response.tutorial006c_py39 import app
 
 client = TestClient(app)
 
index 4ede820b94db9f97406a0043854040fae709085e..a62476ec14392b61aee7b62026fe6e538a86bb62 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial007 import app
+from docs_src.custom_response.tutorial007_py39 import app
 
 client = TestClient(app)
 
index 10d88a594849fbdbffd1036f5b56ada230c165c3..d9fe61f5391973a085025a0606a81448bcb7d6af 100644 (file)
@@ -2,15 +2,15 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response import tutorial008
-from docs_src.custom_response.tutorial008 import app
+from docs_src.custom_response import tutorial008_py39
+from docs_src.custom_response.tutorial008_py39 import app
 
 client = TestClient(app)
 
 
 def test_get(tmp_path: Path):
     file_path: Path = tmp_path / "large-video-file.mp4"
-    tutorial008.some_file_path = str(file_path)
+    tutorial008_py39.some_file_path = str(file_path)
     test_content = b"Fake video bytes"
     file_path.write_bytes(test_content)
     response = client.get("/")
index ac20f89e6704ed08b043e988124ded6285b54ccd..cb6a514be6c2ea119c9731d41717c79834bc34ee 100644 (file)
@@ -2,15 +2,15 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response import tutorial009
-from docs_src.custom_response.tutorial009 import app
+from docs_src.custom_response import tutorial009_py39
+from docs_src.custom_response.tutorial009_py39 import app
 
 client = TestClient(app)
 
 
 def test_get(tmp_path: Path):
     file_path: Path = tmp_path / "large-video-file.mp4"
-    tutorial009.some_file_path = str(file_path)
+    tutorial009_py39.some_file_path = str(file_path)
     test_content = b"Fake video bytes"
     file_path.write_bytes(test_content)
     response = client.get("/")
index 4f56e2f3fe49e3a437dd962808aa3dbeb5178c99..9918bdb1aca0f773310b082679a11a65105df5bf 100644 (file)
@@ -2,15 +2,15 @@ from pathlib import Path
 
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response import tutorial009b
-from docs_src.custom_response.tutorial009b import app
+from docs_src.custom_response import tutorial009b_py39
+from docs_src.custom_response.tutorial009b_py39 import app
 
 client = TestClient(app)
 
 
 def test_get(tmp_path: Path):
     file_path: Path = tmp_path / "large-video-file.mp4"
-    tutorial009b.some_file_path = str(file_path)
+    tutorial009b_py39.some_file_path = str(file_path)
     test_content = b"Fake video bytes"
     file_path.write_bytes(test_content)
     response = client.get("/")
index 23c711abe9a0e5380f8a16a1e890ba1b6e55baa9..efc3a6b4a026922011344ade12e22204a2eb37d5 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.custom_response.tutorial009c import app
+from docs_src.custom_response.tutorial009c_py39 import app
 
 client = TestClient(app)
 
index b36dee76842ecde9a7e50a2c326ac978461a7b4c..d5f230bc423e3e411d8ffbb4744a9c0096e9b1ef 100644 (file)
@@ -10,7 +10,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001"),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index baaea45d8ffd7ed5451648cf8239ce5b4f5c93f7..4cf8933805ce64fe5f0a6aa71b8913aec5ce4f56 100644 (file)
@@ -4,14 +4,13 @@ import pytest
 from dirty_equals import IsDict, IsOneOf
 from fastapi.testclient import TestClient
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002"),
-        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
     ],
 )
index 5728d2b6b358409c3d0bb425c940c883379ca9d1..d8cc45dd69a9b35f72b107bafb501c439002ea5d 100644 (file)
@@ -3,14 +3,13 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial003"),
-        pytest.param("tutorial003_py39", marks=needs_py39),
+        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index ed9944912e427b4674f1df139ac60cdb62ec92e8..8dac99cf30416cfd60904aa5795e79411954cf5b 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 8221c83d44a970da0ef4307060c274fef446565a..8a1346d0d2b072ab200eee2f55b7ac95c076bb4d 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial004",
+        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
-        "tutorial004_an",
-        pytest.param("tutorial004_an_py39", marks=needs_py39),
+        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
     ],
 )
index 4530762f763e3e6128bcacd8ad466778fe7d56a0..46f0066f9f05ae9e374c00873b4275612f6a6c02 100644 (file)
@@ -4,15 +4,12 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial006",
-        "tutorial006_an",
-        pytest.param("tutorial006_an_py39", marks=needs_py39),
+        pytest.param("tutorial006_py39"),
+        pytest.param("tutorial006_an_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 4d70922657e1b567650cd44b7975d7342502c799..91e00b37055f7e89e9d21ac34ad3eddf0a95d35b 100644 (file)
@@ -3,15 +3,12 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial008b",
-        "tutorial008b_an",
-        pytest.param("tutorial008b_an_py39", marks=needs_py39),
+        pytest.param("tutorial008b_py39"),
+        pytest.param("tutorial008b_an_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 369b0a221d3aef3e9423cd778c6088e4842cbca4..aede6f8d25c4e11d8d1a05889d3e4b8114d883e9 100644 (file)
@@ -5,15 +5,12 @@ import pytest
 from fastapi.exceptions import FastAPIError
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="mod",
     params=[
-        "tutorial008c",
-        "tutorial008c_an",
-        pytest.param("tutorial008c_an_py39", marks=needs_py39),
+        pytest.param("tutorial008c_py39"),
+        pytest.param("tutorial008c_an_py39"),
     ],
 )
 def get_mod(request: pytest.FixtureRequest):
index bc99bb383507e9dcaca03301438b82ab552891b9..5477f8b95316048f2b1613194b6e11e455c06519 100644 (file)
@@ -4,15 +4,12 @@ from types import ModuleType
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="mod",
     params=[
-        "tutorial008d",
-        "tutorial008d_an",
-        pytest.param("tutorial008d_an_py39", marks=needs_py39),
+        pytest.param("tutorial008d_py39"),
+        pytest.param("tutorial008d_an_py39"),
     ],
 )
 def get_mod(request: pytest.FixtureRequest):
index 1ae9ab2cd11b7be0213ddbaada4f90c957df14ab..c433157ea1768e45aa4e999c49a1496b796997eb 100644 (file)
@@ -3,15 +3,12 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial008e",
-        "tutorial008e_an",
-        pytest.param("tutorial008e_an_py39", marks=needs_py39),
+        pytest.param("tutorial008e_py39"),
+        pytest.param("tutorial008e_an_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 0af17e9bc57ddf797ec161e83270c046241e2272..b791ee0aa150c2666c4a6b16781309696c3f2da4 100644 (file)
@@ -4,15 +4,12 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial012",
-        "tutorial012_an",
-        pytest.param("tutorial012_an_py39", marks=needs_py39),
+        pytest.param("tutorial012_py39"),
+        pytest.param("tutorial012_an_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index f65b92d127ff1a0a7ee4a4e675e26e79f66d66a2..5fe99d50df5aab73ab1422e8608630c8c5f27062 100644 (file)
@@ -6,7 +6,7 @@ from fastapi.testclient import TestClient
 @pytest.fixture(name="app", scope="module")
 def get_app():
     with pytest.warns(DeprecationWarning):
-        from docs_src.events.tutorial001 import app
+        from docs_src.events.tutorial001_py39 import app
     yield app
 
 
index 137294d737d8b7b354f8fe29835fdcec9313f60f..0612899b55bca2c3df639c0fab29814e9cd0072e 100644 (file)
@@ -6,7 +6,7 @@ from fastapi.testclient import TestClient
 @pytest.fixture(name="app", scope="module")
 def get_app():
     with pytest.warns(DeprecationWarning):
-        from docs_src.events.tutorial002 import app
+        from docs_src.events.tutorial002_py39 import app
     yield app
 
 
index 0ad1a1f8b24bdf4792751fd1fd0ea9e7112ce56a..38710edfead7a253564197e33ae6436e280cb2a1 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.events.tutorial003 import (
+from docs_src.events.tutorial003_py39 import (
     app,
     fake_answer_to_everything_ml_model,
     ml_models,
index a85a313501428f2b4fbe71637f94b97cc2d2acf4..83ecb300ee597b4195daa802047cb8a26498a1be 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.extending_openapi.tutorial001 import app
+from docs_src.extending_openapi.tutorial001_py39 import app
 
 client = TestClient(app)
 
index b816c9cab50fb48b4eef9b13c1d0c45737ec1982..e11f73fe352f898135473c987116ea26ef5e308e 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 73aa299039895e44e5e98df47a90321618530667..3aa83c0c40062ad9ba5a52aa3a2cb12455f3dd25 100644 (file)
@@ -10,7 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003",
+        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index 7628db30c7d9430ea0f4d882d94b7680a177736d..073375ccc96e2a05bb22fc3767ebd39513859246 100644 (file)
@@ -3,14 +3,11 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial004",
-        pytest.param("tutorial004_py39", marks=needs_py39),
+        pytest.param("tutorial004_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 553e4423852c8608d28644ca296a62601f11b12b..8e52d8d4bab7681d7046d7435752bb4f648ec9f0 100644 (file)
@@ -3,14 +3,11 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial005",
-        pytest.param("tutorial005_py39", marks=needs_py39),
+        pytest.param("tutorial005_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 6cc9fc22826dd5e163ea35417cb6d40866de877a..c102bb99999a11bb8e225e3238c4a30e4ae4f687 100644 (file)
@@ -1,7 +1,7 @@
 import pytest
 from fastapi.testclient import TestClient
 
-from docs_src.first_steps.tutorial001 import app
+from docs_src.first_steps.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 1cd9678a1c8e4bc1a6e0e7cf00714817e54e7ea8..bac52e4fd6307b51b56b4930a7e3f664bf86034c 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.generate_clients.tutorial003 import app
+from docs_src.generate_clients.tutorial003_py39 import app
 
 client = TestClient(app)
 
index 8809c135bd706cbb18e1438335b1a2807035a261..c01850fae6549481989d5b5963b340f05311c822 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.handling_errors.tutorial001 import app
+from docs_src.handling_errors.tutorial001_py39 import app
 
 client = TestClient(app)
 
index efd86ebdecd462b70f7eac7b763bb654c55a4646..09366a86fa03c2584a27eda6017775ca4b4b0013 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.handling_errors.tutorial002 import app
+from docs_src.handling_errors.tutorial002_py39 import app
 
 client = TestClient(app)
 
index 4763f68f3fabb0cc1a4da3279b3566f99093808b..51ac3e7b28a35b31f97ca5ab91c57e6c3cb30699 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.handling_errors.tutorial003 import app
+from docs_src.handling_errors.tutorial003_py39 import app
 
 client = TestClient(app)
 
index c04bf372456ca0ac43a2c3297e65caf23724354e..376bc8266fd6c7948a4831c490091062da8f387c 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.handling_errors.tutorial004 import app
+from docs_src.handling_errors.tutorial004_py39 import app
 
 client = TestClient(app)
 
index 581b2e4c75178780320aab754447fd3b20a8eb35..d713c5d8761f726bbfa6631035e88ebad7c3d8f4 100644 (file)
@@ -1,7 +1,7 @@
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from docs_src.handling_errors.tutorial005 import app
+from docs_src.handling_errors.tutorial005_py39 import app
 
 client = TestClient(app)
 
index 7d2f553aac8f449338309cb700f1735e0f39858c..491e461b3db6b458157016ec348c4e01190db91b 100644 (file)
@@ -1,7 +1,7 @@
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from docs_src.handling_errors.tutorial006 import app
+from docs_src.handling_errors.tutorial006_py39 import app
 
 client = TestClient(app)
 
index bc876897b21f7190ad696d7e79f80a9cf78eacf9..f59d50762c0fdea9bf0377f80f39fd532ffafd2e 100644 (file)
@@ -5,17 +5,15 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
-        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 0615521c43080e33a9ecdb68ea0d8b7c5b248a45..a7a271ba41cad90a897673c01d7a3e3ea43cf6d8 100644 (file)
@@ -5,21 +5,19 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+from tests.utils import needs_py310, needs_pydanticv1, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002", marks=needs_pydanticv2),
+        pytest.param("tutorial002_py39", marks=needs_pydanticv2),
         pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_an", marks=needs_pydanticv2),
-        pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
+        pytest.param("tutorial002_an_py39", marks=needs_pydanticv2),
         pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
+        pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1),
         pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
+        pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1),
         pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
     ],
 )
index 554a48d2e86475f65c0e96bef4ae1fe708d74005..947587504ff7a2cce5ce53f50f117b9df872ab1c 100644 (file)
@@ -5,17 +5,15 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003",
-        pytest.param("tutorial003_py39", marks=needs_py39),
+        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        "tutorial003_an",
-        pytest.param("tutorial003_an_py39", marks=needs_py39),
+        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index d6f7fe6189aa80edf479f98a4080508788e6ad62..beaf917f924df547a13aee78597f191b19721fa3 100644 (file)
@@ -10,9 +10,9 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 7158f8651b839247bf6d3b4a4e9fceb053e23cae..b892ff905f8f13580c48842663f2567f88e7e320 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002",
+        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        "tutorial002_an",
-        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 473b9612369b3f106df60c27f850a46de0e0d1c0..ef762441590c6b970b6a938d9304f8a4240714d9 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003",
+        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        "tutorial003_an",
-        pytest.param("tutorial003_an_py39", marks=needs_py39),
+        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index 04e8ff82b09c0730a8350e8f3de352240f9a6122..ead48577d053ebf442b393f4df140eb7a9a79815 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.metadata.tutorial001 import app
+from docs_src.metadata.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 3efb1c432932b11024a07deabb6cbff2e43451a6..40878ccfd43824b56a59f4b00e43e163becab7b0 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.metadata.tutorial001_1 import app
+from docs_src.metadata.tutorial001_1_py39 import app
 
 client = TestClient(app)
 
index 5072203712cf626ecabee7b9cf73e91aede1f503..4ef93fd5e3bcd47eb00748156cd52693895d5898 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.metadata.tutorial004 import app
+from docs_src.metadata.tutorial004_py39 import app
 
 client = TestClient(app)
 
index 2df2b98893c9ca37d899646aa28740919aa979c4..975e07cbdd4dcb4215b06c9ed43927cdef7421d1 100644 (file)
@@ -11,7 +11,7 @@ from tests.utils import needs_py310
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial001"),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index dc67ec401d28b37b8dbf7adad96250cc327f8ee9..27619489fa855441f7c291a36af8992b4b2feeca 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.openapi_webhooks.tutorial001 import app
+from docs_src.openapi_webhooks.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 95542398e44f7011142f788fcb07e6aa6afa4fec..ee0b707108242d6be79988f9153c7e621bc8d48b 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.path_operation_advanced_configuration.tutorial001 import app
+from docs_src.path_operation_advanced_configuration.tutorial001_py39 import app
 
 client = TestClient(app)
 
index d1388c367019ecc17cf1e2dcc87ba1f1dbe14d26..f6580d72e3d283ec3c69505b4b88a561b6ae2f1a 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.path_operation_advanced_configuration.tutorial002 import app
+from docs_src.path_operation_advanced_configuration.tutorial002_py39 import app
 
 client = TestClient(app)
 
index 313bb2a04aaca9c191c5ac93b2e3f0539a3c98f4..104554fce388b5b38eb7689a101e9571c0b68239 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.path_operation_advanced_configuration.tutorial003 import app
+from docs_src.path_operation_advanced_configuration.tutorial003_py39 import app
 
 client = TestClient(app)
 
index da5782d189e1d35cdad763027c00a880c7702fbf..3805536e76a4f2caf53fb266d19df484892a8949 100644 (file)
@@ -3,14 +3,13 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial004"),
-        pytest.param("tutorial004_py39", marks=needs_py39),
+        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index 07e2d7d202c0d04a6bee9d8f186a0a456e8d7cca..e2a71236ffc0af69d3ff450d1d6e08770143c81c 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.path_operation_advanced_configuration.tutorial005 import app
+from docs_src.path_operation_advanced_configuration.tutorial005_py39 import app
 
 client = TestClient(app)
 
index f92c59015e099f0da6a3681f78c4f79a55e0620e..9484f7f57348aa204789e7c563dd0bae118baaf7 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.path_operation_advanced_configuration.tutorial006 import app
+from docs_src.path_operation_advanced_configuration.tutorial006_py39 import app
 
 client = TestClient(app)
 
index a90337a63dd70d5711f3f76651ee25055f35fe33..204cca09edf46a8465f2282e0984bd48ffa90ef2 100644 (file)
@@ -3,14 +3,13 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_pydanticv2
+from ...utils import needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial007"),
-        pytest.param("tutorial007_py39", marks=needs_py39),
+        pytest.param("tutorial007_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index b38e4947cca5024df111754886f758a10c2c7bd0..62b67a98c177482401ef342af3b3aa402e6b0ede 100644 (file)
@@ -3,14 +3,13 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_pydanticv1
+from ...utils import needs_pydanticv1
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial007_pv1"),
-        pytest.param("tutorial007_pv1_py39", marks=needs_py39),
+        pytest.param("tutorial007_pv1_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 58dec5769d0d12eaa935443defc4e285d6e74a46..5a0193adfaab2e22557ac9142b0b376244393cf6 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.path_operation_configuration.tutorial002b import app
+from docs_src.path_operation_configuration.tutorial002b_py39 import app
 
 client = TestClient(app)
 
index 0742f5d0e855ddee1ecfed17793ff1a29ea272d9..2a7a2b78b20f83966dbf9a1cc324e7bca94f232f 100644 (file)
@@ -3,14 +3,13 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial005",
-        pytest.param("tutorial005_py39", marks=needs_py39),
+        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
     ],
 )
index 91180d10973ce995a8554d6bcbb69cafe0e0a900..5d9c55675f3588198498ad76cd765969536ccd93 100644 (file)
@@ -1,7 +1,7 @@
 import pytest
 from fastapi.testclient import TestClient
 
-from docs_src.path_operation_configuration.tutorial006 import app
+from docs_src.path_operation_configuration.tutorial006_py39 import app
 
 client = TestClient(app)
 
index acbeaca769895a1ca7f5921e6b8077a6dba6e440..f7f233ccff3814bb7320c990707d8261d5f44537 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.path_params.tutorial004 import app
+from docs_src.path_params.tutorial004_py39 import app
 
 client = TestClient(app)
 
index 2e4b0146bee5f58a19853bbd152396cd36c74c3a..b3be70471af8cd0d6a9caab676120e90ad8a7f77 100644 (file)
@@ -1,7 +1,7 @@
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from docs_src.path_params.tutorial005 import app
+from docs_src.path_params.tutorial005_py39 import app
 
 client = TestClient(app)
 
index 3075a05f51f8281b215b7b9b950a41e9438c8dc8..ce53a36eb8dbe2e2ef847a0ac6578db8f06f39a5 100644 (file)
@@ -23,7 +23,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="mod",
     params=[
-        "tutorial001_an",
+        "tutorial001_an_py39",
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index a402c663d1fc78912742fc067bbb7cf4d15e49a7..57720bf4892a6041ba495fb99878dc3792f3a4bc 100644 (file)
@@ -24,7 +24,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002_an",
+        "tutorial002_an_py39",
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 03155c9249cbb8740d99feb4e17e7cf3303fb73d..f020d4a9756de51cb630366f09840b4a74287ef4 100644 (file)
@@ -23,7 +23,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003_an",
+        "tutorial003_an_py39",
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index d2e204ddafe666d6edf16d0c0d338245af87be9e..daa6f0b05055acd5747f0d57db82a1d50e81de9b 100644 (file)
@@ -17,14 +17,13 @@ import importlib
 
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial004_an",
-        pytest.param("tutorial004_an_py39", marks=needs_py39),
+        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
     ],
 )
index 5b7bc7b42493e670f9f8e55e99ffa48b928beb91..86830b9341eb2d85029c67c2220651a50309ba6b 100644 (file)
@@ -5,17 +5,15 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
-        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 4432c9d8a36747f6da92f57e088a49f8e426c1ef..e7de73f8041e9a54c0b37e2381fcf96ba8ff3871 100644 (file)
@@ -5,23 +5,19 @@ from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from tests.utils import needs_py39, needs_py310, needs_pydanticv1, needs_pydanticv2
+from tests.utils import needs_py310, needs_pydanticv1, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial002", marks=needs_pydanticv2),
-        pytest.param("tutorial002_py39", marks=[needs_py39, needs_pydanticv2]),
+        pytest.param("tutorial002_py39", marks=needs_pydanticv2),
         pytest.param("tutorial002_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_an", marks=needs_pydanticv2),
-        pytest.param("tutorial002_an_py39", marks=[needs_py39, needs_pydanticv2]),
+        pytest.param("tutorial002_an_py39", marks=needs_pydanticv2),
         pytest.param("tutorial002_an_py310", marks=[needs_py310, needs_pydanticv2]),
-        pytest.param("tutorial002_pv1", marks=[needs_pydanticv1, needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_py39", marks=[needs_py39, needs_pydanticv1]),
+        pytest.param("tutorial002_pv1_py39", marks=needs_pydanticv1),
         pytest.param("tutorial002_pv1_py310", marks=[needs_py310, needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an", marks=[needs_pydanticv1]),
-        pytest.param("tutorial002_pv1_an_py39", marks=[needs_py39, needs_pydanticv1]),
+        pytest.param("tutorial002_pv1_an_py39", marks=needs_pydanticv1),
         pytest.param("tutorial002_pv1_an_py310", marks=[needs_py310, needs_pydanticv1]),
     ],
 )
index 05ae85b451fa78a243f72f92c41efcf15ec43696..ad4e4efa6b11fa464d3e6794e951e4b65c4a4d12 100644 (file)
@@ -1,7 +1,7 @@
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from docs_src.query_params.tutorial005 import app
+from docs_src.query_params.tutorial005_py39 import app
 
 client = TestClient(app)
 
index a0b5ef494322df34cd3811b97b67678178428f14..349f8dd223f6cd93f11e4281478fe2bd2907595b 100644 (file)
@@ -10,7 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial006",
+        pytest.param("tutorial006_py39"),
         pytest.param("tutorial006_py310", marks=needs_py310),
     ],
 )
index e08e169633872823157aea84122761981559a23f..de5dbbb2ee7af7234fadd799acd5ec0aed6501e9 100644 (file)
@@ -5,16 +5,15 @@ from dirty_equals import IsDict
 from fastapi._compat import PYDANTIC_VERSION_MINOR_TUPLE
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial010",
+        pytest.param("tutorial010_py39"),
         pytest.param("tutorial010_py310", marks=needs_py310),
-        "tutorial010_an",
-        pytest.param("tutorial010_an_py39", marks=needs_py39),
+        pytest.param("tutorial010_an_py39"),
         pytest.param("tutorial010_an_py310", marks=needs_py310),
     ],
 )
index f4da25752bbf484a36e662ca54f2dd4dcdda2177..50b3c5683cb44f97067a3e0368ebbb148591ee09 100644 (file)
@@ -4,17 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial011",
-        pytest.param("tutorial011_py39", marks=needs_py310),
+        pytest.param("tutorial011_py39"),
         pytest.param("tutorial011_py310", marks=needs_py310),
-        "tutorial011_an",
-        pytest.param("tutorial011_an_py39", marks=needs_py39),
+        pytest.param("tutorial011_an_py39"),
         pytest.param("tutorial011_an_py310", marks=needs_py310),
     ],
 )
index 549a90519e63b001b9e6645f8c4313ad59163f4c..1826928611a89b640425bbc35fefbfde7bf3ff48 100644 (file)
@@ -3,16 +3,12 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial012",
-        pytest.param("tutorial012_py39", marks=needs_py39),
-        "tutorial012_an",
-        pytest.param("tutorial012_an_py39", marks=needs_py39),
+        pytest.param("tutorial012_py39"),
+        pytest.param("tutorial012_an_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index f2f5f7a8589d93596decd3e6ddadedaa97ca165a..46c367c86bc0c40cbac101a8283489e4b90b66fe 100644 (file)
@@ -3,15 +3,12 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial013",
-        "tutorial013_an",
-        pytest.param("tutorial013_an_py39", marks=needs_py39),
+        "tutorial013_py39",
+        "tutorial013_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index edd40bb1ab433a78d3b2bce9ea590c567872695c..0feaccfa44f643f26f4dca286b8521ddbaea683c 100644 (file)
@@ -3,16 +3,15 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial014",
+        pytest.param("tutorial014_py39"),
         pytest.param("tutorial014_py310", marks=needs_py310),
-        "tutorial014_an",
-        pytest.param("tutorial014_an_py39", marks=needs_py39),
+        pytest.param("tutorial014_an_py39"),
         pytest.param("tutorial014_an_py310", marks=needs_py310),
     ],
 )
index ae1c40286d1fcfd99e3277f2ebcbbe79b82fafad..50ebf711f5d1e3fb9066ad4c4fa79d42999adea5 100644 (file)
@@ -5,15 +5,14 @@ from dirty_equals import IsStr
 from fastapi.testclient import TestClient
 from inline_snapshot import snapshot
 
-from ...utils import needs_py39, needs_py310, needs_pydanticv2
+from ...utils import needs_py310, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial015_an", marks=needs_pydanticv2),
+        pytest.param("tutorial015_an_py39", marks=needs_pydanticv2),
         pytest.param("tutorial015_an_py310", marks=(needs_py310, needs_pydanticv2)),
-        pytest.param("tutorial015_an_py39", marks=(needs_py39, needs_pydanticv2)),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index b06919961288481a7d385db73fb16a8fdca8a9f1..a16d951dc6cd78e3c4c945104e0dac3101d0e11c 100644 (file)
@@ -4,15 +4,12 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_py39",
+        "tutorial001_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 9075a1756194d25a2385a7410b800fbb9c5a3c00..caea0d2e8fc9161d850b1ce3f5955fa8e513db65 100644 (file)
@@ -5,16 +5,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_02",
+        pytest.param("tutorial001_02_py39"),
         pytest.param("tutorial001_02_py310", marks=needs_py310),
-        "tutorial001_02_an",
-        pytest.param("tutorial001_02_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_02_an_py39"),
         pytest.param("tutorial001_02_an_py310", marks=needs_py310),
     ],
 )
index 9fbe2166c17b578648c89b9400e3832593c47c23..53a7a0cf85ca4a3bfdb18d0b41c9f1dc56c66665 100644 (file)
@@ -3,15 +3,12 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_03",
-        "tutorial001_03_an",
-        pytest.param("tutorial001_03_an_py39", marks=needs_py39),
+        "tutorial001_03_py39",
+        "tutorial001_03_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 446a8765784f8116b25dc26e0366ef7c15674579..34dbbb985dae4b5064e212c9da42901ed28ebbd0 100644 (file)
@@ -5,16 +5,12 @@ from dirty_equals import IsDict
 from fastapi import FastAPI
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="app",
     params=[
-        "tutorial002",
-        "tutorial002_an",
-        pytest.param("tutorial002_py39", marks=needs_py39),
-        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        "tutorial002_py39",
+        "tutorial002_an_py39",
     ],
 )
 def get_app(request: pytest.FixtureRequest):
index 8534ba3e9a2efbf9fd92cf2cd7739d6bcffd1485..fa4bfd569547281f35fd89c168003cbaebae3e85 100644 (file)
@@ -4,16 +4,12 @@ import pytest
 from fastapi import FastAPI
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="app",
     params=[
-        "tutorial003",
-        "tutorial003_an",
-        pytest.param("tutorial003_py39", marks=needs_py39),
-        pytest.param("tutorial003_an_py39", marks=needs_py39),
+        "tutorial003_py39",
+        "tutorial003_an_py39",
     ],
 )
 def get_app(request: pytest.FixtureRequest):
index 1ca3c96d331aad557381c1d759d0a69dcc38a29c..a54df8536c0f60455ff2388c54acbd27fb91d12e 100644 (file)
@@ -4,15 +4,12 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_py39",
+        "tutorial001_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index b3f6be63ab96094af9db6bb225f46dd19b81cc49..9bb90fa064af813a06e9d56d911094f34e8b9ded 100644 (file)
@@ -3,15 +3,14 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_pydanticv2
+from ...utils import needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002",
-        "tutorial002_an",
-        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        "tutorial002_py39",
+        "tutorial002_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index b503f23a535da55c4d3b6e235aadbed8fdcf64cd..41c7833beff55e747174511b22b7e3fafc2e2ed2 100644 (file)
@@ -3,15 +3,14 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_pydanticv1
+from ...utils import needs_pydanticv1
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002_pv1",
-        "tutorial002_pv1_an",
-        pytest.param("tutorial002_pv1_an_py39", marks=needs_py39),
+        "tutorial002_pv1_py39",
+        "tutorial002_pv1_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 321f8022b7179356aa9f15663c24c503e7ad6d36..da20535cf883ca7c450f00b5e99a0de8bdc0024f 100644 (file)
@@ -4,15 +4,12 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_py39",
+        "tutorial001_an_py39",
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index d12219245e741dd8ee131c1f117a30c355f6e198..f37ffad44337b5be9f4aaf9530eff1da2ed914b0 100644 (file)
@@ -5,15 +5,12 @@ from dirty_equals import IsDict
 from fastapi import FastAPI
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="app",
     params=[
-        "tutorial001",
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        "tutorial001_py39",
+        "tutorial001_an_py39",
     ],
 )
 def get_app(request: pytest.FixtureRequest):
index 8ce3dcf1abdcb5dddc89950da93c96abd15fcf3c..05d5ca619f34407149d0a065c7e9a3bccb9b6cd2 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_change_status_code.tutorial001 import app
+from docs_src.response_change_status_code.tutorial001_py39 import app
 
 client = TestClient(app)
 
index eecd1a24c9096b08af29b049dfbab496be99e584..6b931c8bdaa1b7ca6e9e2f40ce43a58faaa04165 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_cookies.tutorial001 import app
+from docs_src.response_cookies.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 3e390025fa9f11819e4017cc5efb7a86f9734d51..3ee5f500c529f79215430878183939f5bd5be1b6 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_cookies.tutorial002 import app
+from docs_src.response_cookies.tutorial002_py39 import app
 
 client = TestClient(app)
 
index 2cc4f3b0c11d0db0954eb60a02c72070619a5154..127f0e4c1d6106eb11d13bb5e9cbc5617b5bf857 100644 (file)
@@ -9,7 +9,7 @@ from ...utils import needs_py310, needs_pydanticv1, needs_pydanticv2
 @pytest.fixture(
     name="client",
     params=[
-        pytest.param("tutorial001"),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index 1549d6b5b1a03c17518dad6de97d1d3409f3a4e1..6232aad23ea1ab2f7e679ca67d72c51c2e0bc885 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_headers.tutorial001 import app
+from docs_src.response_headers.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 2826833f84dd0866492e9b1e9115e83c2a53fa11..2ac2226cb1700cb36433ba790f663a60d1213f2f 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_headers.tutorial002 import app
+from docs_src.response_headers.tutorial002_py39 import app
 
 client = TestClient(app)
 
index 70cfd6e4cc2a30276c8e6e74d28bac0664bc6a00..0f9eac890b41a1a50a8d982b5e5f760154300cae 100644 (file)
@@ -10,7 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003",
+        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
     ],
 )
index 3975856b6cf153e767ab364f155ab1ceaa747f69..1a7ce4c7a1e2b5394d1820aba4ce6260830d4080 100644 (file)
@@ -10,7 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003_01",
+        pytest.param("tutorial003_01_py39"),
         pytest.param("tutorial003_01_py310", marks=needs_py310),
     ],
 )
index eabd203456583dcdd2e037ad974b2fcc37f11c0d..b7507b71105547bd988c136b18723e4b96db5c8c 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_model.tutorial003_02 import app
+from docs_src.response_model.tutorial003_02_py39 import app
 
 client = TestClient(app)
 
index 970ff5845000086c8b13d72112779a9569f034b7..ea3c733b249ef437a99b9fcf09c12b0cba1b12ad 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.response_model.tutorial003_03 import app
+from docs_src.response_model.tutorial003_03_py39 import app
 
 client = TestClient(app)
 
index f32e93ddcb8cc85c5e726af17092954bf67c8575..145af126fde0fe27173ac15cde7ece9ff0432222 100644 (file)
@@ -9,7 +9,7 @@ from ...utils import needs_py310
 @pytest.mark.parametrize(
     "module_name",
     [
-        "tutorial003_04",
+        pytest.param("tutorial003_04_py39"),
         pytest.param("tutorial003_04_py310", marks=needs_py310),
     ],
 )
index 9500852e15705243fafa63038ec9aaf4d8032ec1..19a7c601bb482df6e9673814cafa1e5a14030628 100644 (file)
@@ -9,7 +9,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003_05",
+        pytest.param("tutorial003_05_py39"),
         pytest.param("tutorial003_05_py310", marks=needs_py310),
     ],
 )
index 449a52b8138a49c31f7c98f0f36dfa2dc1b67329..19f6998f70b585166863e131f89fc8493cbcf584 100644 (file)
@@ -4,14 +4,13 @@ import pytest
 from dirty_equals import IsDict, IsOneOf
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial004",
-        pytest.param("tutorial004_py39", marks=needs_py39),
+        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
     ],
 )
index a633a3fddd6f352b76862c03aaddc56c57dee94d..47d77dc4988e5dd52603fd2ad9bbab6e05a2bcc5 100644 (file)
@@ -10,7 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial005",
+        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
     ],
 )
index 863522d1b4ceb0cf19307a8c4ea5088bc30e7b55..a03aa41e8cc91f5f057163c0f89ec44109401135 100644 (file)
@@ -10,7 +10,7 @@ from ...utils import needs_py310
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial006",
+        pytest.param("tutorial006_py39"),
         pytest.param("tutorial006_py310", marks=needs_py310),
     ],
 )
index c21cbb4bc217239587e60e39fb0c8bece023fee6..4d1808cf6a233b46045b69226f3c5c432adaf2be 100644 (file)
@@ -9,7 +9,7 @@ from ...utils import needs_py310, needs_pydanticv2
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
     ],
 )
index b79f42e642b5097f7732e6fb16b52b8f8e84b5df..552bb66970c651ca5a70481175f5049033cae7d5 100644 (file)
@@ -9,7 +9,7 @@ from ...utils import needs_py310, needs_pydanticv1
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001_pv1",
+        pytest.param("tutorial001_pv1_py39"),
         pytest.param("tutorial001_pv1_py310", marks=needs_py310),
     ],
 )
index 61aefd12a8bb9a1f842e62e8e57d7412321edc0e..47ecb9ba7372fc69d6f94286703f98b6164c3056 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial004",
+        pytest.param("tutorial004_py39"),
         pytest.param("tutorial004_py310", marks=needs_py310),
-        "tutorial004_an",
-        pytest.param("tutorial004_an_py39", marks=needs_py39),
+        pytest.param("tutorial004_an_py39"),
         pytest.param("tutorial004_an_py310", marks=needs_py310),
     ],
 )
index 12859227b12eafe2b07dc3b0dc29435b379b5b61..1c964f3d15d7854c7115bc5e922f463fa796e689 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial005",
+        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
-        "tutorial005_an",
-        pytest.param("tutorial005_an_py39", marks=needs_py39),
+        pytest.param("tutorial005_an_py39"),
         pytest.param("tutorial005_an_py310", marks=needs_py310),
     ],
 )
index f572d6e3e1d26734dd123071557a8d6a9997da91..cdaa50b191804582938c95aa9dee55a0e3f79aab 100644 (file)
@@ -3,15 +3,12 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_py39"),
+        pytest.param("tutorial001_an_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 6b873511396fc9659c471eb08ccd51725e7f45ad..000c8b2ac4a65068aad3de1540b51a875d0325fb 100644 (file)
@@ -4,16 +4,15 @@ import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial003",
+        pytest.param("tutorial003_py39"),
         pytest.param("tutorial003_py310", marks=needs_py310),
-        "tutorial003_an",
-        pytest.param("tutorial003_an_py39", marks=needs_py39),
+        pytest.param("tutorial003_an_py39"),
         pytest.param("tutorial003_an_py310", marks=needs_py310),
     ],
 )
index ad644d61bbaefab2adeb349b022b030b2f9ac4dc..7953e8e3f6b892586ecdb789a9047a598c85d47d 100644 (file)
@@ -5,17 +5,15 @@ import pytest
 from dirty_equals import IsDict, IsOneOf
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="mod",
     params=[
-        "tutorial005",
+        pytest.param("tutorial005_py39"),
         pytest.param("tutorial005_py310", marks=needs_py310),
-        "tutorial005_an",
-        pytest.param("tutorial005_py39", marks=needs_py39),
-        pytest.param("tutorial005_an_py39", marks=needs_py39),
+        pytest.param("tutorial005_an_py39"),
         pytest.param("tutorial005_an_py310", marks=needs_py310),
     ],
 )
index 9587159dc276f659fef73cd3d7b4477ad5f939f8..a4b3104bbcbd04877713bbd5e4b21e3a5d193083 100644 (file)
@@ -4,15 +4,12 @@ from base64 import b64encode
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial006",
-        "tutorial006_an",
-        pytest.param("tutorial006_an_py39", marks=needs_py39),
+        pytest.param("tutorial006_py39"),
+        pytest.param("tutorial006_an_py39"),
     ],
 )
 def get_client(request: pytest.FixtureRequest):
index 059fb889b3fea1fafdeb6cce1ff7f242326685a2..b59d799a310e55af73566b562f1544496b3933b5 100644 (file)
@@ -3,15 +3,14 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310, needs_pydanticv2
+from ...utils import needs_py310, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        pytest.param("tutorial001_py39", marks=needs_py39),
     ],
 )
 def get_client(request: pytest.FixtureRequest) -> TestClient:
index cc9afeab75cb20fd523e1f850c7c1c153a83d125..61fbacfc34d839eb92378f8fba5f5770fd30cc9a 100644 (file)
@@ -3,15 +3,14 @@ import importlib
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39, needs_py310, needs_pydanticv2
+from ...utils import needs_py310, needs_pydanticv2
 
 
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002",
+        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        pytest.param("tutorial002_py39", marks=needs_py39),
     ],
 )
 def get_client(request: pytest.FixtureRequest) -> TestClient:
index 5e1232ea01553dd7604e6465ef82b40dd260d90c..9cedc5a5264acf6df3b7c2260a2b2fddc9f6570c 100644 (file)
@@ -4,15 +4,14 @@ from types import ModuleType
 import pytest
 from pytest import MonkeyPatch
 
-from ...utils import needs_py39, needs_pydanticv2
+from ...utils import needs_pydanticv2
 
 
 @pytest.fixture(
     name="mod_path",
     params=[
-        pytest.param("app02"),
-        pytest.param("app02_an"),
-        pytest.param("app02_an_py39", marks=needs_py39),
+        pytest.param("app02_py39"),
+        pytest.param("app02_an_py39"),
     ],
 )
 def get_mod_path(request: pytest.FixtureRequest):
index d9872c15f28ba984714ffec8b3b948fe110ee499..dbaf8f3f900175010ecb385785273bb30f802770 100644 (file)
@@ -5,15 +5,14 @@ import pytest
 from fastapi.testclient import TestClient
 from pytest import MonkeyPatch
 
-from ...utils import needs_py39, needs_pydanticv1, needs_pydanticv2
+from ...utils import needs_pydanticv1, needs_pydanticv2
 
 
 @pytest.fixture(
     name="mod_path",
     params=[
-        pytest.param("app03"),
-        pytest.param("app03_an"),
-        pytest.param("app03_an_py39", marks=needs_py39),
+        pytest.param("app03_py39"),
+        pytest.param("app03_an_py39"),
     ],
 )
 def get_mod_path(request: pytest.FixtureRequest):
index 92a5782d4ded1cfcda409551e80e75b970afa8f8..2c6dce261fe74e38b4e2807743dbe14287ab7b17 100644 (file)
@@ -10,8 +10,8 @@ from ...utils import needs_pydanticv1, needs_pydanticv2
 @pytest.fixture(
     name="app",
     params=[
-        pytest.param("tutorial001", marks=needs_pydanticv2),
-        pytest.param("tutorial001_pv1", marks=needs_pydanticv1),
+        pytest.param("tutorial001_py39", marks=needs_pydanticv2),
+        pytest.param("tutorial001_pv1_py39", marks=needs_pydanticv1),
     ],
 )
 def get_app(request: pytest.FixtureRequest, monkeypatch: MonkeyPatch):
index b45be4884d25a56275008eb14cdf5e4ced9de7ae..e3e6bac12842ba0d00068b4c95b7b45756e0e1b6 100644 (file)
@@ -9,7 +9,7 @@ from sqlalchemy import StaticPool
 from sqlmodel import SQLModel, create_engine
 from sqlmodel.main import default_registry
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 def clear_sqlmodel():
@@ -22,11 +22,9 @@ def clear_sqlmodel():
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial001",
-        pytest.param("tutorial001_py39", marks=needs_py39),
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index da0b8b7ce70fb570d8e5142dd9c7cef1b41c45ba..e3b8c7f9e43f506fb123dc613b6f23232c040422 100644 (file)
@@ -9,7 +9,7 @@ from sqlalchemy import StaticPool
 from sqlmodel import SQLModel, create_engine
 from sqlmodel.main import default_registry
 
-from tests.utils import needs_py39, needs_py310
+from tests.utils import needs_py310
 
 
 def clear_sqlmodel():
@@ -22,11 +22,9 @@ def clear_sqlmodel():
 @pytest.fixture(
     name="client",
     params=[
-        "tutorial002",
-        pytest.param("tutorial002_py39", marks=needs_py39),
+        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        "tutorial002_an",
-        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 0790d207be10b752a921658bfd3f86bb9caa002d..ef1f80164b082a58b70936982a5e86a11e57add4 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.sub_applications.tutorial001 import app
+from docs_src.sub_applications.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 4d4729425e845247a7813356578075cd956387ec..818508037df8c0d7f141f405672fb956ce10e0b5 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 import app
+    from docs_src.templates.tutorial001_py39 import app
 
     client = TestClient(app)
     response = client.get("/items/foo")
similarity index 90%
rename from tests/test_tutorial/test_testing/test_main.py
rename to tests/test_tutorial/test_testing/test_main_a.py
index fe349808136cf16e4f2f3647e0a0baa866bc0af0..9b3c796bdc416b3ebfa4a265cf4227130dab11f9 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.app_testing.test_main import client, test_read_main
+from docs_src.app_testing.app_a_py39.test_main import client, test_read_main
 
 
 def test_main():
index aa7f969c6d612fca57ca0b59e74bbcbbeb5effbe..3d679cd5a684d3ab79fdc7af9eb2b0d7350cc543 100644 (file)
@@ -3,16 +3,15 @@ from types import ModuleType
 
 import pytest
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="test_module",
     params=[
-        "app_b.test_main",
+        "app_b_py39.test_main",
         pytest.param("app_b_py310.test_main", marks=needs_py310),
-        "app_b_an.test_main",
-        pytest.param("app_b_an_py39.test_main", marks=needs_py39),
+        "app_b_an_py39.test_main",
         pytest.param("app_b_an_py310.test_main", marks=needs_py310),
     ],
 )
index 471e896c93cac851b2fb16e1d8e1f13268c55d82..5f6533306efa181e6af844c0b4170c9a2ba35780 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.app_testing.tutorial001 import client, test_read_main
+from docs_src.app_testing.tutorial001_py39 import client, test_read_main
 
 
 def test_main():
index ec4f91ee7f04793a81297a0b3bb217c2c170deec..cc9b5ba27c48cfc7573248cd7a4e2b7777569ce4 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.app_testing.tutorial002 import test_read_main, test_websocket
+from docs_src.app_testing.tutorial002_py39 import test_read_main, test_websocket
 
 
 def test_main():
index 2a5d67071260f9b28edfd3d50373a2cc326ec757..4faa820e98e48353560baaab6bab329951cb819b 100644 (file)
@@ -3,5 +3,5 @@ import pytest
 
 def test_main():
     with pytest.warns(DeprecationWarning):
-        from docs_src.app_testing.tutorial003 import test_read_items
+        from docs_src.app_testing.tutorial003_py39 import test_read_items
     test_read_items()
index 812ee44c1f68f14f8d2f227f5d08fc3547d3b69c..c95214ffe32b93698765b082d2191d79726f0650 100644 (file)
@@ -1,4 +1,4 @@
-from docs_src.app_testing.tutorial004 import test_read_items
+from docs_src.app_testing.tutorial004_py39 import test_read_items
 
 
 def test_main():
index 00ee6ab1eab26931faa73d76c9c20a787145ec75..6e9656bf559d528f2163d3f0a075a6fc6ac362e4 100644 (file)
@@ -3,16 +3,15 @@ from types import ModuleType
 
 import pytest
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="test_module",
     params=[
-        "tutorial001",
+        pytest.param("tutorial001_py39"),
         pytest.param("tutorial001_py310", marks=needs_py310),
-        "tutorial001_an",
-        pytest.param("tutorial001_an_py39", marks=needs_py39),
+        pytest.param("tutorial001_an_py39"),
         pytest.param("tutorial001_an_py310", marks=needs_py310),
     ],
 )
index 54c53ae1e31b94130a85463d8af0709e1f4870c4..33e661b16484c5f4b760c25ee77456c657c38a5e 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.using_request_directly.tutorial001 import app
+from docs_src.using_request_directly.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 7dbecb26502eebdcca01326dc7bb4ee6c1f93723..4f8368db289331cff501ed218513f4e1c2d5520f 100644 (file)
@@ -2,7 +2,7 @@ import pytest
 from fastapi.testclient import TestClient
 from fastapi.websockets import WebSocketDisconnect
 
-from docs_src.websockets.tutorial001 import app
+from docs_src.websockets.tutorial001_py39 import app
 
 client = TestClient(app)
 
index 51aa5752a6d5b95b45ca85b97de9d330a44de51f..ebf1fc8e8111db6dc82c46994e8ff5fdfd25882a 100644 (file)
@@ -5,16 +5,15 @@ from fastapi import FastAPI
 from fastapi.testclient import TestClient
 from fastapi.websockets import WebSocketDisconnect
 
-from ...utils import needs_py39, needs_py310
+from ...utils import needs_py310
 
 
 @pytest.fixture(
     name="app",
     params=[
-        "tutorial002",
+        pytest.param("tutorial002_py39"),
         pytest.param("tutorial002_py310", marks=needs_py310),
-        "tutorial002_an",
-        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        pytest.param("tutorial002_an_py39"),
         pytest.param("tutorial002_an_py310", marks=needs_py310),
     ],
 )
index 85efc185901492e8037f57a991eb1910fd42e23d..f303990f03d5db85ea9256df9b353650402ac137 100644 (file)
@@ -4,14 +4,11 @@ from types import ModuleType
 import pytest
 from fastapi.testclient import TestClient
 
-from ...utils import needs_py39
-
 
 @pytest.fixture(
     name="mod",
     params=[
-        pytest.param("tutorial003"),
-        pytest.param("tutorial003_py39", marks=needs_py39),
+        pytest.param("tutorial003_py39"),
     ],
 )
 def get_mod(request: pytest.FixtureRequest):
@@ -32,13 +29,11 @@ def get_client(mod: ModuleType):
     return client
 
 
-@needs_py39
 def test_get(client: TestClient, html: str):
     response = client.get("/")
     assert response.text == html
 
 
-@needs_py39
 def test_websocket_handle_disconnection(client: TestClient):
     with client.websocket_connect("/ws/1234") as connection, client.websocket_connect(
         "/ws/5678"
index 4f822527390ce31cf074dd8bb88c4d5c27ff71f5..9fe8c2a4b826259921d3b48e78cabcfcd6db3dc9 100644 (file)
@@ -1,6 +1,6 @@
 from fastapi.testclient import TestClient
 
-from docs_src.wsgi.tutorial001 import app
+from docs_src.wsgi.tutorial001_py39 import app
 
 client = TestClient(app)