FastAPI โ Postman collection
FastAPI already knows your routes. routeman turns them into a Postman collection that's ready to use: the OAuth2 login stores the token, Pydantic bodies have valid example values, and there are environments for every server.
Why not just import /openapi.json into Postman?
You can, and for a quick look it's fine. But the imported collection doesn't log in for you, doesn't save the token, has no environments for staging and production, and leaves out every route marked include_in_schema=False. You also need the server running to download the JSON.
routeman builds the same OpenAPI document in memory, without starting a server, and then adds what a Postman user needs:
- A login request for your
OAuth2PasswordBearertokenUrl(or JWT login route) that savesaccess_token/refresh_tokenautomatically. - Collection-level auth from
Depends()security: OAuth2,HTTPBearer,HTTPBasicandAPIKeyHeader. Public routes are set to No Auth. - Example values that validate: Pydantic constraints (
gt,min_length,pattern,Literal/Enum) and field names are respected. - Hidden routes (
include_in_schema=False) are included too. - Folders by tag, environments per server and a 5xx smoke test on every request.
Example (real output)
# main.py
app = FastAPI(title="Shop API")
oauth = OAuth2PasswordBearer(tokenUrl="/auth/token")
class ProductIn(BaseModel):
name: str = Field(min_length=2, max_length=80)
price: float = Field(gt=0)
sku: str
@app.post("/auth/token", tags=["auth"])
def token(): ...
@app.get("/products", tags=["products"])
def list_products(page: int = 1, search: str | None = Query(None)): ...
@app.post("/products", tags=["products"])
def create_product(p: ProductIn, user=Depends(oauth)): ...
@app.get("/products/{product_id}", tags=["products"])
def get_product(product_id: int, user=Depends(oauth)): ...
$ routeman routes -a main:app
POST /auth/token
GET /products
POST /products ๐ json: name, price, sku
GET /products/{product_id} ๐
4 routes, auth: bearer
$ routeman generate -a main:app
โ fastapi: 4 requests (2 POST, 2 GET)
โ auth: bearer (login: POST /auth/token)
โ wrote postman/demo-api.postman_collection.json
โ wrote postman/demo-api.local.postman_environment.json
done in 0.31s - import the files in Postman (File โ Import)
The generated Create Product request body is valid on the first send. price is 1.5 because of gt=0, and name respects the length limits:
{
"name": "John Doe",
"price": 1.5,
"sku": "string"
}
List Products has page and search query parameters, added but disabled, and {{product_id}} lives in the environment.
App location
routeman looks for a FastAPI() instance in common places. If yours is elsewhere, point to it with -a module:attribute, or to a factory with -a "app.factory:create_app()". Save it once with routeman init.
Read the full guide: FastAPI to Postman: better than importing openapi.json.