Courses Curriculum Cities Blog Enroll Now
Build the FastAPI Backend · Day 2 of 5 ~45 minutes

Day 2: Build the FastAPI Backend

Build the backend API that receives documents, calls Claude, and returns structured analysis. By the end, you'll have a working AI endpoint you can call with curl or Postman.

1
Day 1
2
Day 2
3
Day 3
4
Day 4
5
Day 5
What You'll Build

A complete FastAPI backend: document analysis endpoint that calls Claude, structured JSON response with summary, key points, and sentiment, and error handling for all failure modes.

1
Section 1 · 10 min

The Analysis Endpoint

pythonbackend/main.py
from fastapi import FastAPI, HTTPException
from fastapi.middleware.cors import CORSMiddleware
from pydantic import BaseModel
import anthropic, json

app = FastAPI()
app.add_middleware(CORSMiddleware,
    allow_origins=["http://localhost:3000"],
    allow_methods=["*"], allow_headers=["*"])
client = anthropic.Anthropic()

class AnalyzeRequest(BaseModel):
    text: str

@app.post("/analyze")
def analyze(req: AnalyzeRequest):
    if not req.text.strip():
        raise HTTPException(400, "text is required")

    msg = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=1024,
        system="Analyze the provided text. Return JSON only: {summary, key_points: [], sentiment, word_count, reading_time_minutes}",
        messages=[{"role": "user", "content": req.text}]
    )
    try:
        return json.loads(msg.content[0].text)
    except json.JSONDecodeError:
        return {"summary": msg.content[0].text, "key_points": []}
2
Section 2 · 15 min

Test the Endpoint

Start the server: uvicorn main:app --reload

Test with curl:

bash
$ curl -X POST http://localhost:8000/analyze   -H "Content-Type: application/json"   -d '{"text": "Artificial intelligence is transforming industries worldwide. Companies that adopt AI early gain significant competitive advantages. However, implementation requires careful planning and expertise."}'

Also visit http://localhost:8000/docs and test from the interactive UI. Verify the JSON response has all the expected fields.

JSON parsing tip: Instruct Claude to start its response with an opening brace: add to the system prompt "Start your response with {" — this almost eliminates cases where Claude adds text before the JSON.

3
Section 3 · 20 min

Add More Endpoints

Add two more endpoints to make the backend complete:

pythonbackend/main.py (additions)
@app.post("/summarize")
def summarize(req: AnalyzeRequest):
    msg = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=512,
        system="Summarize in 3 sentences or less. Output only the summary.",
        messages=[{"role": "user", "content": req.text}]
    )
    return {"summary": msg.content[0].text}

@app.post("/questions")
def generate_questions(req: AnalyzeRequest):
    msg = client.messages.create(
        model="claude-sonnet-4-20250514",
        max_tokens=512,
        system="Generate 5 thoughtful questions about this text. Return JSON: {questions: []}",
        messages=[{"role": "user", "content": req.text}]
    )
    return json.loads(msg.content[0].text)

What You Learned Today

  • How to build a FastAPI endpoint that calls Claude and returns structured JSON
  • The JSON parsing pattern: ask Claude for JSON, parse it, handle JSONDecodeError gracefully
  • CORS middleware: why it's needed and how to configure it for your frontend URL
  • Testing API endpoints with curl and the /docs interactive interface
Your Challenge

Go Further on Your Own

  • Add a /tone endpoint that analyzes the tone of a text: formal/casual/aggressive/passive with 1-sentence explanation
  • Add request size limits: reject requests where text is over 10,000 characters with a clear error message
  • Add logging: log every request with timestamp, text length, and response time. This is essential for debugging production issues.
Day 2 Complete

Nice work. Keep going.

Day 3 is ready when you are.

Continue to Day 3
Course Progress
40%

Want live instruction and hands-on projects? Join the AI bootcamp — 3 days, 5 cities.

Finished this lesson?