FastAPI helps you build APIs faster with automatic OpenAPI documentation, built-in Swagger and ReDoc support, and a clean Python developer experience. Bruno makes testing easier by importing your OpenAPI spec into a local-first, Git-friendly API collection
Table of Contents
API development usually involves three repeating tasks: building endpoints, maintaining documentation, and testing requests. In many teams, those pieces drift apart quickly. The backend changes, the docs become outdated, and test collections no longer reflect the real API.
FastAPI and Bruno work especially well together because FastAPI automatically generates the OpenAPI specification from your code, and Bruno can import that spec directly into a local, Git-based collection. That means less duplication, less manual effort, and a much smoother workflow from development to testing.
Traditional API Development
FastAPI + Bruno Workflow
FastAPI uses Python type hints and Pydantic models to handle validation, serialization, and schema generation automatically. Instead of writing the same information multiple times for models, docs, and validation, you define it once in Python and FastAPI takes care of the rest.
One of FastAPI’s biggest advantages is that it ships with automatic API documentation out of the box.
/docs gives you Swagger UI/redoc gives you ReDoc/openapi.json gives you the OpenAPI specificationThat means you can build the API and instantly browse, test, and share the documentation without manually maintaining a separate spec file.
FastAPI feels natural for Python developers. The syntax is clean, readable, and intuitive, which makes it approachable for both beginners and experienced backend engineers.
FastAPI has a strong ecosystem, active community support, great documentation, and broad adoption in startups and production systems. It fits naturally into modern Python application stacks.
Create a virtual environment and install the packages needed for FastAPI, Uvicorn, and MongoDB integration.
python -m venv venv
source venv/bin/activate
pip install fastapi uvicorn pymongo
Start by setting up the FastAPI app, MongoDB connection, and the Todo model. This is the base of the CRUD API.
from fastapi import FastAPI, HTTPException
from pydantic import BaseModel
from pymongo import MongoClient
from bson import ObjectId
app = FastAPI(
title="Todo API",
description="Simple CRUD API with FastAPI and MongoDB",
version="1.0.0"
)
client = MongoClient("mongodb://localhost:27017")
db = client["testdb"]
collection = db["todos"]
class Todo(BaseModel):
title: str
completed: bool = False
The POST endpoint lets you create a new todo item and store it in MongoDB.
@app.post("/todos")
def create_todo(todo: Todo):
result = collection.insert_one(todo.dict())
return {"id": str(result.inserted_id), **todo.dict()}
You can expose one GET endpoint to list all todos and another to fetch a single todo by its ID.
@app.get("/todos")
def get_todos():
todos = []
for t in collection.find():
t["id"] = str(t["_id"])
del t["_id"]
todos.append(t)
return todos
@app.get("/todos/{id}")
def get_todo(id: str):
todo = collection.find_one({"_id": ObjectId(id)})
if not todo:
raise HTTPException(status_code=404, detail="Not found")
todo["id"] = str(todo["_id"])
del todo["_id"]
return todo
The PUT endpoint updates an existing todo by ID.
@app.put("/todos/{id}")
def update_todo(id: str, todo: Todo):
result = collection.update_one(
{"_id": ObjectId(id)},
{"$set": todo.dict()}
)
if result.matched_count == 0:
raise HTTPException(status_code=404, detail="Not found")
return {"message": "Updated"}
The DELETE endpoint removes a todo from MongoDB.
@app.delete("/todos/{id}")
def delete_todo(id: str):
result = collection.delete_one({"_id": ObjectId(id)})
if result.deleted_count == 0:
raise HTTPException(status_code=404, detail="Not found")
return {"message": "Deleted"}
Start the development server with Uvicorn:
uvicorn main:app --reload
Once the app is running, FastAPI automatically exposes documentation and schema endpoints:
http://localhost:8000/docs for Swagger UIhttp://localhost:8000/redoc for ReDochttp://localhost:8000/openapi.json for the raw OpenAPI specKey benefit: you do not need to manually write Swagger or OpenAPI YAML. FastAPI generates everything from your route definitions and Pydantic models.
Once your OpenAPI spec is available, Bruno can import it directly and generate a collection for your API endpoints.
http://localhost:8000/openapi.jsonBruno will generate requests for your endpoints automatically, which makes testing the API much easier. Instead of creating each request manually, you get a ready-to-use collection based on the same OpenAPI spec generated by FastAPI.
Why Bruno fits so well here
Because Bruno stores collections locally as files, it is especially useful for developers and teams who want their API test collections version-controlled alongside application code.
bru run --env local
Tip: Bruno recently introduced a feature called OpenAPI Sync, which helps keep your OpenAPI file in sync with your collection. You can read more about it here.
FastAPI and Bruno create a strong workflow for modern API development. FastAPI speeds up backend development with clean Python code, automatic validation, and built-in interactive docs. Bruno makes testing straightforward by turning your OpenAPI spec into a local, Git-friendly collection you can run and maintain easily.
Together, they reduce duplication across development, documentation, and testing. You spend less time maintaining docs manually and more time shipping useful APIs.
Useful endpoints to remember:
/docs for Swagger UI/redoc for ReDoc/openapi.json for the OpenAPI specificationHappy building 🚀