Hello! Welcome back to the course.
In our last lesson, you learned the art of prompt engineering. We moved from simple questions to crafting detailed, structured prompts that guide the Gemini AI to produce high-quality results. You even designed a specific prompt for a text summarization task.
Today, we'll bring that theory into practice. Our goal is to create a Flask endpoint that calls the Gemini API with the user's prompt. This is a major step: we're building the bridge between our web application's backend and the powerful AI model. We will combine your knowledge of Flask from Module 5 with the Gemini API concepts we've been covering.
By the end of this lesson, you will have a working server that can receive text from a user, send it to Google's AI for summarization, and send the result back.
The Role of the Backend Endpoint
First, let's clarify the role of the component we are building. In our application, the user will type text into a web page (the frontend). When they click "Summarize," the browser will send that text to our Flask server (the backend).
The Flask endpoint we're creating is the specific part of our server that will "catch" this incoming request, process it, and send a response. Because the user will be sending a block of text, we'll use a POST request, which is designed to handle sending data in the request body.

Setting Up Your app.py for API Calls
To get started, we need to bring together the code for running a Flask server and the code for interacting with the Gemini API. This means our app.py file will need a few key ingredients right at the top.
Let's look at the full code for our app.py file. We will then break it down section by section.
import os
from dotenv import load_dotenv
from flask import Flask, request, jsonify
import google.generativeai as genai
# Load environment variables from a .env file
load_dotenv()
# Configure the Gemini API with the key from environment variables
try:
api_key = os.getenv('GEMINI_API_KEY')
if not api_key:
raise ValueError("GEMINI_API_KEY not found in environment variables. Please set it in your .env file.")
genai.configure(api_key=api_key)
print("Gemini API configured successfully.")
except Exception as e:
print(f"Error configuring Gemini API: {e}")
# We might want to exit or handle this more gracefully
# For now, we'll print the error and continue, but API calls will fail.
# Initialize the Flask application
app = Flask(__name__)
# Define the summarization endpoint
@app.route('/api/summarize', methods=['POST'])
def summarize_endpoint():
# 1. Get the text from the incoming JSON request
if not request.is_json:
return jsonify({"error": "Missing JSON in request"}), 400
data = request.get_json()
user_text = data.get('text', '').strip() # Use .get for safety, strip whitespace
if not user_text:
return jsonify({"error": "The 'text' field is required and cannot be empty."}), 400
# 2. Construct the full prompt using our template from the previous lesson
full_prompt = f"""
Act as an expert editor specializing in creating concise and clear summaries.
Summarize the following text for a busy professional who needs to quickly grasp the main points.
The summary should be approximately 3-4 sentences long and written in a formal, professional tone.
Focus only on the key findings and conclusions. Provide the summary as a single paragraph.
Here is the text:
---
{user_text}
---
"""
try:
# 3. Call the Gemini API
model = genai.GenerativeModel('gemini-pro')
response = model.generate_content(full_prompt)
# 4. Return the AI's response text
summary = response.text
return jsonify({'summary': summary})
except Exception as e:
# Handle potential errors from the API call
print(f"An error occurred during API call: {e}")
return jsonify({"error": "Failed to generate summary due to an internal error."}), 500
# Standard Flask entry point
if __name__ == '__main__':
app.run(debug=True, port=5000)
Now, let's understand this code by examining a similar real-world example and then breaking down our own code.
Building a Sustainable Living Tips Generator with Next.js, ...
The article 'Building a Sustainable Living Tips Generator' provides an excellent, complete app.py file that integrates Flask with the Gemini API. We will use it as a reference to understand the structure of our own application.
Scan through the code in the app.py section of the article. You don't need to understand every single line, but focus on the overall structure: The imports at the top (os, Flask, genai, etc.). The initialize_ai_model() function that configures the API key. The Flask route definition: @app.route('/api/tips', methods=['POST']). How it gets data from the request: data = request.get_json(). How it calls a separate function to generate AI content.
Breaking Down Our summarize Endpoint
As you saw in the reference article and our code, the process inside a Flask endpoint follows a clear pattern. Let's walk through our @app.route('/api/summarize', methods=['POST']) endpoint step-by-step.
1. Getting User Input
First, we need to get the text that the user wants to summarize. It will be sent as a JSON object in the body of the POST request, looking something like this: {"text": "This is the long article I want to summarize..."}.
# Get the text from the incoming JSON request
if not request.is_json:
return jsonify({"error": "Missing JSON in request"}), 400
data = request.get_json()
user_text = data.get('text', '').strip()
if not user_text:
return jsonify({"error": "The 'text' field is required..."}), 400
request.get_json()parses the incoming JSON data into a Python dictionary.- We use
data.get('text', '')as a safe way to access the text. If the 'text' key doesn't exist, it returns an empty string instead of crashing. .strip()removes any accidental leading or trailing whitespace.- We then check if
user_textis empty and return an error if it is. This is basic server-side validation.
Test your understanding!
Imagine the incoming JSON from the user looks like this: {"article_content": "A long story...", "author": "Jane Doe"}. How would you modify the code to get the article content and store it in the user_text variable?
Show answer
You would change data.get('text', '') to data.get('article_content', '').
The line would look like this:user_text = data.get('article_content', '').strip()
This is because you need to use the key that matches the incoming JSON data (article_content).
2. Constructing the Prompt
This is where we use the prompt you designed in the last lesson! We use a Python f-string to embed the user_text directly into our detailed instructions.
full_prompt = f"""
Act as an expert editor...
...
Here is the text:
---
{user_text}
---
"""
This combines our fixed instructions (the persona, task, format, etc.) with the dynamic content from the user, creating a complete, high-quality prompt for the API.
3. Calling the Gemini API
Now for the main event. This is where our server talks to Google.
To see this specific part in action, let's watch a quick video clip.
Gemini API with Python - Getting Started Tutorial
The following video clip gives a clear, concise demonstration of the core Python code used to call the Gemini API.
Watch the section from 04:10 to 05:25. Pay close attention to the client.generate_content() or model.generate_content() method. Notice how it takes a model name and the prompt as arguments, and how the result is accessed via response.text.
As the video demonstrates, the process is straightforward with the google-genai library. In our code, it looks like this:
try:
# Initialize the model we want to use
model = genai.GenerativeModel('gemini-pro')
# Send the prompt and get the response
response = model.generate_content(full_prompt)
# Extract the text part of the response
summary = response.text
# Send the summary back to the user
return jsonify({'summary': summary})
except Exception as e:
# Handle errors
print(f"An error occurred during API call: {e}")
return jsonify({"error": "Failed to generate summary..."}), 500
genai.GenerativeModel('gemini-pro')selects the specific AI model we want to use.model.generate_content(full_prompt)is the line that actually sends our prompt to the Gemini API and waits for a response.- We wrap this call in a
try...exceptblock. This is crucial for handling potential issues, like the API service being down or our request being invalid. If an error occurs, we return a helpful JSON error message with a500 Internal Server Errorstatus code.
Conclusion
Congratulations! You have successfully created a fully functional Flask endpoint that integrates with a powerful generative AI. You've built the core logic of your application's backend.
Key Takeaways:
- A Flask
POSTendpoint is ideal for receiving larger amounts of data, like text for summarization. - You can access incoming JSON data using
request.get_json(). - Using f-strings is an effective way to insert user-provided data into a pre-designed prompt template.
- The
google-genailibrary makes calling the Gemini API simple withgenai.GenerativeModel()andmodel.generate_content(). - Wrapping API calls in
try...exceptblocks is essential for robust error handling.
In the next lesson, we will look closer at the response object we get back from the Gemini API. While response.text gives us a quick result, the full response contains more information that allows us to handle things more safely and extract content more reliably. We will learn how to parse the JSON response from the Gemini API to extract the generated text, making our application even more robust.