✅ Simplify tests for header_params

@@ -1,10 +1,26 @@
+import importlib
+
 import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient

-from docs_src.header_params.tutorial001 import app
+from ...utils import needs_py310
+
+
+[USER_REDACTED].fixture(
+    name="client",
+    params=[
+        "tutorial001",
+        pytest.param("tutorial001_py310", marks=needs_py310),
+        "tutorial001_an",
+        pytest.param("tutorial001_an_py310", marks=needs_py310),
+    ],
+)
+def get_client(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.header_params.{request.param}")

-client = TestClient(app)
+    client = TestClient(mod.app)
+    return client

 [USER_REDACTED].mark.parametrize(
@@ -15,13 +31,13 @@
         ("/items", {"User-Agent": "FastAPI test"}, 200, {"User-Agent": "FastAPI test"}),
     ],
 )
-def test(path, headers, expected_status, expected_response):
+def test(path, headers, expected_status, expected_response, client: TestClient):
     response = client.get(path, headers=headers)
     assert response.status_code == expected_status
     assert response.json() == expected_response

-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200
     assert response.json() == {

@@ -1,102 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from docs_src.header_params.tutorial001_an import app
-
-client = TestClient(app)
-
-
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"User-Agent": "testclient"}),
-        ("/items", {"X-Header": "notvalid"}, 200, {"User-Agent": "testclient"}),
-        ("/items", {"User-Agent": "FastAPI test"}, 200, {"User-Agent": "FastAPI test"}),
-    ],
-)
-def test(path, headers, expected_status, expected_response):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "User-Agent",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "User-Agent", "type": "string"}
-                            ),
-                            "name": "user-agent",
-                            "in": "header",
-                        }
-                    ],
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }

@@ -1,110 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial001_an_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py310
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"User-Agent": "testclient"}),
-        ("/items", {"X-Header": "notvalid"}, 200, {"User-Agent": "testclient"}),
-        ("/items", {"User-Agent": "FastAPI test"}, 200, {"User-Agent": "FastAPI test"}),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "User-Agent",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "User-Agent", "type": "string"}
-                            ),
-                            "name": "user-agent",
-                            "in": "header",
-                        }
-                    ],
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }

@@ -1,110 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial001_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py310
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"User-Agent": "testclient"}),
-        ("/items", {"X-Header": "notvalid"}, 200, {"User-Agent": "testclient"}),
-        ("/items", {"User-Agent": "FastAPI test"}, 200, {"User-Agent": "FastAPI test"}),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "User-Agent",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "User-Agent", "type": "string"}
-                            ),
-                            "name": "user-agent",
-                            "in": "header",
-                        }
-                    ],
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }

@@ -1,10 +1,27 @@
+import importlib
+
 import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient

-from docs_src.header_params.tutorial002 import app
+from ...utils import needs_py39, needs_py310
+
+
+[USER_REDACTED].fixture(
+    name="client",
+    params=[
+        "tutorial002",
+        pytest.param("tutorial002_py310", marks=needs_py310),
+        "tutorial002_an",
+        pytest.param("tutorial002_an_py39", marks=needs_py39),
+        pytest.param("tutorial002_an_py310", marks=needs_py310),
+    ],
+)
+def get_client(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.header_params.{request.param}")

-client = TestClient(app)
+    client = TestClient(mod.app)
+    return client

 [USER_REDACTED].mark.parametrize(
@@ -26,13 +43,13 @@
         ),
     ],
 )
-def test(path, headers, expected_status, expected_response):
+def test(path, headers, expected_status, expected_response, client: TestClient):
     response = client.get(path, headers=headers)
     assert response.status_code == expected_status
     assert response.json() == expected_response

-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200
     assert response.json() == {

@@ -1,113 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from docs_src.header_params.tutorial002_an import app
-
-client = TestClient(app)
-
-
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"strange_header": None}),
-        ("/items", {"X-Header": "notvalid"}, 200, {"strange_header": None}),
-        (
-            "/items",
-            {"strange_header": "FastAPI test"},
-            200,
-            {"strange_header": "FastAPI test"},
-        ),
-        (
-            "/items",
-            {"strange-header": "Not really underscore"},
-            200,
-            {"strange_header": None},
-        ),
-    ],
-)
-def test(path, headers, expected_status, expected_response):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "[NAME_REDACTED]",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "[NAME_REDACTED]", "type": "string"}
-                            ),
-                            "name": "strange_header",
-                            "in": "header",
-                        }
-                    ],
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }

@@ -1,121 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial002_an_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py310
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"strange_header": None}),
-        ("/items", {"X-Header": "notvalid"}, 200, {"strange_header": None}),
-        (
-            "/items",
-            {"strange_header": "FastAPI test"},
-            200,
-            {"strange_header": "FastAPI test"},
-        ),
-        (
-            "/items",
-            {"strange-header": "Not really underscore"},
-            200,
-            {"strange_header": None},
-        ),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "[NAME_REDACTED]",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "[NAME_REDACTED]", "type": "string"}
-                            ),
-                            "name": "strange_header",
-                            "in": "header",
-                        }
-                    ],
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }

@@ -1,124 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial002_an_py39 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py39
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"strange_header": None}),
-        ("/items", {"X-Header": "notvalid"}, 200, {"strange_header": None}),
-        (
-            "/items",
-            {"strange_header": "FastAPI test"},
-            200,
-            {"strange_header": "FastAPI test"},
-        ),
-        (
-            "/items",
-            {"strange-header": "Not really underscore"},
-            200,
-            {"strange_header": None},
-        ),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py39
-def test_openapi_schema():
-    from docs_src.header_params.tutorial002_an_py39 import app
-
-    client = TestClient(app)
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "[NAME_REDACTED]",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "[NAME_REDACTED]", "type": "string"}
-                            ),
-                            "name": "strange_header",
-                            "in": "header",
-                        }
-                    ],
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }

@@ -1,124 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial002_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py310
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"strange_header": None}),
-        ("/items", {"X-Header": "notvalid"}, 200, {"strange_header": None}),
-        (
-            "/items",
-            {"strange_header": "FastAPI test"},
-            200,
-            {"strange_header": "FastAPI test"},
-        ),
-        (
-            "/items",
-            {"strange-header": "Not really underscore"},
-            200,
-            {"strange_header": None},
-        ),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py310
-def test_openapi_schema():
-    from docs_src.header_params.tutorial002_py310 import app
-
-    client = TestClient(app)
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "anyOf": [{"type": "string"}, {"type": "null"}],
-                                    "title": "[NAME_REDACTED]",
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {"title": "[NAME_REDACTED]", "type": "string"}
-                            ),
-                            "name": "strange_header",
-                            "in": "header",
-                        }
-                    ],
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-            }
-        },
-    }

