gemini-webapi 1.9.0__tar.gz → 1.17.0__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/.github/workflows/github-release.yml +1 -1
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/.github/workflows/pypi-publish.yml +5 -5
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/.gitignore +1 -1
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/PKG-INFO +197 -92
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/README.md +192 -89
- gemini_webapi-1.17.0/assets/sample.pdf +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/pyproject.toml +2 -1
- gemini_webapi-1.17.0/src/gemini_webapi/__init__.py +6 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/client.py +279 -155
- gemini_webapi-1.17.0/src/gemini_webapi/components/__init__.py +3 -0
- gemini_webapi-1.17.0/src/gemini_webapi/components/gem_mixin.py +288 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/constants.py +40 -36
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/exceptions.py +32 -0
- gemini_webapi-1.17.0/src/gemini_webapi/types/__init__.py +7 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/types/candidate.py +13 -1
- gemini_webapi-1.17.0/src/gemini_webapi/types/gem.py +132 -0
- gemini_webapi-1.17.0/src/gemini_webapi/types/grpc.py +34 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/types/image.py +10 -5
- gemini_webapi-1.17.0/src/gemini_webapi/utils/__init__.py +14 -0
- gemini_webapi-1.17.0/src/gemini_webapi/utils/decorators.py +52 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/utils/get_access_token.py +77 -22
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/utils/load_browser_cookies.py +10 -4
- gemini_webapi-1.17.0/src/gemini_webapi/utils/logger.py +37 -0
- gemini_webapi-1.17.0/src/gemini_webapi/utils/parsing.py +79 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/utils/rotate_1psidts.py +5 -1
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/utils/upload_file.py +27 -6
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi.egg-info/PKG-INFO +197 -92
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi.egg-info/SOURCES.txt +8 -1
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi.egg-info/requires.txt +2 -1
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/tests/test_client_features.py +67 -57
- gemini_webapi-1.17.0/tests/test_gem_mixin.py +88 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/tests/test_save_image.py +15 -9
- gemini_webapi-1.9.0/src/gemini_webapi/__init__.py +0 -4
- gemini_webapi-1.9.0/src/gemini_webapi/types/__init__.py +0 -3
- gemini_webapi-1.9.0/src/gemini_webapi/utils/__init__.py +0 -10
- gemini_webapi-1.9.0/src/gemini_webapi/utils/logger.py +0 -39
- gemini_webapi-1.9.0/tests/test_rotate_cookies.py +0 -26
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/.github/dependabot.yml +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/.vscode/launch.json +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/.vscode/settings.json +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/LICENSE +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/assets/banner.png +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/assets/favicon.png +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/assets/logo.svg +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/setup.cfg +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi/types/modeloutput.py +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi.egg-info/dependency_links.txt +0 -0
- {gemini_webapi-1.9.0 → gemini_webapi-1.17.0}/src/gemini_webapi.egg-info/top_level.txt +0 -0
|
@@ -24,9 +24,9 @@ jobs:
|
|
|
24
24
|
name: Build package
|
|
25
25
|
runs-on: ubuntu-latest
|
|
26
26
|
steps:
|
|
27
|
-
- uses: actions/checkout@
|
|
27
|
+
- uses: actions/checkout@v5
|
|
28
28
|
- name: Set up Python
|
|
29
|
-
uses: actions/setup-python@
|
|
29
|
+
uses: actions/setup-python@v6
|
|
30
30
|
with:
|
|
31
31
|
python-version: '3.x'
|
|
32
32
|
- name: Install dependencies
|
|
@@ -36,7 +36,7 @@ jobs:
|
|
|
36
36
|
- name: Build package
|
|
37
37
|
run: python -m build
|
|
38
38
|
- name: Archive production artifacts
|
|
39
|
-
uses: actions/upload-artifact@v4.6.
|
|
39
|
+
uses: actions/upload-artifact@v4.6.2
|
|
40
40
|
with:
|
|
41
41
|
name: dist
|
|
42
42
|
path: dist
|
|
@@ -52,9 +52,9 @@ jobs:
|
|
|
52
52
|
id-token: write # IMPORTANT: this permission is mandatory for trusted publishing
|
|
53
53
|
steps:
|
|
54
54
|
- name: Retrieve built artifacts
|
|
55
|
-
uses: actions/download-artifact@
|
|
55
|
+
uses: actions/download-artifact@v5.0.0
|
|
56
56
|
with:
|
|
57
57
|
name: dist
|
|
58
58
|
path: dist
|
|
59
59
|
- name: Publish package distributions to PyPI
|
|
60
|
-
uses: pypa/gh-action-pypi-publish@v1.
|
|
60
|
+
uses: pypa/gh-action-pypi-publish@v1.13.0
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: gemini-webapi
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.17.0
|
|
4
4
|
Summary: ✨ An elegant async Python wrapper for Google Gemini web app
|
|
5
5
|
Author: UZQueen
|
|
6
6
|
License: GNU AFFERO GENERAL PUBLIC LICENSE
|
|
@@ -677,8 +677,10 @@ Requires-Python: >=3.10
|
|
|
677
677
|
Description-Content-Type: text/markdown
|
|
678
678
|
License-File: LICENSE
|
|
679
679
|
Requires-Dist: httpx[http2]~=0.28.1
|
|
680
|
-
Requires-Dist: pydantic~=2.10.5
|
|
681
680
|
Requires-Dist: loguru~=0.7.3
|
|
681
|
+
Requires-Dist: orjson~=3.11.1
|
|
682
|
+
Requires-Dist: pydantic~=2.12.2
|
|
683
|
+
Dynamic: license-file
|
|
682
684
|
|
|
683
685
|
<p align="center">
|
|
684
686
|
<img src="https://raw.githubusercontent.com/HanaokaYuzu/Gemini-API/master/assets/banner.png" width="55%" alt="Gemini Banner" align="center">
|
|
@@ -711,9 +713,10 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
711
713
|
## Features
|
|
712
714
|
|
|
713
715
|
- **Persistent Cookies** - Automatically refreshes cookies in background. Optimized for always-on services.
|
|
714
|
-
- **
|
|
716
|
+
- **Image Generation** - Natively supports generating and editing images with natural language.
|
|
717
|
+
- **System Prompt** - Supports customizing model's system prompt with [Gemini Gems](https://gemini.google.com/gems/view).
|
|
715
718
|
- **Extension Support** - Supports generating contents with [Gemini extensions](https://gemini.google.com/extensions) on, like YouTube and Gmail.
|
|
716
|
-
- **Classified Outputs** -
|
|
719
|
+
- **Classified Outputs** - Categorizes texts, thoughts, web images and AI generated images in the response.
|
|
717
720
|
- **Official Flavor** - Provides a simple and elegant interface inspired by [Google Generative AI](https://ai.google.dev/tutorials/python_quickstart)'s official API.
|
|
718
721
|
- **Asynchronous** - Utilizes `asyncio` to run generating tasks and return outputs efficiently.
|
|
719
722
|
|
|
@@ -725,18 +728,22 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
725
728
|
- [Authentication](#authentication)
|
|
726
729
|
- [Usage](#usage)
|
|
727
730
|
- [Initialization](#initialization)
|
|
728
|
-
- [
|
|
729
|
-
- [Generate contents
|
|
730
|
-
- [Generate contents from image](#generate-contents-from-image)
|
|
731
|
+
- [Generate contents](#generate-contents)
|
|
732
|
+
- [Generate contents with files](#generate-contents-with-files)
|
|
731
733
|
- [Conversations across multiple turns](#conversations-across-multiple-turns)
|
|
732
734
|
- [Continue previous conversations](#continue-previous-conversations)
|
|
735
|
+
- [Select language model](#select-language-model)
|
|
736
|
+
- [Apply system prompt with Gemini Gems](#apply-system-prompt-with-gemini-gems)
|
|
737
|
+
- [Manage Custom Gems](#manage-custom-gems)
|
|
738
|
+
- [Create a custom gem](#create-a-custom-gem)
|
|
739
|
+
- [Update an existing gem](#update-an-existing-gem)
|
|
740
|
+
- [Delete a custom gem](#delete-a-custom-gem)
|
|
733
741
|
- [Retrieve model's thought process](#retrieve-models-thought-process)
|
|
734
742
|
- [Retrieve images in response](#retrieve-images-in-response)
|
|
735
|
-
- [Generate
|
|
736
|
-
- [Save images to local files](#save-images-to-local-files)
|
|
743
|
+
- [Generate and edit images](#generate-and-edit-images)
|
|
737
744
|
- [Generate contents with Gemini extensions](#generate-contents-with-gemini-extensions)
|
|
738
745
|
- [Check and switch to other reply candidates](#check-and-switch-to-other-reply-candidates)
|
|
739
|
-
- [
|
|
746
|
+
- [Logging Configuration](#logging-configuration)
|
|
740
747
|
- [References](#references)
|
|
741
748
|
- [Stargazers](#stargazers)
|
|
742
749
|
|
|
@@ -748,13 +755,13 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
748
755
|
|
|
749
756
|
Install/update the package with pip.
|
|
750
757
|
|
|
751
|
-
```
|
|
758
|
+
```sh
|
|
752
759
|
pip install -U gemini_webapi
|
|
753
760
|
```
|
|
754
761
|
|
|
755
762
|
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](https://github.com/borisbabic/browser_cookie3?tab=readme-ov-file#contribute).
|
|
756
763
|
|
|
757
|
-
```
|
|
764
|
+
```sh
|
|
758
765
|
pip install -U browser-cookie3
|
|
759
766
|
```
|
|
760
767
|
|
|
@@ -770,15 +777,17 @@ pip install -U browser-cookie3
|
|
|
770
777
|
|
|
771
778
|
> [!NOTE]
|
|
772
779
|
>
|
|
773
|
-
> If your application is deployed in a containerized environment (e.g. Docker), you may want to persist the cookies with a volume to avoid re-authentication every time the container rebuilds.
|
|
780
|
+
> If your application is deployed in a containerized environment (e.g. Docker), you may want to persist the cookies with a volume to avoid re-authentication every time the container rebuilds. You can set `GEMINI_COOKIE_PATH` environment variable to specify the path where auto-refreshed cookies are stored. Make sure the path is writable by the application.
|
|
774
781
|
>
|
|
775
782
|
> Here's part of a sample `docker-compose.yml` file:
|
|
776
783
|
|
|
777
784
|
```yaml
|
|
778
785
|
services:
|
|
779
|
-
|
|
780
|
-
|
|
781
|
-
|
|
786
|
+
main:
|
|
787
|
+
environment:
|
|
788
|
+
GEMINI_COOKIE_PATH: /tmp/gemini_webapi
|
|
789
|
+
volumes:
|
|
790
|
+
- ./gemini_cookies:/tmp/gemini_webapi
|
|
782
791
|
```
|
|
783
792
|
|
|
784
793
|
> [!NOTE]
|
|
@@ -816,44 +825,9 @@ asyncio.run(main())
|
|
|
816
825
|
>
|
|
817
826
|
> `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 an always-on service like chatbot, it's recommended to set `auto_close` to `True` combined with reasonable seconds of `close_delay` for better resource management.
|
|
818
827
|
|
|
819
|
-
###
|
|
820
|
-
|
|
821
|
-
You can specify which language model to use by passing `model` argument to `GeminiClient.generate_content` or `GeminiClient.start_chat`. The default value is `unspecified`.
|
|
822
|
-
|
|
823
|
-
Currently available models (as of Feb 5, 2025):
|
|
824
|
-
|
|
825
|
-
- `unspecified` - Default model (same as `gemini-2.0-flash` if account does NOT have Gemini Advanced subscription)
|
|
826
|
-
- `gemini-2.0-flash` - Gemini 2.0 Flash
|
|
827
|
-
- `gemini-2.0-flash-thinking` - Gemini 2.0 Flash Thinking Experimental
|
|
828
|
-
- `gemini-2.0-flash-thinking-with-apps` - Gemini 2.0 Flash Thinking Experimental with apps
|
|
829
|
-
- `gemini-1.5-flash` - Gemini 1.5 Flash
|
|
830
|
-
|
|
831
|
-
Models pending update (may not work as expected):
|
|
828
|
+
### Generate contents
|
|
832
829
|
|
|
833
|
-
- `
|
|
834
|
-
- `gemini-1.5-pro` - Gemini 1.5 Pro **(requires Gemini Advanced account)**
|
|
835
|
-
- `gemini-1.5-pro-research` - Gemini 1.5 Pro with Deep Research **(requires Gemini Advanced account)**
|
|
836
|
-
|
|
837
|
-
```python
|
|
838
|
-
from gemini_webapi.constants import Model
|
|
839
|
-
|
|
840
|
-
async def main():
|
|
841
|
-
response1 = await client.generate_content(
|
|
842
|
-
"What's you language model version? Reply version number only.",
|
|
843
|
-
model=Model.G_2_0_FLASH,
|
|
844
|
-
)
|
|
845
|
-
print(f"Model version ({Model.G_2_0_FLASH.model_name}): {response1.text}")
|
|
846
|
-
|
|
847
|
-
chat = client.start_chat(model="gemini-2.0-flash-thinking")
|
|
848
|
-
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
849
|
-
print(f"Model version (gemini-2.0-flash-thinking): {response2.text}")
|
|
850
|
-
|
|
851
|
-
asyncio.run(main())
|
|
852
|
-
```
|
|
853
|
-
|
|
854
|
-
### Generate contents from text
|
|
855
|
-
|
|
856
|
-
Ask a one-turn quick question by calling `GeminiClient.generate_content`.
|
|
830
|
+
Ask a single-turn question by calling `GeminiClient.generate_content`, which returns a `gemini_webapi.ModelOutput` object containing the generated text, images, thoughts, and conversation metadata.
|
|
857
831
|
|
|
858
832
|
```python
|
|
859
833
|
async def main():
|
|
@@ -867,15 +841,15 @@ asyncio.run(main())
|
|
|
867
841
|
>
|
|
868
842
|
> Simply use `print(response)` to get the same output if you just want to see the response text
|
|
869
843
|
|
|
870
|
-
### Generate contents
|
|
844
|
+
### Generate contents with files
|
|
871
845
|
|
|
872
|
-
Gemini supports
|
|
846
|
+
Gemini supports file input, including images and documents. Optionally, you can pass files as a list of paths in `str` or `pathlib.Path` to `GeminiClient.generate_content` together with text prompt.
|
|
873
847
|
|
|
874
848
|
```python
|
|
875
849
|
async def main():
|
|
876
850
|
response = await client.generate_content(
|
|
877
|
-
"
|
|
878
|
-
|
|
851
|
+
"Introduce the contents of these two files. Is there any connection between them?",
|
|
852
|
+
files=["assets/sample.pdf", Path("assets/banner.png")],
|
|
879
853
|
)
|
|
880
854
|
print(response.text)
|
|
881
855
|
|
|
@@ -884,14 +858,20 @@ asyncio.run(main())
|
|
|
884
858
|
|
|
885
859
|
### Conversations across multiple turns
|
|
886
860
|
|
|
887
|
-
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.
|
|
861
|
+
If you want to keep conversation continuous, please use `GeminiClient.start_chat` to create a `gemini_webapi.ChatSession` object and send messages through it. The conversation history will be automatically handled and get updated after each turn.
|
|
888
862
|
|
|
889
863
|
```python
|
|
890
864
|
async def main():
|
|
891
865
|
chat = client.start_chat()
|
|
892
|
-
response1 = await chat.send_message(
|
|
893
|
-
|
|
894
|
-
|
|
866
|
+
response1 = await chat.send_message(
|
|
867
|
+
"Introduce the contents of these two files. Is there any connection between them?",
|
|
868
|
+
files=["assets/sample.pdf", Path("assets/banner.png")],
|
|
869
|
+
)
|
|
870
|
+
print(response1.text)
|
|
871
|
+
response2 = await chat.send_message(
|
|
872
|
+
"Use image generation tool to modify the banner with another font and design."
|
|
873
|
+
)
|
|
874
|
+
print(response2.text, response2.images, sep="\n\n----------------------------------\n\n")
|
|
895
875
|
|
|
896
876
|
asyncio.run(main())
|
|
897
877
|
```
|
|
@@ -921,6 +901,139 @@ async def main():
|
|
|
921
901
|
asyncio.run(main())
|
|
922
902
|
```
|
|
923
903
|
|
|
904
|
+
### Select language model
|
|
905
|
+
|
|
906
|
+
You can specify which language model to use by passing `model` argument to `GeminiClient.generate_content` or `GeminiClient.start_chat`. The default value is `unspecified`.
|
|
907
|
+
|
|
908
|
+
Currently available models (as of November 20, 2025):
|
|
909
|
+
|
|
910
|
+
- `unspecified` - Default model
|
|
911
|
+
- `gemini-3.0-pro` - Gemini 3.0 Pro
|
|
912
|
+
- `gemini-2.5-pro` - Gemini 2.5 Pro
|
|
913
|
+
- `gemini-2.5-flash` - Gemini 2.5 Flash
|
|
914
|
+
|
|
915
|
+
```python
|
|
916
|
+
from gemini_webapi.constants import Model
|
|
917
|
+
|
|
918
|
+
async def main():
|
|
919
|
+
response1 = await client.generate_content(
|
|
920
|
+
"What's you language model version? Reply version number only.",
|
|
921
|
+
model=Model.G_2_5_FLASH,
|
|
922
|
+
)
|
|
923
|
+
print(f"Model version ({Model.G_2_5_FLASH.model_name}): {response1.text}")
|
|
924
|
+
|
|
925
|
+
chat = client.start_chat(model="gemini-2.5-pro")
|
|
926
|
+
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
927
|
+
print(f"Model version (gemini-2.5-pro): {response2.text}")
|
|
928
|
+
|
|
929
|
+
asyncio.run(main())
|
|
930
|
+
```
|
|
931
|
+
|
|
932
|
+
### Apply system prompt with Gemini Gems
|
|
933
|
+
|
|
934
|
+
System prompt can be applied to conversations via [Gemini Gems](https://gemini.google.com/gems/view). To use a gem, you can pass `gem` argument to `GeminiClient.generate_content` or `GeminiClient.start_chat`. `gem` can be either a string of gem id or a `gemini_webapi.Gem` object. Only one gem can be applied to a single conversation.
|
|
935
|
+
|
|
936
|
+
> [!TIP]
|
|
937
|
+
>
|
|
938
|
+
> There are some system predefined gems that by default are not shown to users (and therefore may not work properly). Use `client.fetch_gems(include_hidden=True)` to include them in the fetch result.
|
|
939
|
+
|
|
940
|
+
```python
|
|
941
|
+
async def main():
|
|
942
|
+
# Fetch all gems for the current account, including both predefined and user-created ones
|
|
943
|
+
await client.fetch_gems(include_hidden=False)
|
|
944
|
+
|
|
945
|
+
# Once fetched, gems will be cached in `GeminiClient.gems`
|
|
946
|
+
gems = client.gems
|
|
947
|
+
|
|
948
|
+
# Get the gem you want to use
|
|
949
|
+
system_gems = gems.filter(predefined=True)
|
|
950
|
+
coding_partner = system_gems.get(id="coding-partner")
|
|
951
|
+
|
|
952
|
+
response1 = await client.generate_content(
|
|
953
|
+
"what's your system prompt?",
|
|
954
|
+
model=Model.G_2_5_FLASH,
|
|
955
|
+
gem=coding_partner,
|
|
956
|
+
)
|
|
957
|
+
print(response1.text)
|
|
958
|
+
|
|
959
|
+
# Another example with a user-created custom gem
|
|
960
|
+
# Gem ids are consistent strings. Store them somewhere to avoid fetching gems every time
|
|
961
|
+
your_gem = gems.get(name="Your Gem Name")
|
|
962
|
+
your_gem_id = your_gem.id
|
|
963
|
+
chat = client.start_chat(gem=your_gem_id)
|
|
964
|
+
response2 = await chat.send_message("what's your system prompt?")
|
|
965
|
+
print(response2)
|
|
966
|
+
```
|
|
967
|
+
|
|
968
|
+
### Manage Custom Gems
|
|
969
|
+
|
|
970
|
+
You can create, update, and delete your custom gems programmatically with the API. Note that predefined system gems cannot be modified or deleted.
|
|
971
|
+
|
|
972
|
+
#### Create a custom gem
|
|
973
|
+
|
|
974
|
+
Create a new custom gem with a name, system prompt (instructions), and optional description:
|
|
975
|
+
|
|
976
|
+
```python
|
|
977
|
+
async def main():
|
|
978
|
+
# Create a new custom gem
|
|
979
|
+
new_gem = await client.create_gem(
|
|
980
|
+
name="Python Tutor",
|
|
981
|
+
prompt="You are a helpful Python programming tutor.",
|
|
982
|
+
description="A specialized gem for Python programming"
|
|
983
|
+
)
|
|
984
|
+
|
|
985
|
+
print(f"Custom gem created: {new_gem}")
|
|
986
|
+
|
|
987
|
+
# Use the newly created gem in a conversation
|
|
988
|
+
response = await client.generate_content(
|
|
989
|
+
"Explain how list comprehensions work in Python",
|
|
990
|
+
gem=new_gem
|
|
991
|
+
)
|
|
992
|
+
print(response.text)
|
|
993
|
+
|
|
994
|
+
asyncio.run(main())
|
|
995
|
+
```
|
|
996
|
+
|
|
997
|
+
#### Update an existing gem
|
|
998
|
+
|
|
999
|
+
> [!NOTE]
|
|
1000
|
+
>
|
|
1001
|
+
> When updating a gem, you must provide all parameters (name, prompt, description) even if you only want to change one of them.
|
|
1002
|
+
|
|
1003
|
+
```python
|
|
1004
|
+
async def main():
|
|
1005
|
+
# Get a custom gem (assuming you have one named "Python Tutor")
|
|
1006
|
+
await client.fetch_gems()
|
|
1007
|
+
python_tutor = client.gems.get(name="Python Tutor")
|
|
1008
|
+
|
|
1009
|
+
# Update the gem with new instructions
|
|
1010
|
+
updated_gem = await client.update_gem(
|
|
1011
|
+
gem=python_tutor, # Can also pass gem ID string
|
|
1012
|
+
name="Advanced Python Tutor",
|
|
1013
|
+
prompt="You are an expert Python programming tutor.",
|
|
1014
|
+
description="An advanced Python programming assistant"
|
|
1015
|
+
)
|
|
1016
|
+
|
|
1017
|
+
print(f"Custom gem updated: {updated_gem}")
|
|
1018
|
+
|
|
1019
|
+
asyncio.run(main())
|
|
1020
|
+
```
|
|
1021
|
+
|
|
1022
|
+
#### Delete a custom gem
|
|
1023
|
+
|
|
1024
|
+
```python
|
|
1025
|
+
async def main():
|
|
1026
|
+
# Get the gem to delete
|
|
1027
|
+
await client.fetch_gems()
|
|
1028
|
+
gem_to_delete = client.gems.get(name="Advanced Python Tutor")
|
|
1029
|
+
|
|
1030
|
+
# Delete the gem
|
|
1031
|
+
await client.delete_gem(gem_to_delete) # Can also pass gem ID string
|
|
1032
|
+
print(f"Custom gem deleted: {gem_to_delete.name}")
|
|
1033
|
+
|
|
1034
|
+
asyncio.run(main())
|
|
1035
|
+
```
|
|
1036
|
+
|
|
924
1037
|
### Retrieve model's thought process
|
|
925
1038
|
|
|
926
1039
|
When using models with thinking capabilities, the model's thought process will be populated in `ModelOutput.thoughts`.
|
|
@@ -928,7 +1041,7 @@ When using models with thinking capabilities, the model's thought process will b
|
|
|
928
1041
|
```python
|
|
929
1042
|
async def main():
|
|
930
1043
|
response = await client.generate_content(
|
|
931
|
-
"What's 1+1?", model="gemini-2.
|
|
1044
|
+
"What's 1+1?", model="gemini-2.5-pro"
|
|
932
1045
|
)
|
|
933
1046
|
print(response.thoughts)
|
|
934
1047
|
print(response.text)
|
|
@@ -938,7 +1051,7 @@ asyncio.run(main())
|
|
|
938
1051
|
|
|
939
1052
|
### Retrieve images in response
|
|
940
1053
|
|
|
941
|
-
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 `
|
|
1054
|
+
Images in the API's output are stored as a list of `gemini_webapi.Image` objects. You can access the image title, URL, and description by calling `Image.title`, `Image.url` and `Image.alt` respectively.
|
|
942
1055
|
|
|
943
1056
|
```python
|
|
944
1057
|
async def main():
|
|
@@ -949,24 +1062,27 @@ async def main():
|
|
|
949
1062
|
asyncio.run(main())
|
|
950
1063
|
```
|
|
951
1064
|
|
|
952
|
-
### Generate
|
|
1065
|
+
### Generate and edit images
|
|
953
1066
|
|
|
954
|
-
|
|
1067
|
+
You can ask Gemini to generate and edit images with Nano Banana, Google's latest image model, simply by natural language.
|
|
955
1068
|
|
|
956
1069
|
> [!IMPORTANT]
|
|
957
1070
|
>
|
|
958
|
-
> 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](https://support.google.com/gemini/answer/14286560) (as of
|
|
1071
|
+
> 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](https://support.google.com/gemini/answer/14286560) (as of Sep 10, 2025):
|
|
959
1072
|
>
|
|
960
|
-
> > 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**.
|
|
961
|
-
> >
|
|
962
1073
|
> > This feature’s availability in any specific Gemini app is also limited to the supported languages and countries of that app.
|
|
963
1074
|
> >
|
|
964
1075
|
> > For now, this feature isn’t available to users under 18.
|
|
1076
|
+
> >
|
|
1077
|
+
> > To use this feature, you must be signed in to Gemini Apps.
|
|
1078
|
+
|
|
1079
|
+
You can save images returned from Gemini to local 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`.
|
|
965
1080
|
|
|
966
1081
|
```python
|
|
967
1082
|
async def main():
|
|
968
1083
|
response = await client.generate_content("Generate some pictures of cats")
|
|
969
|
-
for image in response.images:
|
|
1084
|
+
for i, image in enumerate(response.images):
|
|
1085
|
+
await image.save(path="temp/", filename=f"cat_{i}.png", verbose=True)
|
|
970
1086
|
print(image, "\n\n----------------------------------\n")
|
|
971
1087
|
|
|
972
1088
|
asyncio.run(main())
|
|
@@ -976,32 +1092,17 @@ asyncio.run(main())
|
|
|
976
1092
|
>
|
|
977
1093
|
> 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.
|
|
978
1094
|
|
|
979
|
-
### Save images to local files
|
|
980
|
-
|
|
981
|
-
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`.
|
|
982
|
-
|
|
983
|
-
```python
|
|
984
|
-
async def main():
|
|
985
|
-
response = await client.generate_content("Generate some pictures of cats")
|
|
986
|
-
for i, image in enumerate(response.images):
|
|
987
|
-
await image.save(path="temp/", filename=f"cat_{i}.png", verbose=True)
|
|
988
|
-
|
|
989
|
-
asyncio.run(main())
|
|
990
|
-
```
|
|
991
|
-
|
|
992
1095
|
### Generate contents with Gemini extensions
|
|
993
1096
|
|
|
994
1097
|
> [!IMPORTANT]
|
|
995
1098
|
>
|
|
996
|
-
> To access Gemini extensions in API, you must activate them on the [Gemini website](https://gemini.google.com/extensions) first. Same as image generation, Google also has limitations on the availability of Gemini extensions. Here's a summary copied from [official documentation](https://support.google.com/gemini/answer/13695044) (as of
|
|
1099
|
+
> To access Gemini extensions in API, you must activate them on the [Gemini website](https://gemini.google.com/extensions) first. Same as image generation, Google also has limitations on the availability of Gemini extensions. Here's a summary copied from [official documentation](https://support.google.com/gemini/answer/13695044) (as of March 19th, 2025):
|
|
997
1100
|
>
|
|
998
|
-
> > To
|
|
999
|
-
> >
|
|
1000
|
-
> > 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.
|
|
1101
|
+
> > To connect apps to Gemini, you must have Gemini Apps Activity on.
|
|
1001
1102
|
> >
|
|
1002
|
-
> >
|
|
1103
|
+
> > To use this feature, you must be signed in to Gemini Apps.
|
|
1003
1104
|
> >
|
|
1004
|
-
> > Important:
|
|
1105
|
+
> > Important: If you’re under 18, Google Workspace and Maps apps currently only work with English prompts in Gemini.
|
|
1005
1106
|
|
|
1006
1107
|
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.
|
|
1007
1108
|
|
|
@@ -1022,7 +1123,7 @@ asyncio.run(main())
|
|
|
1022
1123
|
|
|
1023
1124
|
### Check and switch to other reply candidates
|
|
1024
1125
|
|
|
1025
|
-
A response from Gemini
|
|
1126
|
+
A response from Gemini sometimes 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.
|
|
1026
1127
|
|
|
1027
1128
|
```python
|
|
1028
1129
|
async def main():
|
|
@@ -1043,9 +1144,9 @@ async def main():
|
|
|
1043
1144
|
asyncio.run(main())
|
|
1044
1145
|
```
|
|
1045
1146
|
|
|
1046
|
-
###
|
|
1147
|
+
### Logging Configuration
|
|
1047
1148
|
|
|
1048
|
-
|
|
1149
|
+
This package uses [loguru](https://loguru.readthedocs.io/en/stable/) for logging, and exposes a function `set_log_level` to control log level. You can set log level to one of the following values: `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL`. The default value is `INFO`.
|
|
1049
1150
|
|
|
1050
1151
|
```python
|
|
1051
1152
|
from gemini_webapi import set_log_level
|
|
@@ -1053,6 +1154,10 @@ from gemini_webapi import set_log_level
|
|
|
1053
1154
|
set_log_level("DEBUG")
|
|
1054
1155
|
```
|
|
1055
1156
|
|
|
1157
|
+
> [!NOTE]
|
|
1158
|
+
>
|
|
1159
|
+
> Calling `set_log_level` for the first time will **globally** remove all existing loguru handlers. You may want to configure logging directly with loguru to avoid this issue and have more advanced control over logging behaviors.
|
|
1160
|
+
|
|
1056
1161
|
## References
|
|
1057
1162
|
|
|
1058
1163
|
[Google AI Studio](https://ai.google.dev/tutorials/ai-studio_quickstart)
|