gemini-webapi 1.8.4__tar.gz → 1.9.1__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.8.4 → gemini_webapi-1.9.1}/PKG-INFO +55 -33
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/README.md +52 -31
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/client.py +17 -8
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/constants.py +25 -10
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/types/candidate.py +3 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/types/modeloutput.py +4 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi.egg-info/PKG-INFO +55 -33
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/tests/test_client_features.py +21 -2
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/.github/dependabot.yml +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/.github/workflows/github-release.yml +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/.github/workflows/pypi-publish.yml +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/.gitignore +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/.vscode/launch.json +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/.vscode/settings.json +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/LICENSE +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/assets/banner.png +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/assets/favicon.png +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/assets/logo.svg +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/pyproject.toml +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/setup.cfg +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/__init__.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/exceptions.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/types/__init__.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/types/image.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/utils/__init__.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/utils/get_access_token.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/utils/load_browser_cookies.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/utils/logger.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/utils/rotate_1psidts.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi/utils/upload_file.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi.egg-info/SOURCES.txt +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi.egg-info/dependency_links.txt +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi.egg-info/requires.txt +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/src/gemini_webapi.egg-info/top_level.txt +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/tests/test_rotate_cookies.py +0 -0
- {gemini_webapi-1.8.4 → gemini_webapi-1.9.1}/tests/test_save_image.py +0 -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.9.1
|
|
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
|
|
@@ -679,6 +679,7 @@ License-File: LICENSE
|
|
|
679
679
|
Requires-Dist: httpx[http2]~=0.28.1
|
|
680
680
|
Requires-Dist: pydantic~=2.10.5
|
|
681
681
|
Requires-Dist: loguru~=0.7.3
|
|
682
|
+
Dynamic: license-file
|
|
682
683
|
|
|
683
684
|
<p align="center">
|
|
684
685
|
<img src="https://raw.githubusercontent.com/HanaokaYuzu/Gemini-API/master/assets/banner.png" width="55%" alt="Gemini Banner" align="center">
|
|
@@ -725,14 +726,15 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
725
726
|
- [Authentication](#authentication)
|
|
726
727
|
- [Usage](#usage)
|
|
727
728
|
- [Initialization](#initialization)
|
|
729
|
+
- [Select language model](#select-language-model)
|
|
728
730
|
- [Generate contents from text](#generate-contents-from-text)
|
|
729
731
|
- [Generate contents from image](#generate-contents-from-image)
|
|
730
732
|
- [Conversations across multiple turns](#conversations-across-multiple-turns)
|
|
731
733
|
- [Continue previous conversations](#continue-previous-conversations)
|
|
734
|
+
- [Retrieve model's thought process](#retrieve-models-thought-process)
|
|
732
735
|
- [Retrieve images in response](#retrieve-images-in-response)
|
|
733
736
|
- [Generate images with ImageFx](#generate-images-with-imagefx)
|
|
734
737
|
- [Save images to local files](#save-images-to-local-files)
|
|
735
|
-
- [Specify language model version](#specify-language-model-version)
|
|
736
738
|
- [Generate contents with Gemini extensions](#generate-contents-with-gemini-extensions)
|
|
737
739
|
- [Check and switch to other reply candidates](#check-and-switch-to-other-reply-candidates)
|
|
738
740
|
- [Control log level](#control-log-level)
|
|
@@ -815,6 +817,41 @@ asyncio.run(main())
|
|
|
815
817
|
>
|
|
816
818
|
> `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.
|
|
817
819
|
|
|
820
|
+
### Select language model
|
|
821
|
+
|
|
822
|
+
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`.
|
|
823
|
+
|
|
824
|
+
Currently available models (as of Feb 5, 2025):
|
|
825
|
+
|
|
826
|
+
- `unspecified` - Default model (same as `gemini-2.0-flash` if account does NOT have Gemini Advanced subscription)
|
|
827
|
+
- `gemini-2.0-flash` - Gemini 2.0 Flash
|
|
828
|
+
- `gemini-2.0-flash-thinking` - Gemini 2.0 Flash Thinking Experimental
|
|
829
|
+
- `gemini-2.0-flash-thinking-with-apps` - Gemini 2.0 Flash Thinking Experimental with apps
|
|
830
|
+
- `gemini-1.5-flash` - Gemini 1.5 Flash
|
|
831
|
+
|
|
832
|
+
Models pending update (may not work as expected):
|
|
833
|
+
|
|
834
|
+
- `gemini-2.0-exp-advanced` - Gemini 2.0 Experimental Advanced **(requires Gemini Advanced account)**
|
|
835
|
+
- `gemini-1.5-pro` - Gemini 1.5 Pro **(requires Gemini Advanced account)**
|
|
836
|
+
- `gemini-1.5-pro-research` - Gemini 1.5 Pro with Deep Research **(requires Gemini Advanced account)**
|
|
837
|
+
|
|
838
|
+
```python
|
|
839
|
+
from gemini_webapi.constants import Model
|
|
840
|
+
|
|
841
|
+
async def main():
|
|
842
|
+
response1 = await client.generate_content(
|
|
843
|
+
"What's you language model version? Reply version number only.",
|
|
844
|
+
model=Model.G_2_0_FLASH,
|
|
845
|
+
)
|
|
846
|
+
print(f"Model version ({Model.G_2_0_FLASH.model_name}): {response1.text}")
|
|
847
|
+
|
|
848
|
+
chat = client.start_chat(model="gemini-2.0-flash-thinking")
|
|
849
|
+
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
850
|
+
print(f"Model version (gemini-2.0-flash-thinking): {response2.text}")
|
|
851
|
+
|
|
852
|
+
asyncio.run(main())
|
|
853
|
+
```
|
|
854
|
+
|
|
818
855
|
### Generate contents from text
|
|
819
856
|
|
|
820
857
|
Ask a one-turn quick question by calling `GeminiClient.generate_content`.
|
|
@@ -885,6 +922,21 @@ async def main():
|
|
|
885
922
|
asyncio.run(main())
|
|
886
923
|
```
|
|
887
924
|
|
|
925
|
+
### Retrieve model's thought process
|
|
926
|
+
|
|
927
|
+
When using models with thinking capabilities, the model's thought process will be populated in `ModelOutput.thoughts`.
|
|
928
|
+
|
|
929
|
+
```python
|
|
930
|
+
async def main():
|
|
931
|
+
response = await client.generate_content(
|
|
932
|
+
"What's 1+1?", model="gemini-2.0-flash-thinking"
|
|
933
|
+
)
|
|
934
|
+
print(response.thoughts)
|
|
935
|
+
print(response.text)
|
|
936
|
+
|
|
937
|
+
asyncio.run(main())
|
|
938
|
+
```
|
|
939
|
+
|
|
888
940
|
### Retrieve images in response
|
|
889
941
|
|
|
890
942
|
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.
|
|
@@ -938,36 +990,6 @@ async def main():
|
|
|
938
990
|
asyncio.run(main())
|
|
939
991
|
```
|
|
940
992
|
|
|
941
|
-
### Specify language model version
|
|
942
|
-
|
|
943
|
-
You can choose a specified language model version by passing `model` argument to `GeminiClient.generate_content` or `GeminiClient.start_chat`. The default value is `unspecified`.
|
|
944
|
-
|
|
945
|
-
Currently available models (as of Feb 1, 2025):
|
|
946
|
-
|
|
947
|
-
- `unspecified` - Default model (Gemini 2.0 Flash if account does NOT have Gemini Advanced subscription)
|
|
948
|
-
- `gemini-1.5-flash` - Gemini 1.5 Flash
|
|
949
|
-
- `gemini-1.5-pro` - Gemini 1.5 Pro **(requires Gemini Advanced account)**
|
|
950
|
-
- `gemini-1.5-pro-research` - Gemini 1.5 Pro with Deep Research **(requires Gemini Advanced account)**
|
|
951
|
-
- `gemini-2.0-flash-exp` - Gemini 2.0 Flash Experimental
|
|
952
|
-
- `gemini-2.0-exp-advanced` - Gemini 2.0 Experimental Advanced **(requires Gemini Advanced account)**
|
|
953
|
-
|
|
954
|
-
```python
|
|
955
|
-
from gemini_webapi.constants import Model
|
|
956
|
-
|
|
957
|
-
async def main():
|
|
958
|
-
response1 = await client.generate_content(
|
|
959
|
-
"What's you language model version? Reply version number only.",
|
|
960
|
-
model="gemini-1.5-flash",
|
|
961
|
-
)
|
|
962
|
-
print(f"Model version (gemini-1.5-flash): {response1.text}")
|
|
963
|
-
|
|
964
|
-
chat = client.start_chat(model=Model.G_2_0_FLASH_EXP)
|
|
965
|
-
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
966
|
-
print(f"Model version ({Model.G_2_0_FLASH_EXP.model_name}): {response2.text}")
|
|
967
|
-
|
|
968
|
-
asyncio.run(main())
|
|
969
|
-
```
|
|
970
|
-
|
|
971
993
|
### Generate contents with Gemini extensions
|
|
972
994
|
|
|
973
995
|
> [!IMPORTANT]
|
|
@@ -43,14 +43,15 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
43
43
|
- [Authentication](#authentication)
|
|
44
44
|
- [Usage](#usage)
|
|
45
45
|
- [Initialization](#initialization)
|
|
46
|
+
- [Select language model](#select-language-model)
|
|
46
47
|
- [Generate contents from text](#generate-contents-from-text)
|
|
47
48
|
- [Generate contents from image](#generate-contents-from-image)
|
|
48
49
|
- [Conversations across multiple turns](#conversations-across-multiple-turns)
|
|
49
50
|
- [Continue previous conversations](#continue-previous-conversations)
|
|
51
|
+
- [Retrieve model's thought process](#retrieve-models-thought-process)
|
|
50
52
|
- [Retrieve images in response](#retrieve-images-in-response)
|
|
51
53
|
- [Generate images with ImageFx](#generate-images-with-imagefx)
|
|
52
54
|
- [Save images to local files](#save-images-to-local-files)
|
|
53
|
-
- [Specify language model version](#specify-language-model-version)
|
|
54
55
|
- [Generate contents with Gemini extensions](#generate-contents-with-gemini-extensions)
|
|
55
56
|
- [Check and switch to other reply candidates](#check-and-switch-to-other-reply-candidates)
|
|
56
57
|
- [Control log level](#control-log-level)
|
|
@@ -133,6 +134,41 @@ asyncio.run(main())
|
|
|
133
134
|
>
|
|
134
135
|
> `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.
|
|
135
136
|
|
|
137
|
+
### Select language model
|
|
138
|
+
|
|
139
|
+
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`.
|
|
140
|
+
|
|
141
|
+
Currently available models (as of Feb 5, 2025):
|
|
142
|
+
|
|
143
|
+
- `unspecified` - Default model (same as `gemini-2.0-flash` if account does NOT have Gemini Advanced subscription)
|
|
144
|
+
- `gemini-2.0-flash` - Gemini 2.0 Flash
|
|
145
|
+
- `gemini-2.0-flash-thinking` - Gemini 2.0 Flash Thinking Experimental
|
|
146
|
+
- `gemini-2.0-flash-thinking-with-apps` - Gemini 2.0 Flash Thinking Experimental with apps
|
|
147
|
+
- `gemini-1.5-flash` - Gemini 1.5 Flash
|
|
148
|
+
|
|
149
|
+
Models pending update (may not work as expected):
|
|
150
|
+
|
|
151
|
+
- `gemini-2.0-exp-advanced` - Gemini 2.0 Experimental Advanced **(requires Gemini Advanced account)**
|
|
152
|
+
- `gemini-1.5-pro` - Gemini 1.5 Pro **(requires Gemini Advanced account)**
|
|
153
|
+
- `gemini-1.5-pro-research` - Gemini 1.5 Pro with Deep Research **(requires Gemini Advanced account)**
|
|
154
|
+
|
|
155
|
+
```python
|
|
156
|
+
from gemini_webapi.constants import Model
|
|
157
|
+
|
|
158
|
+
async def main():
|
|
159
|
+
response1 = await client.generate_content(
|
|
160
|
+
"What's you language model version? Reply version number only.",
|
|
161
|
+
model=Model.G_2_0_FLASH,
|
|
162
|
+
)
|
|
163
|
+
print(f"Model version ({Model.G_2_0_FLASH.model_name}): {response1.text}")
|
|
164
|
+
|
|
165
|
+
chat = client.start_chat(model="gemini-2.0-flash-thinking")
|
|
166
|
+
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
167
|
+
print(f"Model version (gemini-2.0-flash-thinking): {response2.text}")
|
|
168
|
+
|
|
169
|
+
asyncio.run(main())
|
|
170
|
+
```
|
|
171
|
+
|
|
136
172
|
### Generate contents from text
|
|
137
173
|
|
|
138
174
|
Ask a one-turn quick question by calling `GeminiClient.generate_content`.
|
|
@@ -203,6 +239,21 @@ async def main():
|
|
|
203
239
|
asyncio.run(main())
|
|
204
240
|
```
|
|
205
241
|
|
|
242
|
+
### Retrieve model's thought process
|
|
243
|
+
|
|
244
|
+
When using models with thinking capabilities, the model's thought process will be populated in `ModelOutput.thoughts`.
|
|
245
|
+
|
|
246
|
+
```python
|
|
247
|
+
async def main():
|
|
248
|
+
response = await client.generate_content(
|
|
249
|
+
"What's 1+1?", model="gemini-2.0-flash-thinking"
|
|
250
|
+
)
|
|
251
|
+
print(response.thoughts)
|
|
252
|
+
print(response.text)
|
|
253
|
+
|
|
254
|
+
asyncio.run(main())
|
|
255
|
+
```
|
|
256
|
+
|
|
206
257
|
### Retrieve images in response
|
|
207
258
|
|
|
208
259
|
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.
|
|
@@ -256,36 +307,6 @@ async def main():
|
|
|
256
307
|
asyncio.run(main())
|
|
257
308
|
```
|
|
258
309
|
|
|
259
|
-
### Specify language model version
|
|
260
|
-
|
|
261
|
-
You can choose a specified language model version by passing `model` argument to `GeminiClient.generate_content` or `GeminiClient.start_chat`. The default value is `unspecified`.
|
|
262
|
-
|
|
263
|
-
Currently available models (as of Feb 1, 2025):
|
|
264
|
-
|
|
265
|
-
- `unspecified` - Default model (Gemini 2.0 Flash if account does NOT have Gemini Advanced subscription)
|
|
266
|
-
- `gemini-1.5-flash` - Gemini 1.5 Flash
|
|
267
|
-
- `gemini-1.5-pro` - Gemini 1.5 Pro **(requires Gemini Advanced account)**
|
|
268
|
-
- `gemini-1.5-pro-research` - Gemini 1.5 Pro with Deep Research **(requires Gemini Advanced account)**
|
|
269
|
-
- `gemini-2.0-flash-exp` - Gemini 2.0 Flash Experimental
|
|
270
|
-
- `gemini-2.0-exp-advanced` - Gemini 2.0 Experimental Advanced **(requires Gemini Advanced account)**
|
|
271
|
-
|
|
272
|
-
```python
|
|
273
|
-
from gemini_webapi.constants import Model
|
|
274
|
-
|
|
275
|
-
async def main():
|
|
276
|
-
response1 = await client.generate_content(
|
|
277
|
-
"What's you language model version? Reply version number only.",
|
|
278
|
-
model="gemini-1.5-flash",
|
|
279
|
-
)
|
|
280
|
-
print(f"Model version (gemini-1.5-flash): {response1.text}")
|
|
281
|
-
|
|
282
|
-
chat = client.start_chat(model=Model.G_2_0_FLASH_EXP)
|
|
283
|
-
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
284
|
-
print(f"Model version ({Model.G_2_0_FLASH_EXP.model_name}): {response2.text}")
|
|
285
|
-
|
|
286
|
-
asyncio.run(main())
|
|
287
|
-
```
|
|
288
|
-
|
|
289
310
|
### Generate contents with Gemini extensions
|
|
290
311
|
|
|
291
312
|
> [!IMPORTANT]
|
|
@@ -361,14 +361,17 @@ class GeminiClient:
|
|
|
361
361
|
try:
|
|
362
362
|
response_json = json.loads(response.text.split("\n")[2])
|
|
363
363
|
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
364
|
+
body = None
|
|
365
|
+
for part in response_json:
|
|
366
|
+
try:
|
|
367
|
+
main_part = json.loads(part[2])
|
|
368
|
+
if main_part[4]:
|
|
369
|
+
body = main_part
|
|
370
|
+
break
|
|
371
|
+
except (IndexError, TypeError, ValueError):
|
|
372
|
+
continue
|
|
373
|
+
|
|
374
|
+
if not body:
|
|
372
375
|
raise Exception
|
|
373
376
|
except Exception:
|
|
374
377
|
await self.close()
|
|
@@ -386,6 +389,11 @@ class GeminiClient:
|
|
|
386
389
|
):
|
|
387
390
|
text = candidate[22] and candidate[22][0] or text
|
|
388
391
|
|
|
392
|
+
try:
|
|
393
|
+
thoughts = candidate[37][0][0]
|
|
394
|
+
except (TypeError, IndexError):
|
|
395
|
+
thoughts = None
|
|
396
|
+
|
|
389
397
|
web_images = (
|
|
390
398
|
candidate[12]
|
|
391
399
|
and candidate[12][1]
|
|
@@ -435,6 +443,7 @@ class GeminiClient:
|
|
|
435
443
|
Candidate(
|
|
436
444
|
rcid=candidate[0],
|
|
437
445
|
text=text,
|
|
446
|
+
thoughts=thoughts,
|
|
438
447
|
web_images=web_images,
|
|
439
448
|
generated_images=generated_images,
|
|
440
449
|
)
|
|
@@ -25,6 +25,31 @@ class Headers(Enum):
|
|
|
25
25
|
|
|
26
26
|
class Model(Enum):
|
|
27
27
|
UNSPECIFIED = ("unspecified", {}, False)
|
|
28
|
+
G_2_0_FLASH = (
|
|
29
|
+
"gemini-2.0-flash",
|
|
30
|
+
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"f299729663a2343f"]'},
|
|
31
|
+
False,
|
|
32
|
+
)
|
|
33
|
+
G_2_0_FLASH_EXP = (
|
|
34
|
+
"gemini-2.0-flash-exp",
|
|
35
|
+
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"f299729663a2343f"]'},
|
|
36
|
+
False,
|
|
37
|
+
) # Deprecated, should be removed in the future
|
|
38
|
+
G_2_0_FLASH_THINKING = (
|
|
39
|
+
"gemini-2.0-flash-thinking",
|
|
40
|
+
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"9c17b1863f581b8a"]'},
|
|
41
|
+
False,
|
|
42
|
+
)
|
|
43
|
+
G_2_0_FLASH_THINKING_WITH_APPS = (
|
|
44
|
+
"gemini-2.0-flash-thinking-with-apps",
|
|
45
|
+
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"f8f8f5ea629f5d37"]'},
|
|
46
|
+
False,
|
|
47
|
+
)
|
|
48
|
+
G_2_0_EXP_ADVANCED = (
|
|
49
|
+
"gemini-2.0-exp-advanced",
|
|
50
|
+
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"b1e46a6037e6aa9f"]'},
|
|
51
|
+
True,
|
|
52
|
+
)
|
|
28
53
|
G_1_5_FLASH = (
|
|
29
54
|
"gemini-1.5-flash",
|
|
30
55
|
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"418ab5ea040b5c43"]'},
|
|
@@ -40,16 +65,6 @@ class Model(Enum):
|
|
|
40
65
|
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"e5a44cb1dae2b489"]'},
|
|
41
66
|
True,
|
|
42
67
|
)
|
|
43
|
-
G_2_0_FLASH_EXP = (
|
|
44
|
-
"gemini-2.0-flash-exp",
|
|
45
|
-
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"f299729663a2343f"]'},
|
|
46
|
-
False,
|
|
47
|
-
)
|
|
48
|
-
G_2_0_EXP_ADVANCED = (
|
|
49
|
-
"gemini-2.0-exp-advanced",
|
|
50
|
-
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"b1e46a6037e6aa9f"]'},
|
|
51
|
-
True,
|
|
52
|
-
)
|
|
53
68
|
|
|
54
69
|
def __init__(self, name, header, advanced_only):
|
|
55
70
|
self.model_name = name
|
|
@@ -13,6 +13,8 @@ class Candidate(BaseModel):
|
|
|
13
13
|
Reply candidate ID to build the metadata
|
|
14
14
|
text: `str`
|
|
15
15
|
Text output
|
|
16
|
+
thoughts: `str`, optional
|
|
17
|
+
Model's thought process, can be empty. Only populated with `-thinking` models
|
|
16
18
|
web_images: `list[WebImage]`, optional
|
|
17
19
|
List of web images in reply, can be empty.
|
|
18
20
|
generated_images: `list[GeneratedImage]`, optional
|
|
@@ -21,6 +23,7 @@ class Candidate(BaseModel):
|
|
|
21
23
|
|
|
22
24
|
rcid: str
|
|
23
25
|
text: str
|
|
26
|
+
thoughts: str | None = None
|
|
24
27
|
web_images: list[WebImage] = []
|
|
25
28
|
generated_images: list[GeneratedImage] = []
|
|
26
29
|
|
|
@@ -32,6 +32,10 @@ class ModelOutput(BaseModel):
|
|
|
32
32
|
def text(self) -> str:
|
|
33
33
|
return self.candidates[self.chosen].text
|
|
34
34
|
|
|
35
|
+
@property
|
|
36
|
+
def thoughts(self) -> str | None:
|
|
37
|
+
return self.candidates[self.chosen].thoughts
|
|
38
|
+
|
|
35
39
|
@property
|
|
36
40
|
def images(self) -> list[Image]:
|
|
37
41
|
return self.candidates[self.chosen].images
|
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
Metadata-Version: 2.
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
2
|
Name: gemini-webapi
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.9.1
|
|
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
|
|
@@ -679,6 +679,7 @@ License-File: LICENSE
|
|
|
679
679
|
Requires-Dist: httpx[http2]~=0.28.1
|
|
680
680
|
Requires-Dist: pydantic~=2.10.5
|
|
681
681
|
Requires-Dist: loguru~=0.7.3
|
|
682
|
+
Dynamic: license-file
|
|
682
683
|
|
|
683
684
|
<p align="center">
|
|
684
685
|
<img src="https://raw.githubusercontent.com/HanaokaYuzu/Gemini-API/master/assets/banner.png" width="55%" alt="Gemini Banner" align="center">
|
|
@@ -725,14 +726,15 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
725
726
|
- [Authentication](#authentication)
|
|
726
727
|
- [Usage](#usage)
|
|
727
728
|
- [Initialization](#initialization)
|
|
729
|
+
- [Select language model](#select-language-model)
|
|
728
730
|
- [Generate contents from text](#generate-contents-from-text)
|
|
729
731
|
- [Generate contents from image](#generate-contents-from-image)
|
|
730
732
|
- [Conversations across multiple turns](#conversations-across-multiple-turns)
|
|
731
733
|
- [Continue previous conversations](#continue-previous-conversations)
|
|
734
|
+
- [Retrieve model's thought process](#retrieve-models-thought-process)
|
|
732
735
|
- [Retrieve images in response](#retrieve-images-in-response)
|
|
733
736
|
- [Generate images with ImageFx](#generate-images-with-imagefx)
|
|
734
737
|
- [Save images to local files](#save-images-to-local-files)
|
|
735
|
-
- [Specify language model version](#specify-language-model-version)
|
|
736
738
|
- [Generate contents with Gemini extensions](#generate-contents-with-gemini-extensions)
|
|
737
739
|
- [Check and switch to other reply candidates](#check-and-switch-to-other-reply-candidates)
|
|
738
740
|
- [Control log level](#control-log-level)
|
|
@@ -815,6 +817,41 @@ asyncio.run(main())
|
|
|
815
817
|
>
|
|
816
818
|
> `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.
|
|
817
819
|
|
|
820
|
+
### Select language model
|
|
821
|
+
|
|
822
|
+
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`.
|
|
823
|
+
|
|
824
|
+
Currently available models (as of Feb 5, 2025):
|
|
825
|
+
|
|
826
|
+
- `unspecified` - Default model (same as `gemini-2.0-flash` if account does NOT have Gemini Advanced subscription)
|
|
827
|
+
- `gemini-2.0-flash` - Gemini 2.0 Flash
|
|
828
|
+
- `gemini-2.0-flash-thinking` - Gemini 2.0 Flash Thinking Experimental
|
|
829
|
+
- `gemini-2.0-flash-thinking-with-apps` - Gemini 2.0 Flash Thinking Experimental with apps
|
|
830
|
+
- `gemini-1.5-flash` - Gemini 1.5 Flash
|
|
831
|
+
|
|
832
|
+
Models pending update (may not work as expected):
|
|
833
|
+
|
|
834
|
+
- `gemini-2.0-exp-advanced` - Gemini 2.0 Experimental Advanced **(requires Gemini Advanced account)**
|
|
835
|
+
- `gemini-1.5-pro` - Gemini 1.5 Pro **(requires Gemini Advanced account)**
|
|
836
|
+
- `gemini-1.5-pro-research` - Gemini 1.5 Pro with Deep Research **(requires Gemini Advanced account)**
|
|
837
|
+
|
|
838
|
+
```python
|
|
839
|
+
from gemini_webapi.constants import Model
|
|
840
|
+
|
|
841
|
+
async def main():
|
|
842
|
+
response1 = await client.generate_content(
|
|
843
|
+
"What's you language model version? Reply version number only.",
|
|
844
|
+
model=Model.G_2_0_FLASH,
|
|
845
|
+
)
|
|
846
|
+
print(f"Model version ({Model.G_2_0_FLASH.model_name}): {response1.text}")
|
|
847
|
+
|
|
848
|
+
chat = client.start_chat(model="gemini-2.0-flash-thinking")
|
|
849
|
+
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
850
|
+
print(f"Model version (gemini-2.0-flash-thinking): {response2.text}")
|
|
851
|
+
|
|
852
|
+
asyncio.run(main())
|
|
853
|
+
```
|
|
854
|
+
|
|
818
855
|
### Generate contents from text
|
|
819
856
|
|
|
820
857
|
Ask a one-turn quick question by calling `GeminiClient.generate_content`.
|
|
@@ -885,6 +922,21 @@ async def main():
|
|
|
885
922
|
asyncio.run(main())
|
|
886
923
|
```
|
|
887
924
|
|
|
925
|
+
### Retrieve model's thought process
|
|
926
|
+
|
|
927
|
+
When using models with thinking capabilities, the model's thought process will be populated in `ModelOutput.thoughts`.
|
|
928
|
+
|
|
929
|
+
```python
|
|
930
|
+
async def main():
|
|
931
|
+
response = await client.generate_content(
|
|
932
|
+
"What's 1+1?", model="gemini-2.0-flash-thinking"
|
|
933
|
+
)
|
|
934
|
+
print(response.thoughts)
|
|
935
|
+
print(response.text)
|
|
936
|
+
|
|
937
|
+
asyncio.run(main())
|
|
938
|
+
```
|
|
939
|
+
|
|
888
940
|
### Retrieve images in response
|
|
889
941
|
|
|
890
942
|
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.
|
|
@@ -938,36 +990,6 @@ async def main():
|
|
|
938
990
|
asyncio.run(main())
|
|
939
991
|
```
|
|
940
992
|
|
|
941
|
-
### Specify language model version
|
|
942
|
-
|
|
943
|
-
You can choose a specified language model version by passing `model` argument to `GeminiClient.generate_content` or `GeminiClient.start_chat`. The default value is `unspecified`.
|
|
944
|
-
|
|
945
|
-
Currently available models (as of Feb 1, 2025):
|
|
946
|
-
|
|
947
|
-
- `unspecified` - Default model (Gemini 2.0 Flash if account does NOT have Gemini Advanced subscription)
|
|
948
|
-
- `gemini-1.5-flash` - Gemini 1.5 Flash
|
|
949
|
-
- `gemini-1.5-pro` - Gemini 1.5 Pro **(requires Gemini Advanced account)**
|
|
950
|
-
- `gemini-1.5-pro-research` - Gemini 1.5 Pro with Deep Research **(requires Gemini Advanced account)**
|
|
951
|
-
- `gemini-2.0-flash-exp` - Gemini 2.0 Flash Experimental
|
|
952
|
-
- `gemini-2.0-exp-advanced` - Gemini 2.0 Experimental Advanced **(requires Gemini Advanced account)**
|
|
953
|
-
|
|
954
|
-
```python
|
|
955
|
-
from gemini_webapi.constants import Model
|
|
956
|
-
|
|
957
|
-
async def main():
|
|
958
|
-
response1 = await client.generate_content(
|
|
959
|
-
"What's you language model version? Reply version number only.",
|
|
960
|
-
model="gemini-1.5-flash",
|
|
961
|
-
)
|
|
962
|
-
print(f"Model version (gemini-1.5-flash): {response1.text}")
|
|
963
|
-
|
|
964
|
-
chat = client.start_chat(model=Model.G_2_0_FLASH_EXP)
|
|
965
|
-
response2 = await chat.send_message("What's you language model version? Reply version number only.")
|
|
966
|
-
print(f"Model version ({Model.G_2_0_FLASH_EXP.model_name}): {response2.text}")
|
|
967
|
-
|
|
968
|
-
asyncio.run(main())
|
|
969
|
-
```
|
|
970
|
-
|
|
971
993
|
### Generate contents with Gemini extensions
|
|
972
994
|
|
|
973
995
|
> [!IMPORTANT]
|
|
@@ -25,8 +25,27 @@ class TestGeminiClient(unittest.IsolatedAsyncioTestCase):
|
|
|
25
25
|
|
|
26
26
|
@logger.catch(reraise=True)
|
|
27
27
|
async def test_successful_request(self):
|
|
28
|
-
response = await self.geminiclient.generate_content(
|
|
29
|
-
|
|
28
|
+
response = await self.geminiclient.generate_content(
|
|
29
|
+
"Hello World!", model=Model.G_2_0_FLASH
|
|
30
|
+
)
|
|
31
|
+
logger.debug(response.text)
|
|
32
|
+
|
|
33
|
+
@logger.catch(reraise=True)
|
|
34
|
+
async def test_thinking_model(self):
|
|
35
|
+
response = await self.geminiclient.generate_content(
|
|
36
|
+
"What's 1+1?", model=Model.G_2_0_FLASH_THINKING
|
|
37
|
+
)
|
|
38
|
+
logger.debug(response.thoughts)
|
|
39
|
+
logger.debug(response.text)
|
|
40
|
+
|
|
41
|
+
@logger.catch(reraise=True)
|
|
42
|
+
async def test_thinking_with_apps(self):
|
|
43
|
+
response = await self.geminiclient.generate_content(
|
|
44
|
+
"Tell me a fact about today in history and illustrate it with a youtube video",
|
|
45
|
+
model=Model.G_2_0_FLASH_THINKING_WITH_APPS,
|
|
46
|
+
)
|
|
47
|
+
logger.debug(response.thoughts)
|
|
48
|
+
logger.debug(response.text)
|
|
30
49
|
|
|
31
50
|
@logger.catch(reraise=True)
|
|
32
51
|
async def test_switch_model(self):
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|