@@ -1,32 +1,45 @@
+import importlib
+
 import pytest
 from dirty_equals import IsDict
 from fastapi.testclient import TestClient

-from docs_src.header_params.tutorial003 import app
+from ...utils import needs_py39, needs_py310
+
+
+[USER_REDACTED].fixture(
+    name="client",
+    params=[
+        "tutorial003",
+        pytest.param("tutorial003_py310", marks=needs_py310),
+        "tutorial003_an",
+        pytest.param("tutorial003_an_py39", marks=needs_py39),
+        pytest.param("tutorial003_an_py310", marks=needs_py310),
+    ],
+)
+def get_client(request: pytest.FixtureRequest):
+    mod = importlib.import_module(f"docs_src.header_params.{request.param}")

-client = TestClient(app)
+    client = TestClient(mod.app)
+    return client

 [USER_REDACTED].mark.parametrize(
     "path,headers,expected_status,expected_response",
     [
         ("/items", None, 200, {"X-Token values": None}),
         ("/items", {"x-token": "foo"}, 200, {"X-Token values": ["foo"]}),
-        (
-            "/items",
-            [("x-token", "foo"), ("x-token", "bar")],
-            200,
-            {"X-Token values": ["foo", "bar"]},
-        ),
+        # TODO: fix this, is it a bug?
+        # ("/items", [("x-token", "foo"), ("x-token", "bar")], 200, {"X-Token values": ["foo", "bar"]}),
     ],
 )
-def test(path, headers, expected_status, expected_response):
+def test(path, headers, expected_status, expected_response, client: TestClient):
     response = client.get(path, headers=headers)
     assert response.status_code == expected_status
     assert response.json() == expected_response

-def test_openapi_schema():
+def test_openapi_schema(client: TestClient):
     response = client.get("/openapi.json")
     assert response.status_code == 200
     assert response.json() == {

@@ -1,110 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from docs_src.header_params.tutorial003_an import app
-
-client = TestClient(app)
-
-
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"X-Token values": None}),
-        ("/items", {"x-token": "foo"}, 200, {"X-Token values": ["foo"]}),
-        # TODO: fix this, is it a bug?
-        # ("/items", [("x-token", "foo"), ("x-token", "bar")], 200, {"X-Token values": ["foo", "bar"]}),
-    ],
-)
-def test(path, headers, expected_status, expected_response):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-def test_openapi_schema():
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "title": "X-Token",
-                                    "anyOf": [
-                                        {"type": "array", "items": {"type": "string"}},
-                                        {"type": "null"},
-                                    ],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {
-                                    "title": "X-Token",
-                                    "type": "array",
-                                    "items": {"type": "string"},
-                                }
-                            ),
-                            "name": "x-token",
-                            "in": "header",
-                        }
-                    ],
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-            }
-        },
-    }

@@ -1,118 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial003_an_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py310
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"X-Token values": None}),
-        ("/items", {"x-token": "foo"}, 200, {"X-Token values": ["foo"]}),
-        # TODO: fix this, is it a bug?
-        # ("/items", [("x-token", "foo"), ("x-token", "bar")], 200, {"X-Token values": ["foo", "bar"]}),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "title": "X-Token",
-                                    "anyOf": [
-                                        {"type": "array", "items": {"type": "string"}},
-                                        {"type": "null"},
-                                    ],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {
-                                    "title": "X-Token",
-                                    "type": "array",
-                                    "items": {"type": "string"},
-                                }
-                            ),
-                            "name": "x-token",
-                            "in": "header",
-                        }
-                    ],
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-            }
-        },
-    }

@@ -1,118 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py39
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial003_an_py39 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py39
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"X-Token values": None}),
-        ("/items", {"x-token": "foo"}, 200, {"X-Token values": ["foo"]}),
-        # TODO: fix this, is it a bug?
-        # ("/items", [("x-token", "foo"), ("x-token", "bar")], 200, {"X-Token values": ["foo", "bar"]}),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py39
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "title": "X-Token",
-                                    "anyOf": [
-                                        {"type": "array", "items": {"type": "string"}},
-                                        {"type": "null"},
-                                    ],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {
-                                    "title": "X-Token",
-                                    "type": "array",
-                                    "items": {"type": "string"},
-                                }
-                            ),
-                            "name": "x-token",
-                            "in": "header",
-                        }
-                    ],
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-            }
-        },
-    }

@@ -1,118 +0,0 @@
-import pytest
-from dirty_equals import IsDict
-from fastapi.testclient import TestClient
-
-from ...utils import needs_py310
-
-
-[USER_REDACTED].fixture(name="client")
-def get_client():
-    from docs_src.header_params.tutorial003_py310 import app
-
-    client = TestClient(app)
-    return client
-
-
-[USER_REDACTED]_py310
-[USER_REDACTED].mark.parametrize(
-    "path,headers,expected_status,expected_response",
-    [
-        ("/items", None, 200, {"X-Token values": None}),
-        ("/items", {"x-token": "foo"}, 200, {"X-Token values": ["foo"]}),
-        # TODO: fix this, is it a bug?
-        # ("/items", [("x-token", "foo"), ("x-token", "bar")], 200, {"X-Token values": ["foo", "bar"]}),
-    ],
-)
-def test(path, headers, expected_status, expected_response, client: TestClient):
-    response = client.get(path, headers=headers)
-    assert response.status_code == expected_status
-    assert response.json() == expected_response
-
-
-[USER_REDACTED]_py310
-def test_openapi_schema(client: TestClient):
-    response = client.get("/openapi.json")
-    assert response.status_code == 200
-    assert response.json() == {
-        "openapi": "3.1.0",
-        "info": {"title": "FastAPI", "version": "0.1.0"},
-        "paths": {
-            "/items/": {
-                "get": {
-                    "summary": "[NAME_REDACTED]",
-                    "operationId": "read_items_items__get",
-                    "parameters": [
-                        {
-                            "required": False,
-                            "schema": IsDict(
-                                {
-                                    "title": "X-Token",
-                                    "anyOf": [
-                                        {"type": "array", "items": {"type": "string"}},
-                                        {"type": "null"},
-                                    ],
-                                }
-                            )
-                            | IsDict(
-                                # TODO: remove when deprecating Pydantic v1
-                                {
-                                    "title": "X-Token",
-                                    "type": "array",
-                                    "items": {"type": "string"},
-                                }
-                            ),
-                            "name": "x-token",
-                            "in": "header",
-                        }
-                    ],
-                    "responses": {
-                        "200": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {"application/json": {"schema": {}}},
-                        },
-                        "422": {
-                            "description": "[NAME_REDACTED]",
-                            "content": {
-                                "application/json": {
-                                    "schema": {
-                                        "$ref": "#/components/schemas/HTTPValidationError"
-                                    }
-                                }
-                            },
-                        },
-                    },
-                }
-            }
-        },
-        "components": {
-            "schemas": {
-                "HTTPValidationError": {
-                    "title": "HTTPValidationError",
-                    "type": "object",
-                    "properties": {
-                        "detail": {
-                            "title": "Detail",
-                            "type": "array",
-                            "items": {"$ref": "#/components/schemas/ValidationError"},
-                        }
-                    },
-                },
-                "ValidationError": {
-                    "title": "ValidationError",
-                    "required": ["loc", "msg", "type"],
-                    "type": "object",
-                    "properties": {
-                        "loc": {
-                            "title": "Location",
-                            "type": "array",
-                            "items": {
-                                "anyOf": [{"type": "string"}, {"type": "integer"}]
-                            },
-                        },
-                        "msg": {"title": "Message", "type": "string"},
-                        "type": {"title": "[NAME_REDACTED]", "type": "string"},
-                    },
-                },
-            }
-        },
-    }

