from google import genaiGemini Tutorial
Google Gemini API for Python
This tutorial is a subset of the lab assignment.
This part gives you your first experience using the Gemini Python API. We walk through the official tutorials and try to abstract away the complicated parts of the official documentation.
Google’s Gemini API uses a Python interface. This is unlike the Genius and Wikipedia APIs, which used special URLs to access data. To access the Gemini API, we install the google-genai, which installs related google packages.
Gemini API Key
We shared an API key with you through email. This individualized API key allows Gemini to recognize who is using their API.
Please DO NOT share your API key outside of this class. We will disable your API key (1) if you misuse it, (2) if you exceed the free usage tier during the project, and (3) for all students after the semester has ended.
If you’d like to play around with your code after the term, you’ll have to get your own API key. Ask us how to do this!
Remember that we avoid storing our API keys publicly. In api_key.py, we set my_client_access_token to be this string of alphanumeric characters. We then load it into our notebook environment as the Python name GOOGLE_API_KEY.
import api_key
GOOGLE_API_KEY = api_key.my_client_access_tokenOur first (two) API request(s)
So far, the Genius and Wikipedia APIs we’ve worked with have been what is called RESTful APIs, where we specify a URL to access structured data from an endpoint. After making this request, we then processed the JSON response. Now, we will directly use a Python library API, developed by Google as part of their Gemini Software Development Kit (Gemini SDK).
Using a Python API means that we will make a Python client object using Google’s genai package, then call that object’s methods to get data from Gemini. A Python API is often more convenient than a RESTful API when (1) the input and output are both quite flexible in format, as is the case for Generative AI data, and (2) when we write code that will make multiple calls to the API across different functions.
The cell below imports Google’s genai Python module:
From chat interface to API
We will first examine the example API request listed in the Gemini Quickstart Documentation (“Make your first request”). You are welcome (and encouraged!) to browse this documentation.
An AI chatbot is an application on top of a large language model (LLM). The LLM is what takes in user prompts and returns text responses. The chatbot is what filters input, perhaps converting and loading files with additional prompts, and returns filtered LLM responses back, perhaps with some HTML or Markdown formatting.
Consider the chat prompt shown in the screenshot, as well as (the start of) the model’s response.
We define three pieces of terminology to describe what is happening in the above screenshot:
- The user prompt: “Explain how AI works in a few words.”
- The model response: “AI works by using algorithms to analyze…”
- The specified model: Here, it is “Fast” (note the dropdown in the bottom right). The other option is “Thinking.” We’ll discuss this more later.
Create the client then make the request
The below code uses Gemini’s Python API to directly query the Gemini LLM with this prompt. We describe the behavior below the cell.
# first, create the client
client = genai.Client(api_key=GOOGLE_API_KEY)
# then make the API request
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Explain how AI works in a few words"
)
print(response.text)AI learns patterns from data to make intelligent decisions.
What just happened (and how you would make these API calls):
Make an API client: Make a Gemini client object called
client, which passes in your API key. (We will do this for you usually.) This client lets you access different API calls via its methods. We will focus on one specific method in this class,generate_content.Make the API request. Call
generate_content, available in viaclient.models. This cell takes in several arguments, which we specify by name:model: The underlying large language model. Here we specify Gemini 2.5 Flash, which is equivalent to the “Fast” option in the Gemini chatbot.contents: The prompt: “Explain how AI works in a few words.” We discuss the type ofcontentslater.
Receive a response.
responseis a Gemini-specific object type. The details are too complicated for this course. Instead, we focus on the valueresponse.text, the LLM response string itself.
Make another API request
Once we have created the API client, we do not need to remake the client. Instead, we can just make more calls to generate_content.
Remember—LLMs are random response generators, so you will likely get a different response back!
# client is already created, so just call generate_content
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="Explain how AI works in a few words"
)
print(response.text)AI learns patterns from data to make smart predictions and decisions.
Different Gemini Models
You can specify different Gemini models to get different responses. Some more advanced models will produce higher-quality responses, though with the tradeoff that each response will take longer and be more expensive.
We recommend a few models for this course:
- “Fast” Gemini 2.5 Flash model (
"gemini-2.5-flash"). Pretty fast, though depending on the time of day responses might still take a few seconds. Reasonable cost. - “Thinking” Gemini 2.5 Pro model (
"gemini-2.5-pro"). More in-depth responses, though responses will take significantly longer than Fast responses. Expensive. - Extra fast: Gemini 2.5 Flash-Lite (
"gemini-2.5-flash-lite"). Very fast, very cost effective.
Gemini Pro not only has longer request times. It is also more expensive per request. We strongly recommended testing out prompts with Gemini 2.5 Flash or Gemini 2.5 Flash-Lite. Once you are satisfied with your prompt, only then should you change models.
We use Gemini 2.5 Flash for the remainder of this tutorial.
Prompt Engineering
Prompt engineering is the process of structuring or crafting a prompt (natural language text instruction) in order to produce better outputs from a generative artificial intelligence (AI) model (source: Wikipedia).
Provide context
What is the best restaurant in Berkeley?
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="What is the best restaurant in Berkeley?"
)
print(response.text)Ah, the million-dollar question! "Best" is always subjective and depends entirely on what you're looking for (cuisine, price point, ambiance, occasion).
However, if we're talking about **iconic status, historical significance, and a consistently high-quality experience that influenced the entire culinary world,** the answer is almost universally:
1. **Chez Panisse (Restaurant or Cafe)**
* **Why it's often considered "the best":** Founded by Alice Waters, Chez Panisse is the birthplace of the farm-to-table movement. It emphasizes seasonal, local, and organic ingredients, cooked simply and perfectly.
* **The Downstairs Restaurant:** A fixed-price, multi-course menu that changes nightly. It's a true special occasion splurge and a culinary pilgrimage for many.
* **The Upstairs Cafe:** More casual, à la carte menu, still focused on exquisite ingredients but more accessible.
* **Best for:** Special occasions, foodies, those looking for a piece of culinary history.
Beyond Chez Panisse, Berkeley has a fantastic and diverse food scene. Here are some other contenders for "best" depending on your criteria:
**For a Special Occasion / Modern California Cuisine:**
* **Gather:** Excellent seasonal Californian cuisine with a focus on sustainable ingredients. Great cocktails and a lively atmosphere.
* **Corso:** Rustic, elegant Tuscan cuisine from Chez Panisse alum Wendy Brucker. Fantastic pasta and wood-fired dishes.
**For Lively & Delicious / Global Flavors:**
* **Comal:** Bustling, popular spot for Oaxacan-inspired Mexican food, amazing cocktails (especially their margaritas), and a great patio.
* **Kiraku:** Fantastic, authentic Japanese izakaya. Known for creative small plates, charcoal-grilled skewers, and an extensive sake list.
* **Great China:** A Berkeley institution for high-quality, delicious Peking duck and other Chinese dishes in a lively setting.
* **Agrodolce:** Sicilian comfort food in a cozy setting. Think fresh pastas, seafood, and hearty meat dishes.
**For Unique & Casual Institutions:**
* **The Cheese Board Collective:** A unique, worker-owned collective. They serve one type of vegetarian pizza a day (often with inventive toppings) and have an amazing bakery. Expect lines, but it's an iconic Berkeley experience.
* **Jupiter:** A popular brewpub with delicious wood-fired pizzas, a huge selection of craft beers, and a great outdoor patio.
**For Breakfast/Brunch:**
* **La Note:** Extremely popular for French country-style breakfast and brunch. Expect a wait, but it's worth it for their famous lavender honey lattes and rich omelets.
**To give you the *best* recommendation, I'd need to know:**
* **What kind of cuisine are you in the mood for?**
* **What's your budget like (cheap eats, moderate, fine dining)?**
* **What's the occasion (casual dinner, date night, special celebration, quick lunch)?**
* **What kind of ambiance do you prefer (lively, quiet, romantic, family-friendly)?**
Let me know more, and I can narrow it down!
The LLM response looks too general; these recommendations might not be great for the average college student. One core aspect of prompt engineering is to provide more context to the prompt.
Context can help define:
- What information you are looking for in the response, e.g., “Only include cheap meals under $15, and only consider restaurants that are open past 9pm.”
- How long you want the response to be, e.g., “Limit your response to 200 words.”
- What tone you want the response to have, e.g., “Imagine you are a UC Berkeley student talking to a fellow classmate.”
- How to structure the response: markdown, comma-separated, JSON, etc., e.g., “Format your response as a bulleted list.”
Note: Include linebreaks (with newline characters '\n', or use multi-line strings) to delineate different aspects of the prompt.
One way to provide detailed context is to just pass in a very, very long string as your prompt. See the example below. Note that the triple quotes (""") allows you to specify a multi-line string, with line breaks.
response = client.models.generate_content(
model="gemini-2.5-flash",
contents="""Imagine you are a UC Berkeley student talking to a fellow
classmate.
What is the best restaurant in Berkeley? Only include cheap meals
under $15, and only consider restaurants that are open past 9pm.
Format your response as a bulleted list. Limit your response to 200 words.
"""
)
print(response.text)Yo, fellow classmate! Okay, if we're talking best cheap eats open late, hands down, it's Thai Noodle II. Seriously, it's a Berkeley institution for a reason.
* **Thai Noodle II (on Telegraph Ave):** This place is an absolute lifesaver for students.
* **Super Affordable:** You can get massive portions of incredible Pad See Ew, Pad Thai, or a hearty curry for around $12-14. You often have leftovers!
* **Late Night Hero:** They're typically open until 9:30 or 10 PM on weekdays and even later on weekends, perfect for those late study sessions or after a club meeting.
* **Delicious & Fast:** The food is consistently fresh, flavorful, and they get your order out incredibly quickly. It's authentic Thai that always hits the spot.
* **Reliable Favorite:** It's a go-to for pretty much every Berkeley student because it's no-frills, always good, and won't drain your wallet.
Word count:
# this uses regular expressions, which we don't cover in this course
import re
def split_into_words(any_chunk_of_text):
lowercase_text = any_chunk_of_text.lower()
split_words = re.split(r"\W+", lowercase_text)
return split_words
len(split_into_words(response.text))152
Construct a prompt as a list of parts
As we’ve seen in this class time and time again, we want to reuse pieces of code, data, etc. The same is true of our prompts! A formatting context from one prompt may be very useful for an entirely different application, and it would be great to reuse the context string instead of duplicating string literals in different parts of our code.
The Gemini API supports multiple argument types for content. For this course, we focus on providing additional context to our prompts by passing in a list of strings to content. Passing in a list of strings is comparable to separating context parts with linebreaks and allows us to reuse parts of our context.
The below code specifies the same prompt as before but now with a list of strings passed into content. (Again, because LLMs are random text generators, the response may be different from before.)
context_character = "Imagine you are a UC Berkeley student talking to a fellow classmate."
context_format = "Format your response as a bulleted list. Limit your response to 200 words."
response = client.models.generate_content(
model="gemini-2.5-flash",
contents=[
context_character,
"""
What is the best restaurant in Berkeley? Only include cheap meals under $15,
and only consider restaurants that are open past 9pm.
""",
context_format
]
)
print(response.text)Alright, dude, if we're talking cheap, late, and "best" for a Cal student, this is a no-brainer:
* **Top Dog** is the absolute GOAT.
* **Why it's the best:** It's a quintessential Berkeley experience. You can get a couple of their legendary sausages, chips, and a drink for well under $15. It's fast, it's consistent, and it hits different when you're starving after a late study session.
* **Open Late:** Both the Durant and Shattuck locations are usually open until 2:30 AM, making it the ultimate late-night spot.
* **The Food:** My personal favorite is the Louisiana Hot Link with everything, but honestly, you can't go wrong with any of their sausages. It's a Berkeley institution for a reason!
Word count:
len(split_into_words(response.text))127
See the prompt engineering resources below for how to construct prompt for a variety of tasks.
Additional Reading
Official Documentation:
Prompt Engineering Resources:
- Gemini API: Prompting Strategies
- Ziem et al., Table 1: LLM Prompting Guidelines to generate consistent, machine-readable outputs for CSS tasks. Very useful for project.