Hello again! It's great to have you back.
In our last lesson, you successfully created a Flask endpoint for grammar and spelling correction. You learned the fundamental pattern of setting up the Gemini library, crafting a specific instruction (a prompt), and using it to process user text.
Today, we will build on that exact foundation to add another powerful feature to your writing assistant. The goal for this lesson is to create a Flask endpoint that uses the Gemini API for text summarization. You'll see how quickly you can add new AI capabilities once the initial setup is complete, often just by changing the instructions you give the model.
1. The Reusable AI Pattern
Think back to the /api/correct-grammar endpoint you built. The workflow was:
- Receive text from a
POSTrequest. - Combine that text with a specific instruction (the prompt).
- Send the complete prompt to the Gemini API.
- Receive the AI's response.
- Send the processed text back as a JSON response.
This pattern is the core of our application. To add a summarization feature, we don't need to change the process; we only need to change the instruction we give the AI in step 2.
2. Prompting for Summarization
For the grammar checker, our prompt was focused and restrictive: "You are an expert editor... Correct the grammar and spelling... Only return the corrected text..."
For summarization, we need a different kind of instruction. We want the AI to understand a piece of text and distill its main points into a shorter version. A good prompt for this would be:
"You are an expert writer. Summarize the following text into a concise paragraph. The summary should capture the main points and key information, while maintaining a neutral tone."
This prompt works well because it:
- Assigns a role: "You are an expert writer."
- Defines the task: "Summarize the following text..."
- Sets output constraints: "...into a concise paragraph... capture the main points... maintaining a neutral tone."
This is the essence of prompt engineering: clearly defining the role, task, and desired output format for the AI.
3. Fine-Tuning the AI's Output with Parameters
Beyond the prompt text itself, we can also control the AI's behavior using configuration parameters. One of the most important is temperature.
- Low Temperature (e.g., 0.1 to 0.3): Makes the model more deterministic and factual. It will stick closely to the most likely words, which is ideal for tasks like summarization and fact-based responses.
- High Temperature (e.g., 0.7 to 1.0): Makes the model more creative and unpredictable. This is useful for brainstorming, writing stories, or generating varied stylistic options.
For summarization, we want the AI to stick to the content of the original text, so a lower temperature is best. The following video explains this and other useful parameters you can experiment with in the Google AI Studio playground.
How to Use the Gemini API with Python - Build a Customizable AI Chatbot
This clip from 'How to Use the Gemini API with Python' by Aaron Dunn provides an excellent overview of the model parameters you can control.
Watch the segment from 00:53 to 03:00. Pay close attention to the explanation of the 'temperature' parameter and how it influences the model's output from predictable to creative.
We will apply this knowledge by adding a generation_config to our API call to set the temperature.
4. Implementing the Summarization Endpoint
Now, let's add the new /api/summarize endpoint to your app.py file. The code will look very familiar, which is a good thing! It means the skills you're learning are reusable.
Add the following code to app.py, right below your correct_grammar_endpoint function.
# In app.py, after the correct_grammar_endpoint function
@app.route('/api/summarize', methods=['POST'])
def summarize_endpoint():
user_text = request.json.get('text')
if not user_text:
return jsonify({'error': 'No text provided'}), 400
# A prompt specifically for summarization
prompt = (
"Summarize the following text into a single, concise paragraph, "
"capturing the main points and key information.\n\n"
"Text: " + user_text
)
# Configuration for the model generation
generation_config = genai.types.GenerationConfig(
temperature=0.2 # Lower temperature for factual summary
)
try:
# Call the Gemini API with the new prompt and config
response = model.generate_content(
prompt,
generation_config=generation_config
)
# Return the summary in a JSON object
summary_text = response.text
return jsonify({'summary_text': summary_text.strip()})
except Exception as e:
# Handle potential API errors
print(f"An error occurred: {e}")
return jsonify({'error': 'Failed to communicate with the AI model.'}), 500
Code Breakdown:
- We define a new route,
/api/summarize. - We create a
promptvariable with our new summarization instructions. - We create a
generation_configobject to set thetemperatureto a low value (0.2), ensuring a more focused and factual summary. - In the
model.generate_content()call, we now pass both thepromptand thegeneration_config. - The rest of the logic—error handling and returning a JSON response—is identical to what you did in the last lesson.
Test your understanding!
Imagine you wanted to create another feature for "style improvement" that rephrases text to be more creative or formal. Based on what you just learned, what two things in the summarize_endpoint function would you primarily change to create this new feature?
Show answer
- The
promptstring: You would change it to something like, "Rewrite the following text to be more formal and professional, suitable for a business proposal." - The
temperatureingeneration_config: You would likely increase the temperature (e.g., to 0.7 or higher) to allow the model more creative freedom in rephrasing the text.
5. Testing Your New Summarization Feature
Let's test the endpoint.
-
Make sure your
app.pyfile is saved with the new code. -
Run your Flask application from the terminal:
python app.py. -
Open Postman or Insomnia.
-
Create a new
POSTrequest tohttp://127.0.0.1:5000/api/summarize. -
In the
Bodytab, selectJSONand enter a longer piece of text. For example:{ "text": "The client-server model is a distributed application structure that partitions tasks or workloads between the providers of a resource or service, called servers, and service requesters, called clients. Often clients and servers communicate over a computer network on separate hardware, but both client and server may reside in the same system. A server host runs one or more server programs which share their resources with clients. A client does not share any of its resources, but requests a server's content or service function. Clients therefore initiate communication sessions with servers which await incoming requests. Examples of computer applications that use the client–server model are Email, network printing, and the World Wide Web." } -
Send the request.
You should get back a JSON response containing a concise summary, something like this:
{
"summary_text": "The client-server model is a system where tasks are divided between servers, which provide resources, and clients, which request them. While they can be on the same system, clients and servers typically communicate over a network. The client initiates communication to access a server's content or services, as seen in applications like email, network printing, and the World Wide Web."
}
Excellent! You've just added a second AI-powered feature to your application backend.
Conclusion
In this lesson, you leveraged your existing knowledge to quickly and efficiently add a new, valuable feature. This demonstrates a key principle in software development: building reusable patterns.
Key Takeaways:
- The core pattern for calling an AI API (endpoint -> prompt -> call -> response) can be reused for many different features.
- Prompt engineering is the primary tool for directing the AI to perform different tasks, like summarizing instead of correcting grammar.
- Model parameters like
temperaturegive you finer control over the AI's output, allowing you to tune it for factuality or creativity.
You've now built two of the core AI features for your writing assistant. However, our endpoints currently assume the user always provides valid input. In the next lesson, we will make our backend more robust by implementing server-side validation to handle invalid inputs, such as empty text submissions.