:fire:

This wasn't failing before? 🤔

I updated the test to the latest version `test_tutorial003_an_py310.py`, which already included the comment, so I kept it


🌐 Update Portuguese translations

Update Portuguese translation for the files:
- docs/pt/docs/tutorial/index.md
- docs/pt/docs/tutorial/first-steps.md
- docs/pt/docs/deployment/server-workers.md
- docs/pt/docs/deployment/manually.md

@@ -7,45 +7,33 @@ Em resumo, utilize o comando `fastapi run` para inicializar sua aplicação Fast
 <div class="termy">

 ```console
-$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:single">main.py</u>
-<font color="#3465A4">INFO    </font> Using path <font color="#3465A4">main.py</font>
-<font color="#3465A4">INFO    </font> Resolved absolute path <font color="#75507B">/home/user/code/awesomeapp/</font><font color="#AD7FA8">main.py</font>
-<font color="#3465A4">INFO    </font> Searching for package file structure from directories with <font color="#3465A4">__init__.py</font> files
-<font color="#3465A4">INFO    </font> Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
-
- ╭─ <font color="#8AE234"><b>Python module file</b></font> ─╮
- │                      │
- │  🐍 main.py          │
- │                      │
- ╰──────────────────────╯
-
-<font color="#3465A4">INFO    </font> Importing module <font color="#4E9A06">main</font>
-<font color="#3465A4">INFO    </font> Found importable FastAPI app
-
- ╭─ <font color="#8AE234"><b>[NAME_REDACTED] app</b></font> ─╮
- │                          │
- │  <span style="background-color:#272822"><font color="#FF4689">from</font></span><span style="background-color:#272822"><font color="#F8F8F2"> main </font></span><span style="background-color:#272822"><font color="#FF4689">import</font></span><span style="background-color:#272822"><font color="#F8F8F2"> app</font></span><span style="background-color:#272822">  </span>  │
- │                          │
- ╰──────────────────────────╯
-
-<font color="#3465A4">INFO    </font> Using import string <font color="#8AE234"><b>main:app</b></font>
-
- <font color="#4E9A06">╭─────────── FastAPI CLI - Production mode ───────────╮</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  Serving at: http://0.0.0.0:8000                    │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  API docs: http://0.0.0.0:8000/docs                 │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  Running in production mode, for development use:   │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  </font><font color="#8AE234"><b>fastapi dev</b></font><font color="#4E9A06">                                        │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">╰─────────────────────────────────────────────────────╯</font>
-
-<font color="#4E9A06">INFO</font>:     Started server process [<font color="#06989A">2306215</font>]
-<font color="#4E9A06">INFO</font>:     Waiting for application startup.
-<font color="#4E9A06">INFO</font>:     Application startup complete.
-<font color="#4E9A06">INFO</font>:     Uvicorn running on <b>http://0.0.0.0:8000</b> (Press CTRL+C to quit)
+$ <font color="#4E9A06">fastapi</font> run <u style="text-decoration-style:solid">main.py</u>
+
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting production server 🚀
+
+             Searching for package file structure from directories
+             with <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  🐍 main.py
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with
+             the following code:
+
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
+
+             Logs:
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>2306215</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C
+             to quit<b>)</b>
 ```

 </div>

@@ -36,56 +36,43 @@ Se você usar o comando `fastapi`:
 <div class="termy">

 ```console
-$ <pre> <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:single">main.py</u>
-<font color="#3465A4">INFO    </font> Using path <font color="#3465A4">main.py</font>
-<font color="#3465A4">INFO    </font> Resolved absolute path <font color="#75507B">/home/user/code/awesomeapp/</font><font color="#AD7FA8">main.py</font>
-<font color="#3465A4">INFO    </font> Searching for package file structure from directories with <font color="#3465A4">__init__.py</font> files
-<font color="#3465A4">INFO    </font> Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
-
- ╭─ <font color="#8AE234"><b>Python module file</b></font> ─╮
- │                      │
- │  🐍 main.py          │
- │                      │
- ╰──────────────────────╯
-
-<font color="#3465A4">INFO    </font> Importing module <font color="#4E9A06">main</font>
-<font color="#3465A4">INFO    </font> Found importable FastAPI app
-
- ╭─ <font color="#8AE234"><b>[NAME_REDACTED] app</b></font> ─╮
- │                          │
- │  <span style="background-color:#272822"><font color="#FF4689">from</font></span><span style="background-color:#272822"><font color="#F8F8F2"> main </font></span><span style="background-color:#272822"><font color="#FF4689">import</font></span><span style="background-color:#272822"><font color="#F8F8F2"> app</font></span><span style="background-color:#272822">  </span>  │
- │                          │
- ╰──────────────────────────╯
-
-<font color="#3465A4">INFO    </font> Using import string <font color="#8AE234"><b>main:app</b></font>
-
- <font color="#4E9A06">╭─────────── FastAPI CLI - Production mode ───────────╮</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  Serving at: http://0.0.0.0:8000                    │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  API docs: http://0.0.0.0:8000/docs                 │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  Running in production mode, for development use:   │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">│  </font><font color="#8AE234"><b>fastapi dev</b></font><font color="#4E9A06">                                        │</font>
- <font color="#4E9A06">│                                                     │</font>
- <font color="#4E9A06">╰─────────────────────────────────────────────────────╯</font>
-
-<font color="#4E9A06">INFO</font>:     Uvicorn running on <b>http://0.0.0.0:8000</b> (Press CTRL+C to quit)
-<font color="#4E9A06">INFO</font>:     Started parent process [<font color="#34E2E2"><b>27365</b></font>]
-<font color="#4E9A06">INFO</font>:     Started server process [<font color="#06989A">27368</font>]
-<font color="#4E9A06">INFO</font>:     Waiting for application startup.
-<font color="#4E9A06">INFO</font>:     Application startup complete.
-<font color="#4E9A06">INFO</font>:     Started server process [<font color="#06989A">27369</font>]
-<font color="#4E9A06">INFO</font>:     Waiting for application startup.
-<font color="#4E9A06">INFO</font>:     Application startup complete.
-<font color="#4E9A06">INFO</font>:     Started server process [<font color="#06989A">27370</font>]
-<font color="#4E9A06">INFO</font>:     Waiting for application startup.
-<font color="#4E9A06">INFO</font>:     Application startup complete.
-<font color="#4E9A06">INFO</font>:     Started server process [<font color="#06989A">27367</font>]
-<font color="#4E9A06">INFO</font>:     Waiting for application startup.
-<font color="#4E9A06">INFO</font>:     Application startup complete.
-</pre>
+$ <font color="#4E9A06">fastapi</font> run --workers 4 <u style="text-decoration-style:solid">main.py</u>
+
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting production server 🚀
+
+             Searching for package file structure from directories with
+             <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  🐍 main.py
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with the
+             following code:
+
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000/docs</u></font>
+
+             Logs:
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://0.0.0.0:8000</u></font> <b>(</b>Press CTRL+C to
+             quit<b>)</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started parent process <b>[</b><font color="#34E2E2"><b>27365</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27368</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27369</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27370</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>27367</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
 ```

 </div>

