Skip to main content

A reverse-engineered async wrapper for Google Gemini web client

Project description

Gemini Banner

PyPI Downloads Dependencies License Code style

GitHub stars GitHub issues CI

Gemini Icon Gemini-API

A reverse-engineered asynchronous python wrapper for Google Gemini web app (formerly Bard).

Features

  • Smart Cookies - Automatically import cookies and refresh them in background. Free up your hands!
  • ImageFx Support - Supports retrieving images generated by ImageFx, Google's latest AI image generator.
  • Extension Support - Supports generating contents with Gemini extensions on, like YouTube and Gmail.
  • Classified Outputs - Auto categorizes texts, web images and AI generated images from the response.
  • Official Flavor - Provides a simple and elegant interface inspired by Google Generative AI's official API.
  • Asynchronous - Utilizes asyncio to run generating tasks and return outputs efficiently.

Table of Contents

Installation

[!NOTE]

This package requires Python 3.10 or later.

Install the package with pip.

pip install gemini_webapi

Optionally, package offers a way to automatically import cookies from your local browser. To enable this feature, install browser-cookie3 as well. Supported platforms and browsers can be found here.

pip install browser-cookie3

Authentication

[!NOTE]

If browser-cookie3 is installed, you can skip this step and go directly to usage section. Just make sure you have logged in to https://gemini.google.com in your browser.

  • Go to https://gemini.google.com and login with your Google account
  • Press F12 for web inspector, go to Network tab and refresh the page
  • Click any request and copy cookie values of __Secure-1PSID and __Secure-1PSIDTS

[!TIP]

