
Week 5 Instructions for Spotify Agent Project
Hi All, welcome to week 5 of the Spotify Agent project.
This week, we'll be creating a backend API for our Spotify agent using a library called FastAPI.
Right now, our Spotify agent only works in the terminal - you run the script and interact with it through command line input. While this is great for testing, it's not very practical for real-world applications. Here's why we need a backend:
- Frontend: User interface (web page, mobile app, etc.)
- Backend: Business logic and AI agent processing
By separating out the backend (server where the agent code is running) from the frontend (the interface with which the user interacts), we can debug and evaluate each component individually. This tends to make development easier over time, especially as our application becomes more complex.
Separating applications into a distinct backend and frontend simulates real-world development, so you should be comfortable doing so.
## What is FastAPI?
FastAPI is a modern, fast web framework for building APIs with Python. It's perfect for our use case because:
Think of FastAPI as a way to use your Python functions as endpoints that other applications can call later.
Before we begin creating our backend, let's quickly create a new function in agent_script.py that enables us to use our agent outside of the main function. Copy and paste the following into your agent_script.py code
async def invoke_our_graph(agent, st_messages):
response = await agent.ainvoke({"messages": st_messages})
return response
The following function takes as input an agent object and a parameter called st_messages that represents the full message history with the agent. It then returns the response generated by the agent.
First, let's install the required dependencies. Run the following commands in your terminal:
uv pip install fastapi
uv pip install uvicorn
FastAPI is the web framework for writing our API code, and Uvicorn is server that will run our application.
Now let's create our backend step by step. Create a new file called backend.py in your spotify-agent folder.
### Step 1: Basic Imports and Setup
*from fastapi import FastAPI
from pydantic import BaseModel
from agent_script import create_graph, invoke_our_graph
import asyncio
from contextlib import asynccontextmanager
from typing import List, Dict, Any
from dotenv import load_dotenv
#Load environment variables (for API keys)
load_dotenv()*
Here's what each import does:
- FastAPI: The main framework class
- BaseModel: For defining request/response data structures. Don't worry about what this means for now, we'll get to it in a bit.
- agent_script imports: Our agent functions
- asynccontextmanager: For managing the application lifecycle, again don't worry about exactly what this means right now.
- typing: For type hints to make our code more readable and less prone to certain bugs.
*# Create the agent once at startup
@asynccontextmanager
async def lifespan(app: FastAPI):
# Startup: Create the agent when the server starts
print("Starting up... Creating Spotify agent...")
app.state.agent = await create_graph()
print("Agent created successfully!")
yield # Server is running
# Shutdown: Clean up when server stops
print("Shutting down...")*
This is a crucial concept! The lifespan function ensures that our agent is created once when the server starts (not every request) This is much more efficient than creating a new agent for every request, which would be slow and resource-intensive.
By the way, the @ in front of asynccontextmanager means that asynccontextmanager is a decorator function that we are applying to this lifespan function. Decorator functions are functions that take other functions as input and extend them with some kind of functionality (in this case handling asynchronous code). We'll work with decorators more in the future, so make sure to familiarize yourself with how they work.
*# Create FastAPI app with lifecycle management
app = FastAPI(
title="Spotify Agent API",
description="A FastAPI backend for the Spotify agent",
lifespan=lifespan
)*
This creates our FastAPI application and connects it to our lifecycle manager.
*class ChatQuery(BaseModel):
message: str*
Pydantic models: Pydantic is a library that allows us to define the structure of data coming into and going out of our API. This is important because we want to ensure the data coming in and out has the correct data type and format. For example, the agent takes a string as input to generate a response, it wouldnt make sense to send over an int or a bool because that could cause an error down the line.
Using pydantic like this provides automatic validation - FastAPI will reject requests that don't match the expected structure.
@app.post("/chat")
async def chat(query: Query):
agent = app.state.agent
response = await invoke_our_graph(agent, query.input)
if agent is None:
return {"error": "Agent not initialized"}
print(response)
return {"response": response}
We can eventually call this endpoint when we build our frontend (user interface) to interact with the agent.
Congratulations! You now have an API backend for your Spotify agent.
Okay, lets do some quick verification to make sure our API actually works properly
Run the following code in your terminal
uvicorn backend:app --reload --host 0.0.0.0 --port 8000
This line will launch a server using uvicorn from the backend.py file and specifically the "app" application on port 8000.
Now paste the following url into your browser
You should be able to test the chat endpoint directly here.
Once again thanks for joining us. See you all next week!