@@ -11,26 +11,42 @@ Execute o servidor:

 ```console
-$ uvicorn main:app --reload
+$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>

-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-<span style="color: green;">INFO</span>:     Started reloader process [28720]
-<span style="color: green;">INFO</span>:     Started server process [28722]
-<span style="color: green;">INFO</span>:     Waiting for application startup.
-<span style="color: green;">INFO</span>:     Application startup complete.
-```
+   FastAPI   Starting development server 🚀

-

+             Searching for package file structure from directories
+             with __init__.py files
+             Importing from /home/user/code/awesomeapp

-/// note | Nota
+    module   🐍 main.py

-O comando `uvicorn main:app` se refere a:
+      code   Importing the FastAPI app object from the module with
+             the following code:

-* `main`: o arquivo `main.py` (o "módulo" Python).
-* `app`: o objeto criado no arquivo `main.py` com a linha `app = FastAPI()`.
-* `--reload`: faz o servidor reiniciar após mudanças de código. Use apenas para desenvolvimento.
+             from main import app

-///
+       app   Using import string: main:app
+
+    server   Server started at http://127.0.0.1:8000
+    server   Documentation at http://127.0.0.1:8000/docs
+
+       tip   Running in development mode, for production use:
+             fastapi run
+
+             Logs:
+
+      INFO   Will watch for changes in these directories:
+             ['/home/user/code/awesomeapp']
+      INFO   Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C
+             to quit)
+      INFO   Started reloader process [383138] using WatchFiles
+      INFO   Started server process [383153]
+      INFO   Waiting for application startup.
+      INFO   Application startup complete.
+```
+
+</div>

 Na saída, temos:

@@ -151,34 +167,6 @@ Aqui, a variável `app` será uma "instância" da classe `FastAPI`.

 Este será o principal ponto de interação para criar toda a sua API.

-Este `app` é o mesmo referenciado por `uvicorn` no comando:
-
-<div class="termy">
-
-```console
-$ uvicorn main:app --reload
-
-INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
-
-</div>
-
-Se você criar a sua aplicação como:
-
-{* ../../docs_src/first_steps/tutorial002.py hl[3] *}
-
-E colocar em um arquivo `main.py`, você iria chamar o `uvicorn` assim:
-
-<div class="termy">
-
-```console
-$ uvicorn main:my_awesome_api --reload
-
-INFO:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-```
-
-

-
 ### Passo 3: crie uma *rota*

 #### Rota

@@ -4,9 +4,7 @@ Esse tutorial mostra como usar o **FastAPI** com a maior parte de seus recursos,

 Cada seção constrói, gradualmente, sobre as anteriores, mas sua estrutura são tópicos separados, para que você possa ir a qualquer um específico e resolver suas necessidades específicas de API.

-Ele também foi feito como referência futura.
-
-Então você poderá voltar e ver exatamente o que precisar.
+Ele também foi construído para servir como uma referência futura, então você pode voltar e ver exatamente o que você precisa.

 ## Rode o código

@@ -17,13 +15,39 @@ Para rodar qualquer um dos exemplos, copie o codigo para um arquivo `main.py`, e

 ```console
-$ uvicorn main:app --reload
+$ <font color="#4E9A06">fastapi</font> dev <u style="text-decoration-style:solid">main.py</u>
+
+  <span style="background-color:#009485"><font color="#D3D7CF"> FastAPI </font></span>  Starting development server 🚀
+
+             Searching for package file structure from directories
+             with <font color="#3465A4">__init__.py</font> files
+             Importing from <font color="#75507B">/home/user/code/</font><font color="#AD7FA8">awesomeapp</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> module </font></span>  🐍 main.py
+
+     <span style="background-color:#007166"><font color="#D3D7CF"> code </font></span>  Importing the FastAPI app object from the module with
+             the following code:
+
+             <u style="text-decoration-style:solid">from </u><u style="text-decoration-style:solid"><b>main</b></u><u style="text-decoration-style:solid"> import </u><u style="text-decoration-style:solid"><b>app</b></u>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> app </font></span>  Using import string: <font color="#3465A4">main:app</font>
+
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Server started at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font>
+   <span style="background-color:#007166"><font color="#D3D7CF"> server </font></span>  Documentation at <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000/docs</u></font>
+
+      <span style="background-color:#007166"><font color="#D3D7CF"> tip </font></span>  Running in development mode, for production use:
+             <b>fastapi run</b>
+
+             Logs:

-<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
-<span style="color: green;">INFO</span>:     Started reloader process [28720]
-<span style="color: green;">INFO</span>:     Started server process [28722]
-<span style="color: green;">INFO</span>:     Waiting for application startup.
-<span style="color: green;">INFO</span>:     Application startup complete.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Will watch for changes in these directories:
+             <b>[</b><font color="#4E9A06">'/home/user/code/awesomeapp'</font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Uvicorn running on <font color="#729FCF"><u style="text-decoration-style:solid">http://127.0.0.1:8000</u></font> <b>(</b>Press CTRL+C
+             to quit<b>)</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started reloader process <b>[</b><font color="#34E2E2"><b>383138</b></font><b>]</b> using WatchFiles
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Started server process <b>[</b><font color="#34E2E2"><b>383153</b></font><b>]</b>
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Waiting for application startup.
+     <span style="background-color:#007166"><font color="#D3D7CF"> INFO </font></span>  Application startup complete.
 ```

@@ -43,32 +67,18 @@ Para o tutorial, você deve querer instalá-lo com todas as dependências e recu

 ```console
-$ pip install "fastapi[all]"
+$ pip install "fastapi[standard]"

 ---> 100%
 ```

-...isso também inclui o `uvicorn`, que você pode usar como o servidor que rodará seu código.
-
 /// note | Nota

