To allow others contributing to our application’s codebase, or other frontend developers, to know which endpoints they can use in the User App, we need to document the API. In this section, we will use Swagger.
First, in the docs directory, create a swagger folder. Inside the swagger folder, create the files helpers.py and main.py.

In helpers.py, add the following code.
Import and set up some necessary modules.
from typing import Dict, List, Any, Generic, TypeVar
from pydantic import BaseModel
TData = TypeVar("TData")
TMeta = TypeVar("TMeta")
A function to create JSON responses used in the OpenAPI schema.
class StandardJsonResponse(BaseModel, Generic[TData, TMeta]):
"""
Định nghĩa cấu trúc phản hồi JSON chuẩn dùng chung cho toàn hệ thống.
Đây là một lớp generic cho phép tùy biến kiểu dữ liệu trả về (`data`) và thông tin phụ (`meta`),
đồng thời cung cấp trường `error` để mô tả lỗi nếu có.
Generic:
TData: Kiểu dữ liệu chính được trả về trong response (ví dụ: dict, list, schema cụ thể).
TMeta: Kiểu dữ liệu phụ cho metadata (ví dụ: thông tin phân trang, mã lỗi, trạng thái).
Attributes:
error (Dict[str, Any]): Thông tin lỗi nếu có, bao gồm mã lỗi, mô tả, hoặc chi tiết kỹ thuật.
data (TData | Any): Dữ liệu chính của phản hồi. Có thể là bất kỳ kiểu nào tùy theo ngữ cảnh sử dụng.
meta (TMeta | Dict[str, Any]): Metadata bổ sung cho phản hồi, ví dụ: trạng thái, phân trang, mã xử lý.
"""
data: TData | List[Any] | Dict[str, Any]
meta: TMeta | Dict[str, Any]

Finally, in main.py, we define some options and create an instance of the Swagger documentation.
First, import some necessary modules.
from fastapi import FastAPI
from fastapi.openapi.utils import get_openapi
# Import constant
from utils.constants.app import APP_CONSTANTS
app_info = {
"title": "Cognito Example Application with Python",
"version": "1.0.0",
"description": "Tài liệu API cho Cognito Example Application with Python",
}
def create_custom_openapi_schema(app: FastAPI):
"""Tạo cấu hình FastAPI theo chuẩn của OpenAPI.
Args:
FastAPI: instance của FastAPI.
Returns:
_: schema theo chuẩn open api.
"""
if app.openapi_schema:
return app.openapi_schema
openapi_schema = get_openapi(
title=app_info.get("title", ""),
version=app_info.get("version", ""),
description=app_info.get("description", ""),
routes=app.routes,
)
if "components" not in openapi_schema:
openapi_schema["components"] = {}
# Thêm security schemes (tương đương components.securitySchemes)
openapi_schema["components"]["securitySchemes"] = {
"bearerAuth": {
"type": "http",
"scheme": "bearer",
"bearerFormat": "JWT",
}
}
# Thêm global security (tương đương security)
openapi_schema["security"] = [{"bearerAuth": []}]
# Thêm servers (tương đương servers)
openapi_schema["servers"] = [
{
"url": f"http://{APP_CONSTANTS.get("HOST")}:{APP_CONSTANTS.get("PORT")}",
"description": "Development server",
}
]
app.openapi_schema = openapi_schema
return app.openapi_schema

With this, most of the basics in the core are now prepared. After this section, we will proceed to build the features.