Using the Google Gemini 2.5 Flash APIs
August 10, 2025 note: I added an example client using Google’s Java Gemini SDK in the last section of this chapter. The earlier example uses the Gemini REST interface using only low-level Clojure libraries.
We used the OpenAI LLM APIs in the last chapter and now we provide a similar example using Google’s gemini-2.5-flash model.
I recommend reading Google’s online documentation for the APIs to see all the capabilities of the OpenAI APIs.
Test Code for REST Interface and Sample Test Output
Before we look at the example code, let’s look at an example code running it and later sample output:
1 (ns gemini-api.core-test
2 (:require [clojure.test :refer :all]
3 [gemini-api.core :refer :all]))
4
5 (def some-text
6 "Jupiter is the fifth planet from the Sun and the largest in the Solar System. It \
7 is a gas giant with a mass one-thousandth that of the Sun, but two-and-a-half times \
8 that of all the other planets in the Solar System combined. Jupiter is one of the br\
9 ightest objects visible to the naked eye in the night sky, and has been known to anc\
10 ient civilizations since before recorded history. It is named after the Roman god Ju\
11 piter.[19] When viewed from Earth, Jupiter can be bright enough for its reflected li\
12 ght to cast visible shadows,[20] and is on average the third-brightest natural objec\
13 t in the night sky after the Moon and Venus.")
14
15 (deftest completions-test
16 (testing "gemini completions API"
17 (let [results
18 (gemini-api.core/generate-content "He walked to the river")]
19 (println results))))
20
21 (deftest summarize-test
22 (testing "gemini summarize API"
23 (let [results
24 (gemini-api.core/summarize
25 some-text)]
26 (println results))))
27
28 (deftest question-answering-test
29 (testing "gemini question-answering API"
30 (let [results
31 (gemini-api.core/generate-content
32 "Where is the Valley of Kings?"
33 )]
34 (println results))))
The output (edited for brevity) looks like this:
1 $ lein test
2
3 **Adding detail:**
4
5 * He walked slowly to the river.
6 * He walked to the river, his head down.
7 * He walked to the river, eager to cool off.
8 * He walked to the river, his boots crunching on the gravel path.
9
10 **Adding context:**
11
12 * Tired of the city, he walked to the river.
13 * After the argument, he walked to the river.
14 * He walked to the river, seeking solace in its gentle flow.
15
16 **Setting the scene:**
17
18 * The sun beat down as he walked to the river.
19 * A cool breeze rustled the leaves as he walked to the river.
20 * The air smelled of damp earth as he walked to the river.
21
22 **Making it part of a longer narrative:**
23
24 * He walked to the river and sat down on the bank, watching the water flow by.
25 * He walked to the river, but when he arrived, he hesitated to go further.
26 * He walked to the river, knowing it was the only place he could truly be alone.
27
28
29 Jupiter, the fifth planet from the Sun, is the largest planet in our solar system, a\
30 gas giant exceeding the mass of all other planets combined. Easily visible to the n\
31 aked eye, it's been observed since ancient times and named after the Roman god Jupit\
32 er. Its brightness makes it a prominent object in the night sky, often third brighte\
33 st after the Moon and Venus.
34
35
36 The Valley of the Kings is located on the west bank of the Nile River, near the city\
37 of Luxor (ancient Thebes) in Egypt.
Gemini API Library Implementation for REST Interface
Here is the library implementation, we will discuss the code after the listing:
1 (ns gemini-api.core
2 (:require [clj-http.client :as client])
3 (:require [clojure.data.json :as json]))
4
5 (def model "gemini-2.0-flash") ; or gemini-1.5-pro, etc.
6
7 (def google-api-key (System/getenv "GOOGLE_API_KEY"))
8
9 (def base-url "https://generativelanguage.googleapis.com/v1beta/models")
10
11 (defn generate-content [prompt]
12 (let [url (str base-url "/" model ":generateContent?key=" google-api-key)
13 headers {"Content-Type" "application/json"}
14 body {:contents [{:parts [{:text prompt}]}]}]
15 (try
16 (let [response (client/post url {:headers headers
17 :body (json/write-str body)
18 :content-type :json
19 :accept :json})
20 parsed-response (json/read-str (:body response) :key-fn keyword)
21 candidates (:candidates parsed-response)]
22 (if (seq candidates)
23 (let [text (get-in (first candidates) [:content :parts 0 :text])]
24 (if text
25 text
26 (do
27 (println "No text found in response structure:" parsed-response)
28 nil)))
29 (do
30 (println "No candidates found in response:" parsed-response)
31 nil)))
32 (catch Exception e
33 (println "Error making request:" (.getMessage e))
34 (when-let [response-body (-> e ex-data :body)]
35 (println "Error response body:" response-body))
36 nil))))
37
38 (defn summarize [text]
39 (generate-content (str "Summarize the following text:\n\n" text)))
This Clojure code is designed to interact with Google’s Gemini API to generate text content and specifically to summarize text. It sets up the necessary components to communicate with the API, including importing libraries for making HTTP requests and handling JSON data. Crucially, it retrieves your Google API key from an environment variable, ensuring secure access. The code also defines configuration like the Gemini model to use and the base API endpoint URL. It’s structured within a Clojure namespace for organization and includes basic error handling and debug printing to aid in development and troubleshooting.
The core of the functionality lies in the generate-content function. This function takes a text prompt as input, constructs the API request URL with the chosen model and your API key, and then sends this request to Google’s servers. It handles the API response, parsing the JSON result to extract the generated text content. The code also checks for potential errors, both in the API request itself and in the structure of the response, providing informative error messages if something goes wrong. Building on this, the function summarize offers a higher-level interface, taking text as input and using generate-content to send a “summarize” prompt to the API, effectively providing a convenient way to get text summaries using the Gemini models.
(New) Gemini Client Library Using Google’s Java SDK for Gemini
The code for this section can be found in the directory ** Clojure-AI-Book-Code/gemini_java_api**.
We test code that is almost identical to that used earlier for the REST interface library so we don’t list the test code here.
Here is the library implementation:
1 (ns gemini-java-api.core
2 (:import (com.google.genai Client)
3 (com.google.genai.types GenerateContentResponse)))
4
5 (def DEBUG false)
6
7 (def model "gemini-2.5-flash") ; or gemini-2.5-pro, etc.
8 (def google-api-key (System/getenv "GOOGLE_API_KEY")) ; Make sure to set this env va\
9 riable
10
11 (defn generate-content
12 "Sends a prompt to the Gemini API using the specified model and returns
13 the text response."
14 [prompt]
15 (let [client (Client.)
16 ^GenerateContentResponse resp
17 (.generateContent (.models client)
18 model
19 prompt
20 nil)]
21 (when DEBUG
22 (println (.text resp))
23 (when-let [headers
24 (some-> resp
25 .sdkHttpResponse (.orElse nil)
26 .headers (.orElse nil))]
27 (println "Response headers:" headers)))
28 (.text resp)))
29
30 (defn summarize [text]
31 (generate-content (str "Summarize the following text:\n\n" text)))
I used the previous REST interface library implementation for over one year but now I have switched to using this shorter implementation that uses interop with the Java Gemini SDK.
Gemini APIs Wrap Up
The Gemini APIs also support a message-based API for optionally adding extra context data, configuration data, and AI safety settings. The example code using the REST interface provides a simple completion style of interacting with the Gemini models.
If you use my Java SDK example library you can clone it in your own projects and optionally use those features of the Java SDK that you might find useful. Reference: https://github.com/googleapis/java-genai.