-Você também pode instalar parte por parte.
-
-Isso é provavelmente o que você faria quando você quisesse lançar sua aplicação em produção:
-
-```
-pip install fastapi
-```
-
-Também instale o `uvicorn` para funcionar como servidor:
-
-```
-pip install "uvicorn[standard]"
-```
+Quando você instala com pip install "fastapi[standard]", ele vem com algumas dependências opcionais padrão.

-E o mesmo para cada dependência opcional que você quiser usar.
+Se você não quiser ter essas dependências opcionais, pode instalar pip install fastapi em vez disso.

 ///

It is good, but could you update your branch and pull request changes that can not cause conflicts?

Just some fixes by [NAME_REDACTED] there is also the problem of conflict.

```suggestion
Quando você instala com `pip install "fastapi[standard]"`, ele vem com algumas dependências opcionais padrão.
```

```suggestion
Se você não quiser ter essas dependências opcionais, pode instalar `pip install fastapi` em vez disso.
```


🌐 Add Russian translation for `docs/ru/docs/tutorial/bigger-applications.md`

@@ -0,0 +1,556 @@
+# Большие приложения, в которых много файлов
+
+При построении приложения или веб-API нам редко удается поместить всё в один файл.
+
+**FastAPI** предоставляет удобный инструментарий, который позволяет нам структурировать приложение, сохраняя при этом всю необходимую гибкость.
+
+/// info | Примечание
+
+Если вы раньше использовали Flask, то это аналог шаблонов Flask ([NAME_REDACTED]).
+
+///
+
+## Пример структуры приложения
+
+Давайте предположим, что наше приложение имеет следующую структуру:
+
+```
+.
+├── app
+│   ├── __init__.py
+│   ├── main.py
+│   ├── dependencies.py
+│   └── routers
+│   │   ├── __init__.py
+│   │   ├── items.py
+│   │   └── users.py
+│   └── internal
+│       ├── __init__.py
+│       └── admin.py
+```
+
+/// tip | Подсказка
+
+Обратите внимание, что в каждом каталоге и подкаталоге имеется файл `__init__.py`
+
+Это как раз то, что позволяет импортировать код из одного файла в другой.
+
+Например, в файле `app/main.py` может быть следующая строка:
+
+```
+from app.routers import items
+```
+
+///
+
+* Всё помещается в каталоге `app`. В нём также находится пустой файл `app/__init__.py`. Таким образом, `app` является "Python-пакетом" (коллекцией модулей Python).
+* Он содержит файл `app/main.py`. Данный файл является частью пакета (т.е. находится внутри каталога, содержащего файл `__init__.py`), и, соответственно, он является модулем пакета: `app.main`.
+* Он также содержит файл `app/dependencies.py`, который также, как и `app/main.py`, является модулем: `app.dependencies`.
+* Здесь также находится подкаталог `app/routers/`, содержащий `__init__.py`.  Он является суб-пакетом: `app.routers`.
+* Файл `app/routers/items.py` находится внутри пакета `app/routers/`. Таким образом, он является суб-модулем: `app.routers.items`.
+* Точно также `app/routers/users.py` является ещё одним суб-модулем: `app.routers.users`.
+* Подкаталог `app/internal/`, содержащий файл `__init__.py`, является ещё одним суб-пакетом: `app.internal`.
+* А файл `app/internal/admin.py` является ещё одним суб-модулем: `app.internal.admin`.
+
+
+
+Та же самая файловая структура приложения, но с комментариями:
+
+```
+.
+├── app                  # "app" пакет
+│   ├── __init__.py      # этот файл превращает "app" в "Python-пакет"
+│   ├── main.py          # модуль "main", напр.: import app.main
+│   ├── dependencies.py  # модуль "dependencies", напр.: import app.dependencies
+│   └── routers          # суб-пакет "routers"
+│   │   ├── __init__.py  # превращает "routers" в суб-пакет
+│   │   ├── items.py     # суб-модуль "items", напр.: import app.routers.items
+│   │   └── users.py     # суб-модуль "users", напр.: import app.routers.users
+│   └── internal         # суб-пакет "internal"
+│       ├── __init__.py  # превращает "internal" в суб-пакет
+│       └── admin.py     # суб-модуль "admin", напр.: import app.internal.admin
+```
+
+## `APIRouter`
+
+Давайте предположим, что для работы с пользователями используется отдельный файл (суб-модуль) `/app/routers/users.py`.
+
+Для лучшей организации приложения, вы хотите отделить операции пути, связанные с пользователями, от остального кода.
+
+Но так, чтобы эти операции по-прежнему оставались частью **FastAPI** приложения/веб-API (частью одного пакета)
+
+С помощью  `APIRouter` вы можете создать *операции пути* (*эндпоинты*) для данного модуля.
+
+
+### Импорт `APIRouter`
+
+Точно также, как и в случае с классом `FastAPI`, вам нужно импортировать и создать объект класса `APIRouter`.
+
+```Python hl_lines="1  3" title="app/routers/users.py"
+{!../../docs_src/bigger_applications/app/routers/users.py!}
+```
+
+### Создание *эндпоинтов* с помощью `APIRouter`
+
+В дальнейшем используйте `APIRouter` для объявления *эндпоинтов*, точно также, как вы используете класс `FastAPI`:
+
+```Python hl_lines="6  11  16" title="app/routers/users.py"
+{!../../docs_src/bigger_applications/app/routers/users.py!}
+```
+
+Вы можете думать об `APIRouter` как об "уменьшенной версии" класса FastAPI`.
+
+`APIRouter` поддерживает все те же самые опции.
+
+`APIRouter` поддерживает все те же самые параметры, такие как `parameters`, `responses`, `dependencies`, `tags`, и т. д.
+
+/// tip | Подсказка
+
+В данном примере, в качестве названия переменной используется `router`, но вы можете использовать любое другое имя.
+
+///
+
+Мы собираемся подключить данный `APIRouter` к нашему основному приложению на `FastAPI`, но сначала давайте проверим зависимости и создадим ещё один модуль с `APIRouter`.
+
+## Зависимости
+
+Нам понадобятся некоторые зависимости, которые мы будем использовать в разных местах нашего приложения.
+
+Мы поместим их в отдельный модуль `dependencies` (`app/dependencies.py`).
+
+Теперь мы воспользуемся простой зависимостью, чтобы прочитать кастомизированный `X-Token` из заголовка:
+
+//// tab | Python 3.9+
+
+```Python hl_lines="3  6-8" title="app/dependencies.py"
+{!> ../../docs_src/bigger_applications/app_an_py39/dependencies.py!}
+```
+
+////
+
+//// tab | Python 3.8+
+
+```Python hl_lines="1  5-7" title="app/dependencies.py"
+{!> ../../docs_src/bigger_applications/app_an/dependencies.py!}
+```
+
+////
+
+//// tab | Python 3.8+ non-Annotated
+
+/// tip | Подсказка
+
+Мы рекомендуем использовать версию `Annotated`, когда это возможно.
+
+///
+
+```Python hl_lines="1  4-6" title="app/dependencies.py"
+{!> ../../docs_src/bigger_applications/app/dependencies.py!}
+```
+
+////
+
+/// tip | Подсказка
+
+Для простоты мы воспользовались неким воображаемым заголовоком.
+
+В реальных случаях для получения наилучших результатов используйте интегрированные утилиты обеспечения безопасности [Security utilities](security/index.md){.internal-link target=_blank}.
+
+///
+
+## Ещё один модуль с `APIRouter`
+
+Давайте также предположим, что у вас есть *эндпоинты*, отвечающие за обработку "items", и они находятся в модуле `app/routers/items.py`.
+
+У вас определены следующие *операции пути* (*эндпоинты*):
+
+* `/items/`
+* `/items/{item_id}`
+
+Тут всё точно также, как и в ситуации с `app/routers/users.py`.
+
+Но теперь мы хотим поступить немного умнее и слегка упростить код.
+
+Мы знаем, что все *эндпоинты* данного модуля имеют некоторые общие свойства:
+
+* Префикс пути: `/items`.
+* Теги: (один единственный тег: `items`).
+* Дополнительные ответы (responses)
+* Зависимости: использование созданной нами зависимости `X-token`
+
+Таким образом, вместо того чтобы добавлять все эти свойства в функцию каждого отдельного *эндпоинта*,
+мы добавим их в `APIRouter`.
+
+```Python hl_lines="5-10  16  21" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
+```
+
+Так как каждый *эндпоинт* начинается с символа `/`:
+
+```Python hl_lines="1"
+[USER_REDACTED].get("/{item_id}")
+async def read_item(item_id: str):
+    ...
+```
+
+...то префикс не должен заканчиваться символом `/`.
+
+В нашем случае префиксом является `/items`.
+
+Мы также можем добавить в наш маршрутизатор (router) список `тегов` (`tags`) и дополнительных `ответов` (`responses`), которые являются общими для каждого *эндпоинта*.
+
+И ещё мы можем добавить в наш маршрутизатор список `зависимостей`, которые должны вызываться при каждом обращении к *эндпоинтам*.
+
+/// tip | Подсказка
+
+Обратите внимание, что также, как и в случае с зависимостями в декораторах *эндпоинтов* ([dependencies in *path operation decorators*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), никакого значения в *функцию эндпоинта* передано не будет.
+
+///
+
+В результате мы получим следующие эндпоинты:
+
+* `/items/`
+* `/items/{item_id}`
+
+...как мы и планировали.
+
+* Они будут помечены тегами из заданного списка, в нашем случае это `"items"`.
+    * Эти теги особенно полезны для системы автоматической интерактивной документации (с использованием OpenAPI).
+* Каждый из них будет включать предопределенные ответы `responses`.
+* Каждый *эндпоинт* будет иметь список зависимостей (`dependencies`), исполняемых перед вызовом *эндпоинта*.
+    * Если вы определили зависимости в самой операции пути, **то она также будет выполнена**.
+    * Сначала выполняются зависимости маршрутизатора, затем вызываются зависимости, определенные в декораторе *эндпоинта* ([`dependencies` in the decorator](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), и, наконец, обычные параметрические зависимости.
+    * Вы также можете добавить зависимости безопасности с областями видимости (`scopes`) [`Security` dependencies with `scopes`](../advanced/security/oauth2-scopes.md){.internal-link target=_blank}.
+
+/// tip | Подсказка
+
+Например, с помощью зависимостей в `APIRouter` мы можем потребовать аутентификации для доступа ко всей группе *эндпоинтов*, не указывая зависимости для каждой отдельной функции *эндпоинта*.
+
+///
+
+/// check | Заметка
+
+Параметры `prefix`, `tags`, `responses` и `dependencies` относятся к функционалу **FastAPI**, помогающему избежать дублирования кода.
+
+///
+
+### Импорт зависимостей
+
+Наш код находится в модуле `app.routers.items` (файл `app/routers/items.py`).
+
+И нам нужно вызвать функцию зависимости из модуля `app.dependencies` (файл `app/dependencies.py`).
+
+Мы используем операцию относительного импорта `..` для импорта зависимости:
+
+```Python hl_lines="3" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
+```
+
+#### Как работает относительный импорт?
+
+/// tip | Подсказка
+
+Если вы прекрасно знаете, как работает импорт в Python, то переходите к следующему разделу.
+
+///
+
+Одна точка `.`, как в данном примере:
+
+```Python
+from .dependencies import get_token_header
+```
+означает:
+
+* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` расположен в каталоге `app/routers/`)...
+* ... найдите модуль `dependencies` (файл `app/routers/dependencies.py`)...
+* ... и импортируйте из него функцию `get_token_header`.
+
+К сожалению, такого файла не существует, и наши зависимости находятся в файле `app/dependencies.py`.
+
+Вспомните, как выглядит файловая структура нашего приложения:
+
+
+
+---
+
+Две точки `..`, как в данном примере:
+
+```Python
+from ..dependencies import get_token_header
+```
+
+означают:
+
+* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)...
+* ... перейдите в родительский пакет (каталог `app/`)...
+* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)...
+* ... и импортируйте из него функцию `get_token_header`.
+
+Это работает верно! 🎉
+
+---
+
+Аналогично, если бы мы использовали три точки `...`, как здесь:
+
+```Python
+from ...dependencies import get_token_header
+```
+
+то это бы означало:
+
+* Начните с пакета, в котором находится данный модуль (файл `app/routers/items.py` находится в каталоге `app/routers/`)...
+* ... перейдите в родительский пакет (каталог `app/`)...
+* ... затем перейдите в родительский пакет текущего пакета (такого пакета не существует, `app` находится на самом верхнем уровне 😱)...
+* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)...
+* ... и импортируйте из него функцию `get_token_header`.
+
+Это будет относиться к некоторому пакету, находящемуся на один уровень выше чем `app/` и содержащему свой собственный файл `__init__.py`. Но ничего такого у нас нет. Поэтому это приведет к ошибке в нашем примере. 🚨
+
+Теперь вы знаете, как работает импорт в Python, и сможете использовать относительное импортирование в своих собственных приложениях любого уровня сложности. 🤓
+
+### Добавление пользовательских тегов (`tags`), ответов (`responses`) и зависимостей (`dependencies`)
+
+Мы не будем добавлять префикс `/items` и список тегов `tags=["items"]` для каждого *эндпоинта*, т.к. мы уже их добавили с помощью `APIRouter`.
+
+Но помимо этого мы можем добавить новые теги для каждого отдельного *эндпоинта*, а также некоторые дополнительные ответы (`responses`), характерные для данного *эндпоинта*:
+
+```Python hl_lines="30-31" title="app/routers/items.py"
+{!../../docs_src/bigger_applications/app/routers/items.py!}
+```
+
+/// tip | Подсказка
+
+Последний *эндпоинт* будет иметь следующую комбинацию тегов: `["items", "custom"]`.
+
+А также в его документации будут содержаться оба ответа: один для `404` и другой для `403`.
+
+///
+
+## Модуль main в `FastAPI`
+
+Теперь давайте посмотрим на модуль `app/main.py`.
+
+Именно сюда вы импортируете и именно здесь вы используете класс `FastAPI`.
+
+Это основной файл вашего приложения, который объединяет всё в одно целое.
+
+И теперь, когда большая часть логики приложения разделена на отдельные модули, основной файл `app/main.py` будет достаточно простым.
+
+### Импорт `FastAPI`
+
+Вы импортируете и создаете класс `FastAPI` как обычно.
+
+Мы даже можем объявить глобальные зависимости [global dependencies](dependencies/global-dependencies.md){.internal-link target=_blank}, которые будут объединены с зависимостями для каждого отдельного маршрутизатора:
+
+```Python hl_lines="1  3  7" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+### Импорт `APIRouter`
+
+Теперь мы импортируем другие суб-модули, содержащие `APIRouter`:
+
+```Python hl_lines="4-5" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+Так как файлы `app/routers/users.py` и `app/routers/items.py` являются суб-модулями одного и того же Python-пакета `app`, то мы сможем их импортировать, воспользовавшись операцией относительного импорта `.`.
+
+### Как работает импорт?
+
+Данная строка кода:
+
+```Python
+from .routers import items, users
+```
+
+означает:
+
+* Начните с пакета, в котором содержится данный модуль (файл `app/main.py` содержится в каталоге `app/`)...
+* ... найдите суб-пакет `routers` (каталог `app/routers/`)...
+* ... и из него импортируйте суб-модули `items` (файл `app/routers/items.py`) и `users` (файл `app/routers/users.py`)...
+
+В модуле `items` содержится переменная `router` (`items.router`), та самая, которую мы создали в файле `app/routers/items.py`, она является объектом класса `APIRouter`.
+
+И затем мы сделаем то же самое для модуля `users`.
+
+Мы также могли бы импортировать и другим методом:
+
+```Python
+from app.routers import items, users
+```
+
+/// info | Примечание
+
+Первая версия является примером относительного импорта:
+
+```Python
+from .routers import items, users
+```
+
+Вторая версия является примером абсолютного импорта:
+
+```Python
+from app.routers import items, users
+```
+
+Узнать больше о пакетах и модулях в Python вы можете из официальной документации Python о модулях
+
+///
+
+### Избегайте конфликтов имен
+
+Вместо того чтобы импортировать только переменную `router`, мы импортируем непосредственно суб-модуль `items`.
+
+Мы делаем это потому, что у нас есть ещё одна переменная `router` в суб-модуле `users`.
+
+Если бы мы импортировали их одну за другой, как показано в примере:
+
+```Python
+from .routers.items import router
+from .routers.users import router
+```
+
+то переменная `router` из `users` переписал бы переменную `router` из `items`, и у нас не было бы возможности использовать их одновременно.
+
+Поэтому, для того чтобы использовать обе эти переменные в одном файле, мы импортировали соответствующие суб-модули:
+
+```Python hl_lines="5" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+### Подключение маршрутизаторов (`APIRouter`) для `users` и для `items`
+
+Давайте подключим маршрутизаторы (`router`) из суб-модулей `users` и `items`:
+
+```Python hl_lines="10-11" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+/// info | Примечание
+
+`users.router` содержит `APIRouter` из файла `app/routers/users.py`.
+
+А `items.router` содержит `APIRouter` из файла `app/routers/items.py`.
+
+///
+
+С помощью `app.include_router()` мы можем добавить каждый из маршрутизаторов (`APIRouter`) в основное приложение `FastAPI`.
+
+Он подключит все маршруты заданного маршрутизатора к нашему приложению.
+
+/// note | Технические детали
+
+Фактически, внутри он создаст все *операции пути* для каждой операции пути объявленной в `APIRouter`.
+
+И под капотом всё будет работать так, как будто бы мы имеем дело с одним файлом приложения.
+
+///
+
+/// check | Заметка
+
+При подключении маршрутизаторов не стоит беспокоиться о производительности.
+
+Операция подключения займёт микросекунды и понадобится только при запуске приложения.
+
+Таким образом, это не повлияет на производительность. ⚡
+
+///
+
+### Подключение `APIRouter` с пользовательскими префиксом (`prefix`), тегами (`tags`), ответами (`responses`), и зависимостями (`dependencies`)
+
+Теперь давайте представим, что ваша организация передала вам файл `app/internal/admin.py`.
+
+Он содержит `APIRouter` с некоторыми *эндпоитами* администрирования, которые ваша организация использует для нескольких проектов.
+
+В данном примере это сделать очень просто. Но давайте предположим, что поскольку файл используется для нескольких проектов,
+то мы не можем модифицировать его, добавляя префиксы (`prefix`), зависимости (`dependencies`), теги (`tags`), и т.д. непосредственно в `APIRouter`:
+
+```Python hl_lines="3" title="app/internal/admin.py"
+{!../../docs_src/bigger_applications/app/internal/admin.py!}
+```
+
+Но, несмотря на это, мы хотим использовать кастомный префикс (`prefix`) для подключенного маршрутизатора (`APIRouter`), в результате чего, каждая *операция пути* будет начинаться с `/admin`. Также мы хотим защитить наш маршрутизатор с помощью зависимостей, созданных для нашего проекта. И ещё мы хотим включить теги (`tags`) и ответы (`responses`).
+
+Мы можем применить все вышеперечисленные настройки, не изменяя начальный `APIRouter`. Нам всего лишь нужно передать нужные параметры в `app.include_router()`.
+
+```Python hl_lines="14-17" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+Таким образом, оригинальный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации.
+
+В результате, в нашем приложении каждый *эндпоинт* модуля `admin` будет иметь:
+
+* Префикс `/admin`.
+* Тег `admin`.
+* Зависимость `get_token_header`.
+* Ответ `418`. 🍵
+
+Это будет иметь место исключительно для `APIRouter` в нашем приложении, и не затронет любой другой код, использующий его.
+
+Например, другие проекты, могут использовать тот же самый `APIRouter` с другими методами аутентификации.
+
+### Подключение отдельного *эндпоинта*
+
+Мы также можем добавить *эндпоинт* непосредственно в основное приложение `FastAPI`.
+
+Здесь мы это делаем ... просто, чтобы показать, что это возможно 🤷:
+
+```Python hl_lines="21-23" title="app/main.py"
+{!../../docs_src/bigger_applications/app/main.py!}
+```
+
+и это будет работать корректно вместе с другими *эндпоинтами*, добавленными с помощью `app.include_router()`.
+
+/// info | Сложные технические детали
+
+**Примечание**: это сложная техническая деталь, которую, скорее всего, **вы можете пропустить**.
+
+---
+
+Маршрутизаторы (`APIRouter`) не "монтируются" по-отдельности и не изолируются от остального приложения.
+
+Это происходит потому, что нужно включить их *эндпоинты* в OpenAPI схему и в интерфейс пользователя.
+
+В силу того, что мы не можем их изолировать и "примонтировать" независимо от остальных, *эндпоинты* клонируются (пересоздаются) и не подключаются напрямую.
+
+///
+
+## Проверка автоматической документации API
+
+Теперь запустите приложение:
+
+

+
+```console
+$ fastapi dev app/main.py
+
+<span style="color: green;">INFO</span>:     Uvicorn running on http://127.0.0.1:8000 (Press CTRL+C to quit)
+```
+
+

+
+Откройте документацию по адресу http://127.0.0.1:8000/docs.
+
+Вы увидите автоматическую API документацию. Она включает в себя маршруты из суб-модулей, используя верные маршруты, префиксы и теги:
+
+
+
+## Подключение существующего маршрута через новый префикс (`prefix`)
+
+Вы можете использовать `.include_router()` несколько раз с одним и тем же маршрутом, применив различные префиксы.
+
+Это может быть полезным, если нужно предоставить доступ к одному и тому же API через различные префиксы, например, `/api/v1` и `/api/latest`.
+
+Это продвинутый способ, который вам может и не пригодится. Мы приводим его на случай, если вдруг вам это понадобится.
+
+## Включение одного маршрутизатора (`APIRouter`) в другой
+
+Точно так же, как вы включаете `APIRouter` в приложение `FastAPI`, вы можете включить `APIRouter` в другой `APIRouter`:
+
+```Python
+router.include_router(other_router)
+```
+
+Удостоверьтесь, что вы сделали это до того, как подключить маршрутизатор  (`router`) к вашему `FastAPI` приложению, и *эндпоинты* маршрутизатора `other_router` были также подключены.

Спасибо! С новым годом!

Здесь вместо слова "нечасто" лучше использовать слово "редко" - это будет правильнее и более естественно.

Здесь забыт предлог "в" - "не будет передаваться в".
А также "функции эндпоинта" стоит перевести в единственное число - "функция эндпоинта", так как у одного эндпоинта не может быть несколько функций.

Здесь вместо слова "здесь" лучше использовать слово "там" - "найдите там модуль". "Там" лучше отражает, что вы находитесь в другом пакете (в родительском), а не в том, в котором изначально начинали искать.

В слове "пользовательских" отсутствует буква "х"

"использовать ..., воспользовавшись ..." - получается "тавтология". Предлагаю следующий вариант:
"то мы сможем использовать `.` для того чтобы их импортировать при помощи относительного импорта".

Тут ошибка - вместо "из одного файла" должно быть "в одном файле". Да и "обеими переменными", я бы заменил на "ими".

Здесь забыто "| Примечание"

Здесь ошибка - в исходной документации имелось ввиду "имеем дело с одним простым приложением"

Выше (в одном из заголовков) "custom" уже был переведен как "пользовательский", поэтому для однообразия, и тут тоже стоит вместо слова "кастомизированным" использовать слово "пользовательскими" (в данном случае во множественном числе)

Более точный перевод "we can still share" - "мы **все еще** сможем использовать", а "projects in the organization" - "проектах организации"

"это будет работать так, как нужно вместе с другими *эндпоинтами*" - запутывает понимание. Однозначнее и понятнее будет - "это будет работать корректно вместе с другими *эндпоинтами*"

Опять получается "тавтология" - "покажем ..., чтобы показать". Как вариант, можно прописать так - "Здесь мы это делаем... просто, чтобы показать, что это возможно"

Почему тут появилось слово "по-отдельности"? В исходном тексте этого не упоминается - "The APIRouters are not "mounted", they are not isolated from the rest of the application."

Здесь вместо "включает в себя маршруты из суб-модулей, а также использует верные маршруты, префиксы и теги" лучше будет "включает в себя маршруты из суб-модулей, используя верные маршруты, префиксы и теги"

```suggestion
Так как файлы `app/routers/users.py` и `app/routers/items.py` являются суб-модулями одного и того же Python-пакета `app`, то мы сможем их импортировать, воспользовавшись операцией относительного импорта `.`.
```

```suggestion
Поэтому, для того чтобы использовать обе эти переменные в одном файле, мы импортировали соответствующие суб-модули:
```

в исходной документации подразумевается, что под капотом все копируется в один общий файл, и приложение работает так, как будто-бы в нем существует один единственный файл `main.py`, где прописаны все маршруты.

```suggestion
### Подключение `APIRouter` с пользовательскими префиксом (`prefix`), тегами (`tags`), ответами (`responses`), и зависимостями (`dependencies`)
```

```suggestion
Таким образом, оригинальный `APIRouter` не будет модифицирован, и мы сможем использовать файл `app/internal/admin.py` сразу в нескольких проектах организации.
```

```suggestion
Мы это делаем ... просто, чтобы показать, что это возможно 🤷:
```

```suggestion
и это будет работать корректно вместе с другими *эндпоинтами*, добавленными с помощью `app.include_router()`.
```

Потому что в данном контексте "isolated" является пояснением к "mounted" :smiley:

(оставлю как есть)

```suggestion
Вы увидите автоматическую API документацию. Она включает в себя маршруты из суб-модулей, используя верные маршруты, префиксы и теги:
```

```suggestion
При построении приложения или веб-API нам редко удается поместить всё в один файл.
```

```suggestion
Обратите внимание, что также, как и в случае с зависимостями в декораторах *эндпоинтов* ([dependencies in *path operation decorators*](dependencies/dependencies-in-path-operation-decorators.md){.internal-link target=_blank}), никакого значения в *функцию эндпоинта* передано не будет.
```

```suggestion
* ... найдите в нём модуль `dependencies` (файл `app/dependencies.py`)...
```

```suggestion
### Добавление пользовательских тегов (`tags`), ответов (`responses`) и зависимостей (`dependencies`)
```

```suggestion
/// info | Примечание
```

здесь немного поменяла

здесь немного поменяла

небольшое изменение

внесла изменение

частично поправила
("мы все еще сможем использовать": может и точнее, но смысл теряется :smiley:)

Слово "Здесь" в начале предложения не стоило убирать, ведь оно указывало на пример кода ниже.
А без него тут появляется неоднозначность рода:
1. "Мы" это кто? Все мы - как пользователи фреймворка FastAPI?
2. делаем "где"? В своих проектах на FastAPI?

поправила