<img src="/img/tutorial/path-operation-configuration/image01.png">
+### Tags with Enums
+
+If you have a big application, you might end up accumulating **several tags**, and you would want to make sure you always use the **same tag** for related *path operations*.
+
+In these cases, it could make sense to store the tags in an `Enum`.
+
+**FastAPI** supports that the same way as with plain strings:
+
+```Python hl_lines="1 8-10 13 18"
+{!../../../docs_src/path_operation_configuration/tutorial002b.py!}
+```
+
## Summary and description
You can add a `summary` and `description`:
--- /dev/null
+from enum import Enum
+
+from fastapi import FastAPI
+
+app = FastAPI()
+
+
+class Tags(Enum):
+ items = "items"
+ users = "users"
+
+
+@app.get("/items/", tags=[Tags.items])
+async def get_items():
+ return ["Portal gun", "Plumbus"]
+
+
+@app.get("/users/", tags=[Tags.users])
+async def read_users():
+ return ["Rick", "Morty"]
+from enum import Enum
from typing import Any, Callable, Coroutine, Dict, List, Optional, Sequence, Type, Union
from fastapi import routing
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
router: routing.APIRouter,
*,
prefix: str = "",
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
deprecated: Optional[bool] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
import asyncio
import dataclasses
import email.message
-import enum
import inspect
import json
+from enum import Enum, IntEnum
from typing import (
Any,
Callable,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
openapi_extra: Optional[Dict[str, Any]] = None,
) -> None:
# normalise enums e.g. http.HTTPStatus
- if isinstance(status_code, enum.IntEnum):
+ if isinstance(status_code, IntEnum):
status_code = int(status_code)
self.path = path
self.endpoint = endpoint
self,
*,
prefix: str = "",
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
default_response_class: Type[Response] = Default(JSONResponse),
responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
"/"
), "A path prefix must not end with '/', as the routes will start with '/'"
self.prefix = prefix
- self.tags: List[str] = tags or []
+ self.tags: List[Union[str, Enum]] = tags or []
self.dependencies = list(dependencies or []) or []
self.deprecated = deprecated
self.include_in_schema = include_in_schema
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
router: "APIRouter",
*,
prefix: str = "",
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
default_response_class: Type[Response] = Default(JSONResponse),
responses: Optional[Dict[Union[int, str], Dict[str, Any]]] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
*,
response_model: Optional[Type[Any]] = None,
status_code: Optional[int] = None,
- tags: Optional[List[str]] = None,
+ tags: Optional[List[Union[str, Enum]]] = None,
dependencies: Optional[Sequence[params.Depends]] = None,
summary: Optional[str] = None,
description: Optional[str] = None,
--- /dev/null
+from fastapi.testclient import TestClient
+
+from docs_src.path_operation_configuration.tutorial002b import app
+
+client = TestClient(app)
+
+openapi_schema = {
+ "openapi": "3.0.2",
+ "info": {"title": "FastAPI", "version": "0.1.0"},
+ "paths": {
+ "/items/": {
+ "get": {
+ "tags": ["items"],
+ "summary": "Get Items",
+ "operationId": "get_items_items__get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ }
+ },
+ }
+ },
+ "/users/": {
+ "get": {
+ "tags": ["users"],
+ "summary": "Read Users",
+ "operationId": "read_users_users__get",
+ "responses": {
+ "200": {
+ "description": "Successful Response",
+ "content": {"application/json": {"schema": {}}},
+ }
+ },
+ }
+ },
+ },
+}
+
+
+def test_openapi_schema():
+ response = client.get("/openapi.json")
+ assert response.status_code == 200, response.text
+ assert response.json() == openapi_schema
+
+
+def test_get_items():
+ response = client.get("/items/")
+ assert response.status_code == 200, response.text
+ assert response.json() == ["Portal gun", "Plumbus"]
+
+
+def test_get_users():
+ response = client.get("/users/")
+ assert response.status_code == 200, response.text
+ assert response.json() == ["Rick", "Morty"]