How to Add a New API Endpoint to the FastAPI Application in Open Notebook
To add a new API endpoint to the Open Notebook FastAPI application, create a router module under api/routers/, implement the endpoint function with Pydantic validation, and register it in api/main.py using app.include_router() with the appropriate prefix and tags.
Open Notebook uses a modular FastAPI backend organized by feature-specific routers. When you add a new API endpoint to the FastAPI application in Open Notebook, you follow the established pattern found in files like api/routers/notebooks.py and api/routers/notes.py. This approach keeps the codebase organized and automatically generates OpenAPI documentation at the /docs endpoint.
Step 1: Create the Router Module
Start by creating a new Python file in the api/routers/ directory. The repository follows a strict "router-per-feature" pattern, where each domain entity has its own module.
Create api/routers/hello.py (or your feature name) and instantiate an APIRouter:
from fastapi import APIRouter, HTTPException
router = APIRouter()
@router.get("/hello")
async def say_hello(name: str = "world"):
"""Return a friendly greeting."""
return {"message": f"Hello, {name}!"}
For a complete implementation example, reference api/routers/notebooks.py, which demonstrates the full pattern including validation, repository calls, and error handling.
Step 2: Define Pydantic Models (Optional)
If your endpoint requires request bodies or typed responses, define Pydantic models in api/models.py. The existing routers import schemas from this central location to ensure consistency across the API.
For example, the notebook router uses NotebookCreate and NotebookResponse models defined in this file. Add your models here when you need structured data validation:
from pydantic import BaseModel
class NoteCreate(BaseModel):
title: str
content: str
note_type: str
class NoteResponse(BaseModel):
id: str
title: str
content: str
Step 3: Implement the Endpoint Function
Write an async function that handles the request logic. Follow these conventions from the Open Notebook source code:
- Use type annotations for parameters (
Query,Path, or request body types) - Raise
HTTPExceptionfor error handling - Call domain objects from
open_notebook/domain/(e.g.,Note,Notebook) - Use database utilities like
repo_queryorensure_record_idfromopen_notebook/database/repository.py
Here is a complete example based on the pattern in api/routers/notes.py:
from fastapi import APIRouter, HTTPException
from api.models import NoteCreate, NoteResponse
from open_notebook.domain.notebook import Note
router = APIRouter()
@router.post("/notes", response_model=NoteResponse)
async def create_note(note: NoteCreate):
try:
new_note = Note(
title=note.title,
content=note.content,
note_type=note.note_type,
)
await new_note.save()
return NoteResponse(id=new_note.id, title=new_note.title, content=new_note.content)
except Exception as e:
raise HTTPException(status_code=500, detail=str(e))
Step 4: Register the Router in the FastAPI Application
Open api/main.py and import your new router module. The main application file already includes dozens of routers; add your registration line alongside the existing ones.
Add the include_router call with the standard /api prefix and appropriate tags for documentation grouping:
# api/main.py
from api.routers import hello # Import your new router
# ... existing app initialization ...
app.include_router(hello.router, prefix="/api", tags=["hello"])
The prefix="/api" parameter ensures all routes follow the standard URL structure, while tags organize endpoints in the automatically generated Swagger UI documentation.
Complete Working Example
Here is the minimal code required to add a functional endpoint to Open Notebook:
File: api/routers/hello.py
from fastapi import APIRouter, HTTPException
router = APIRouter()
@router.get("/hello/{name}")
async def read_hello(name: str):
if not name:
raise HTTPException(status_code=400, detail="Name is required")
return {"message": f"Hello, {name}!"}
File: api/main.py (add near other router imports)
from api.routers import hello
app.include_router(hello.router, prefix="/api", tags=["hello"])
After registering, the endpoint becomes available at /api/hello/{name} and appears in the Swagger documentation at /docs.
Key Source Files and Architecture
Understanding these files helps you follow the established patterns when adding endpoints:
api/main.py— The FastAPI entry point that aggregates all routers and configures the application.api/routers/<feature>.py— Individual router modules (e.g.,notebooks.py,notes.py) containing endpoint definitions.api/models.py— Central location for Pydantic request/response schemas shared across routers.open_notebook/domain/notebook.py— Domain objects likeNotebookandNotethat encapsulate business logic.open_notebook/database/repository.py— Database utilities includingrepo_queryandensure_record_idthat routers call for data persistence.
Summary
- Create a new router file in
api/routers/usingAPIRouterto define your endpoints. - Define Pydantic models in
api/models.pyfor type-safe request and response validation. - Implement async endpoint functions that use domain objects from
open_notebook/domain/and handle errors withHTTPException. - Register the router in
api/main.pyusingapp.include_router()withprefix="/api"and appropriate tags. - Test your endpoint using the Swagger UI at
/docsor by runninguvicorn api.main:app.
Frequently Asked Questions
Where should I define Pydantic models for my new endpoint?
Define Pydantic models in api/models.py. This file serves as the central schema repository for the entire FastAPI application, used by routers like notebooks.py to validate requests and serialize responses consistently.
How do I handle database operations in my new endpoint?
Import domain objects from open_notebook/domain/ (such as Note or Notebook) and use methods like save() or utilities from open_notebook/database/repository.py such as repo_query and ensure_record_id. This follows the repository pattern used throughout the codebase.
Does FastAPI automatically document my new endpoint?
Yes. When you register the router with the tags parameter in app.include_router(), FastAPI automatically generates OpenAPI documentation at the /docs endpoint. No additional configuration is required for basic documentation.
What is the standard URL prefix for API routes in Open Notebook?
The standard prefix is /api. When registering your router in api/main.py, always include prefix="/api" in the include_router call to maintain consistency with existing endpoints like /api/notebooks and /api/notes.
Have a question about this repo?
These articles cover the highlights, but your codebase questions are specific. Give your agent direct access to the source. Share this with your agent to get started:
curl -s "https://instagit.com/install.md" Maintain an open-source project? Get it listed too →