API's auto cookie refresh feature may cause that you need to re-login to your Google account in the browser. This is an expected behavior and won't affect the API's functionality. To avoid such result, it's recommended to get cookies from a separate browser session for best utilization (e.g. a fresh login in browser's private mode), or set auto_refresh to False in GeminiClient.init to disable this feature.

Usage

Initialization

Import required packages and initialize a client with your cookies obtained from the previous step. After a successful initialization, the API will automatically refresh __Secure-1PSIDTS in background as long as the process is alive.

import asyncio
from gemini_webapi import GeminiClient

# Replace "COOKIE VALUE HERE" with your actual cookie values.
# Leave Secure_1PSIDTS empty if it's not available for your account.
Secure_1PSID = "COOKIE VALUE HERE"
Secure_1PSIDTS = "COOKIE VALUE HERE"

async def main():
    # If browser-cookie3 is installed, simply use `client = GeminiClient()`
    client = GeminiClient(Secure_1PSID, Secure_1PSIDTS, proxies=None)
    await client.init(timeout=30, auto_close=False, close_delay=300, auto_refresh=True)

asyncio.run(main())

[!TIP]

auto_close and close_delay are optional arguments for automatically closing the client after a certain period of inactivity. This feature is disabled by default. In a keep-alive service like chatbot, it's recommended to set auto_close to True combined with reasonable seconds of close_delay for better resource management.

Generate contents from text

Ask a one-turn quick question by calling GeminiClient.generate_content.

async def main():
    response = await client.generate_content("Hello World!")
    print(response.text)

asyncio.run(main())

[!TIP]

Simply use print(response) to get the same output if you just want to see the response text

Generate contents from image

Gemini supports image recognition and generate contents from image (currently only supports one image at a time). Optionally, you can pass image data in bytes or its path in str to GeminiClient.generate_content together with text prompt.

async def main():
    response = await client.generate_content("Describe the image", image="assets/banner.png")
    print(response.text)

asyncio.run(main())

Conversations across multiple turns

If you want to keep conversation continuous, please use GeminiClient.start_chat to create a ChatSession object and send messages through it. The conversation history will be automatically handled and get updated after each turn.

async def main():
    chat = client.start_chat()
    response1 = await chat.send_message("Briefly introduce Europe")
    response2 = await chat.send_message("What's the population there?")
    print(response1.text, response2.text, sep="\n\n----------------------------------\n\n")

asyncio.run(main())

[!TIP]

Same as GeminiClient.generate_content, ChatSession.send_message also accepts image as an optional argument.

Retrieve images in response

Images in the API's output are stored as a list of Image objects. You can access the image title, URL, and description by calling image.title, image.url and image.alt respectively.

async def main():
    response = await client.generate_content("Send me some pictures of cats")
    for image in response.images:
        print(image, "\n\n----------------------------------\n")

asyncio.run(main())

Generate images with ImageFx

In February 2022, Google introduced a new AI image generator called ImageFx and integrated it into Gemini. You can ask Gemini to generate images with ImageFx simply by natural language.

[!IMPORTANT]

Google has some limitations on the image generation feature in Gemini, so its availability could be different per region/account. Here's a summary copied from official documentation (as of February 15th, 2024):

Image generation in Gemini Apps is available in most countries, except in the European Economic Area (EEA), Switzerland, and the UK. It’s only available for English prompts.

This feature’s availability in any specific Gemini app is also limited to the supported languages and countries of that app.

For now, this feature isn’t available to users under 18.

async def main():
    response = await client.generate_content("Generate some pictures of cats")
    for image in response.images:
        print(image, "\n\n----------------------------------\n")

asyncio.run(main())

[!NOTE]

by default, when asked to send images (like the previous example), Gemini will send images fetched from web instead of generating images with AI model, unless you specifically require to "generate" images in your prompt. In this package, web images and generated images are treated differently as WebImage and GeneratedImage, and will be automatically categorized in the output.

Save images to local files

You can save images returned from Gemini to local files under /temp by calling Image.save(). Optionally, you can specify the file path and file name by passing path and filename arguments to the function and skip images with invalid file names by passing skip_invalid_filename=True. Works for both WebImage and GeneratedImage.

async def main():
    response = await client.generate_content("Generate some pictures of cats")
    for i, image in enumerate(response.images):
        await image.save(path="temp/", filename=f"cat_{i}.png", verbose=True)

asyncio.run(main())

Generate contents with Gemini extensions

[!IMPORTANT]

To access Gemini extensions in API, you must activate them on the Gemini website first. Same as image generation, Google also has limitations on the availability of Gemini extensions. Here's a summary copied from official documentation (as of February 18th, 2024):

To use extensions in Gemini Apps:

Sign in with your personal Google Account that you manage on your own. Extensions, including the Google Workspace extension, are currently not available to Google Workspace accounts for school, business, or other organizations.

Have Gemini Apps Activity on. Extensions are only available when Gemini Apps Activity is turned on.

Important: For now, extensions are available in English, Japanese, and Korean only.

After activating extensions for your account, you can access them in your prompts either by natural language or by starting your prompt with "@" followed by the extension keyword.

async def main():
    response1 = await client.generate_content("@Gmail What's the latest message in my mailbox?")
    print(response1, "\n\n----------------------------------\n")

    response2 = await client.generate_content("@Youtube What's the lastest activity of Taylor Swift?")
    print(response2, "\n\n----------------------------------\n")

asyncio.run(main())

[!NOTE]

For the available regions limitation, it actually only requires your Google account's preferred language to be set to one of the three supported languages listed above. You can change your language settings here.

Check and switch to other reply candidates

A response from Gemini usually contains multiple reply candidates with different generated contents. You can check all candidates and choose one to continue the conversation. By default, the first candidate will be chosen automatically.

async def main():
    # Start a conversation and list all reply candidates
    chat = client.start_chat()
    response = await chat.send_message("Recommend a science fiction book for me.")
    for candidate in response.candidates:
        print(candidate, "\n\n----------------------------------\n")

    if len(response.candidates) > 1:
        # Control the ongoing conversation flow by choosing candidate manually
        new_candidate = chat.choose_candidate(index=1)  # Choose the second candidate here
        followup_response = await chat.send_message("Tell me more about it.")  # Will generate contents based on the chosen candidate
        print(new_candidate, followup_response, sep="\n\n----------------------------------\n\n")
    else:
        print("Only one candidate available.")

asyncio.run(main())

Control log level

You can set the log level of the package to one of the following values: DEBUG, INFO, WARNING, ERROR and CRITICAL. The default value is INFO.

from gemini_webapi import set_log_level

set_log_level("DEBUG")

References

Google AI Studio

acheong08/Bard

Stargazers

Star History Chart

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

gemini-webapi-1.0.2.tar.gz (188.7 kB view details)

Uploaded Source

Built Distribution

gemini_webapi-1.0.2-py3-none-any.whl (31.9 kB view details)

Uploaded Python 3

File details

Details for the file gemini-webapi-1.0.2.tar.gz.

File metadata

  • Download URL: gemini-webapi-1.0.2.tar.gz
  • Upload date:
  • Size: 188.7 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/4.0.2 CPython/3.11.8

File hashes

Hashes for gemini-webapi-1.0.2.tar.gz
Algorithm Hash digest
SHA256 aba813ee520804081e3a0b96b60f9adbf371b1881c63f96461ee722006fdedc5
MD5 0b904e6961cc1722dc412118702a1aad
BLAKE2b-256 4c57c5b6578815698829b8ecacb84e34aae381b0e3249dee7e9a187f27013954

See more details on using hashes here.

File details

Details for the file gemini_webapi-1.0.2-py3-none-any.whl.

File metadata

File hashes

Hashes for gemini_webapi-1.0.2-py3-none-any.whl
Algorithm Hash digest
SHA256 ddbdc0c6818f39a7b96e167ee06009cc552a60c8ff430f9bf0cc1ce934706dbc
MD5 db538a2891dc02a072dc1327d313412b
BLAKE2b-256 a9d89a8d132567f48b203cbb82db87529755b60b327e5667a9e4625ef6de36c0

See more details on using hashes here.

Supported by

AWS AWS Cloud computing and Security Sponsor Datadog Datadog Monitoring Fastly Fastly CDN Google Google Download Analytics Microsoft Microsoft PSF Sponsor Pingdom Pingdom Monitoring Sentry Sentry Error logging StatusPage StatusPage Status page