Welcome to the fifth lesson of our course on building an image generation service with FastAPI! In our previous lessons, we've built several key components of our application: the PromptManager for formatting user inputs, the ImageManager for storing and processing images, the ImageGeneratorService for connecting to Google's Gemini API, and most recently, the ImageGeneratorRouter, which handles input validation and response formatting.
Now it's time to bring everything together by creating the FastAPI application that will expose our functionality through HTTP endpoints. This is the final piece of our backend architecture that will allow users to interact with our image generation service through a web interface.
Our FastAPI API will have three main routes:
- A route to serve the main HTML page
- A route to handle image generation requests
- A route to retrieve all previously generated images
By the end of this lesson, you'll have a complete FastAPI API that integrates with the router we built previously, providing a clean interface for clients to generate and retrieve images.
Let's start by creating our FastAPI application. We'll set up the basic structure in our app/main.py file:
We create a FastAPI application instance by calling FastAPI() with a title for our API. We determine the base directory of the current script and set up Jinja2Templates to handle our HTML templates, passing the directory where our templates are located.
We also mount a static files directory to serve static assets like CSS, JavaScript, and images.
Finally, we create an instance of our ImageGeneratorRouter. This router handles the business logic for our API endpoints.
Now that we have our FastAPI application set up, let's define the routes that will handle client requests.
We'll start with the index route, which will serve the main HTML page of our application:
Next, let's define the route for generating images:
This route is more complex. The decorator @app.post("/api/generate_image") specifies that this function should be called when a client sends a POST request.
Inside the function, we extract the user_input from the request body using FastAPI's Body parameter. We then pass this input to our router's generate_image method.
If the router returns a tuple (like ({'error': 'Missing input'}, 400)), we check for the error pattern and raise an HTTPException with the appropriate status code. Otherwise, we return the response containing the base64 string.
On the frontend, this base64 image will be interpreted as a PNG (because of our implementation in ImageManager), meaning an HTML <img> tag could display it using:
Finally, let's define the route for retrieving all previously generated images:
Now that we have our FastAPI application and routes defined, let's configure the server to run our application. We'll add the following code at the end of our app/main.py file:
This code block uses Uvicorn to run the FastAPI server, listening on all network interfaces (host="0.0.0.0") on port 8000.
In this lesson, we've built a complete FastAPI API that integrates with our ImageGeneratorRouter to provide a web interface for our image generation service.
This completes the server-side portion of our image generation application! You've built a robust, modular architecture with a clear separation of concerns. In the upcoming practice exercises, you'll have the opportunity to test the API endpoints we've created.
