Skip to main content

Organizing with Tags

When you build a large API with many path operations, the automatic documentation (Swagger UI) can become cluttered. FastAPI allows you to group related operations using tags and provide detailed metadata, including descriptions and links to external documentation, to make your API more discoverable.

In this tutorial, you will learn how to organize your API by grouping operations and adding rich metadata to those groups.

Prerequisites

To follow this tutorial, you need FastAPI installed:

pip install fastapi

Grouping Operations with Tags

The simplest way to organize your API is by adding tags to your path operations. You do this by passing a list of strings to the tags parameter in your path operation decorators.

from fastapi import FastAPI

app = FastAPI()

@app.get("/users/", tags=["users"])
async def get_users():
return [{"name": "Harry"}, {"name": "Ron"}]

@app.get("/items/", tags=["items"])
async def get_items():
return [{"name": "wand"}, {"name": "flying broom"}]

When you visit /docs, you will see that the operations are grouped under "users" and "items" sections.

Adding Tag Metadata

While string tags are useful for grouping, you can provide more information like descriptions and links to external documentation by defining tag metadata. You pass this metadata to the openapi_tags parameter when creating your FastAPI application.

FastAPI uses the Tag class from fastapi.openapi.models to represent this metadata. Each tag in the list is a dictionary that matches the structure of the Tag model:

  • name (required): The name of the tag. It must match the tag used in your path operations.
  • description: A short description of the tag. You can use Markdown here.
  • externalDocs: A dictionary containing external documentation links.
from fastapi import FastAPI

tags_metadata = [
{
"name": "users",
"description": "Operations with users. The **login** logic is also here.",
},
{
"name": "items",
"description": "Manage items. So _fancy_ they have their own docs.",
"externalDocs": {
"description": "Items external docs",
"url": "https://fastapi.tiangolo.com/",
},
},
]

app = FastAPI(openapi_tags=tags_metadata)

@app.get("/users/", tags=["users"])
async def get_users():
return [{"name": "Harry"}, {"name": "Ron"}]

@app.get("/items/", tags=["items"])
async def get_items():
return [{"name": "wand"}, {"name": "flying broom"}]

The order of the dictionaries in tags_metadata determines the order in which the tags appear in the documentation UI.

Providing Global External Documentation

In addition to tag-specific documentation, you can provide a link to external documentation for the entire API using the openapi_external_docs parameter. This parameter expects a dictionary that follows the structure of the ExternalDocumentation class from fastapi.openapi.models.

from fastapi import FastAPI

external_docs = {
"description": "Find more info here",
"url": "https://fastapi.tiangolo.com/"
}

app = FastAPI(openapi_external_docs=external_docs)

@app.get("/items/")
async def read_items():
return [{"item_id": "Foo"}]

The OpenAPI Models

Under the hood, FastAPI uses Pydantic models defined in fastapi/openapi/models.py to validate and generate the OpenAPI schema.

Tag Model

The Tag model defines the structure for tag metadata:

class Tag(BaseModelWithConfig):
name: str
description: str | None = None
externalDocs: ExternalDocumentation | None = None

ExternalDocumentation Model

The ExternalDocumentation model is used for both global and tag-specific external links:

class ExternalDocumentation(BaseModelWithConfig):
description: str | None = None
url: AnyUrl

By using these structures, you ensure that your API documentation is not only organized but also provides all the necessary context for your users.