response.text: extracting the output
Why this matters
When you call the Gemini API, you get a response object with multiple fields. <code>response.text</code> is the primary way to access the actual generated text: knowing this is the first step to working with model output in production code.
Explanation
What it does: The response.text property is a convenience accessor that extracts the text content from the first candidate in the Gemini API response. After you call model.generate_content(), the response object contains all the metadata, safety ratings, and generated content. response.text gives you just the text without needing to navigate the nested structure.
How it works: Under the hood, the response object has a candidates list (usually one candidate), and each candidate has content.parts which contains one or more content blocks. response.text automatically fetches the text from the first part of the first candidate. This is a shorthand: if you need fine-grained control (like checking safety ratings or accessing multiple parts), you'll access the nested structure directly.
When to use it: Use response.text for simple text generation tasks where you just need the output string. For anything more complex (streaming, safety analysis, or structured outputs), work with the full response object.
Request code
import os
import google.generativeai as genai
genai.configure(api_key=os.environ['GOOGLE_API_KEY'])
model = genai.GenerativeModel('gemini-2.0-flash')
response = model.generate_content('Explain quantum entanglement in one sentence.')
print(response.text) Authentication
Set your API key before making any request:
1. Get your API key from aistudio.google.com/app/apikeys
2. Set environment variable: export GOOGLE_API_KEY='your-key-here'
3. In Python, configure before first call:
import os
import google.generativeai as genai
genai.configure(api_key=os.environ['GOOGLE_API_KEY'])
Response shape
| Field | Description |
|---|---|
text | str: the generated text output |
candidates | list[Content]: list of response candidates (usually length 1) |
usage_metadata | dict with prompt_token_count, candidates_token_count, total_token_count |
safety_ratings | list of SafetyRating objects with category and probability |
Field guide
text The string output you want. This is what <code>response.text</code> extracts. Use this for the actual model output.
candidates Hidden but crucial: if you need to check why the model stopped (finish_reason), check <code>response.candidates[0].finish_reason</code>. Values like 'STOP' (normal completion) vs 'SAFETY' (content filtered) tell you why generation ended.
usage_metadata Track token counts here to monitor API costs. <code>response.usage_metadata.total_token_count</code> is what you're billed for.
safety_ratings If a response is blocked, <code>response.candidates[0].content</code> may be None. Always check before accessing <code>response.text</code> in production.
Setup trap
Setting os.environ['GOOGLE_API_KEY'] *after* calling genai.configure() does not work. The configure() call reads the environment variable at instantiation time. Set the environment variable or pass the key directly to genai.configure(api_key='...') before creating the model.
Cost
Each call to <code>generate_content()</code> is billed based on <code>usage_metadata.total_token_count</code>. As of April 2026, Gemini 2.0 Flash costs ~$0.075 per million input tokens and ~$0.30 per million output tokens. Monitor token counts in production; a 10,000-token response costs ~$0.003.
Rate limits
Free tier: 15 requests per minute. Paid tier: up to 10,000 requests per minute depending on quota. If you hit a 429 error, implement exponential backoff: wait 1s, then 2s, then 4s before retrying.
Common gotcha
Calling response.text when the response was blocked by safety filters raises an AttributeError because text property returns None. Always wrap it in a safety check: if response.candidates[0].finish_reason.name == 'SAFETY': handle_blocked_response() before accessing response.text.
Error recovery
AttributeError: 'NoneType' object has no attribute '__getitem__'google.auth.exceptions.DefaultCredentialsErrorgoogle.api_core.exceptions.ResourceExhaustedValueError: model_name is requiredExperienced dev note
In production, never assume response.text exists. The Gemini API can return responses with no text (e.g., safety-blocked, streaming interrupted, or function-call mode). Always implement this pattern: if response.candidates and response.candidates[0].content.parts: text = response.text. This saves you from silent failures where response.text silently returns None and your downstream code breaks.
Check your understanding
You call generate_content() and the response object has candidates[0].finish_reason.name == 'SAFETY'. What does response.text return, and why would directly using it in production code be dangerous?
Show answer hint
When a response is blocked by safety filters, the content is filtered and <code>response.text</code> returns None (or an empty value). Accessing it directly without checking <code>finish_reason</code> first will cause a crash or silent failure in downstream code that expects a string.
response.text is the recommended accessor. In 0.1.x, the response structure was different. Always pin your library version: pip install google-generativeai==0.8.x.