gemini-webapi 1.10.1__tar.gz → 1.11.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.
Files changed (37) hide show
  1. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/PKG-INFO +5 -7
  2. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/README.md +3 -5
  3. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/pyproject.toml +1 -1
  4. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/client.py +30 -6
  5. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/constants.py +20 -26
  6. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/exceptions.py +16 -0
  7. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi.egg-info/PKG-INFO +5 -7
  8. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi.egg-info/requires.txt +1 -1
  9. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/tests/test_client_features.py +16 -9
  10. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/.github/dependabot.yml +0 -0
  11. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/.github/workflows/github-release.yml +0 -0
  12. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/.github/workflows/pypi-publish.yml +0 -0
  13. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/.gitignore +0 -0
  14. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/.vscode/launch.json +0 -0
  15. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/.vscode/settings.json +0 -0
  16. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/LICENSE +0 -0
  17. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/assets/banner.png +0 -0
  18. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/assets/favicon.png +0 -0
  19. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/assets/logo.svg +0 -0
  20. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/assets/sample.pdf +0 -0
  21. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/setup.cfg +0 -0
  22. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/__init__.py +0 -0
  23. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/types/__init__.py +0 -0
  24. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/types/candidate.py +0 -0
  25. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/types/image.py +0 -0
  26. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/types/modeloutput.py +0 -0
  27. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/utils/__init__.py +0 -0
  28. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/utils/get_access_token.py +0 -0
  29. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/utils/load_browser_cookies.py +0 -0
  30. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/utils/logger.py +0 -0
  31. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/utils/rotate_1psidts.py +0 -0
  32. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi/utils/upload_file.py +0 -0
  33. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi.egg-info/SOURCES.txt +0 -0
  34. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi.egg-info/dependency_links.txt +0 -0
  35. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/src/gemini_webapi.egg-info/top_level.txt +0 -0
  36. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/tests/test_rotate_cookies.py +0 -0
  37. {gemini_webapi-1.10.1 → gemini_webapi-1.11.0}/tests/test_save_image.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemini-webapi
3
- Version: 1.10.1
3
+ Version: 1.11.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,8 @@ 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: pydantic~=2.11.3
682
682
  Dynamic: license-file
683
683
 
684
684
  <p align="center">
@@ -822,18 +822,16 @@ You can specify which language model to use by passing `model` argument to `Gemi
822
822
 
823
823
  Currently available models (as of Feb 5, 2025):
824
824
 
825
- - `unspecified` - Default model (same as `gemini-2.0-flash` if account does NOT have Gemini Advanced subscription)
825
+ - `unspecified` - Default model
826
826
  - `gemini-2.0-flash` - Gemini 2.0 Flash
827
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
828
+ - `gemini-2.5-flash` - Gemini 2.5 Flash
829
+ - `gemini-2.5-pro` - Gemini 2.5 Pro (daily usage limit imposed)
830
830
 
831
831
  Models pending update (may not work as expected):
832
832
 
833
833
  - `gemini-2.5-exp-advanced` - Gemini 2.5 Experimental Advanced **(requires Gemini Advanced account)**
834
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
835
 
838
836
  ```python
839
837
  from gemini_webapi.constants import Model
@@ -139,18 +139,16 @@ You can specify which language model to use by passing `model` argument to `Gemi
139
139
 
140
140
  Currently available models (as of Feb 5, 2025):
141
141
 
142
- - `unspecified` - Default model (same as `gemini-2.0-flash` if account does NOT have Gemini Advanced subscription)
142
+ - `unspecified` - Default model
143
143
  - `gemini-2.0-flash` - Gemini 2.0 Flash
144
144
  - `gemini-2.0-flash-thinking` - Gemini 2.0 Flash Thinking Experimental
145
- - `gemini-2.0-flash-thinking-with-apps` - Gemini 2.0 Flash Thinking Experimental with apps
146
- - `gemini-1.5-flash` - Gemini 1.5 Flash
145
+ - `gemini-2.5-flash` - Gemini 2.5 Flash
146
+ - `gemini-2.5-pro` - Gemini 2.5 Pro (daily usage limit imposed)
147
147
 
148
148
  Models pending update (may not work as expected):
149
149
 
150
150
  - `gemini-2.5-exp-advanced` - Gemini 2.5 Experimental Advanced **(requires Gemini Advanced account)**
151
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
152
 
155
153
  ```python
156
154
  from gemini_webapi.constants import Model
@@ -21,8 +21,8 @@ classifiers = [
21
21
  requires-python = ">=3.10"
22
22
  dependencies = [
23
23
  "httpx[http2]~=0.28.1",
24
- "pydantic~=2.10.5",
25
24
  "loguru~=0.7.3",
25
+ "pydantic~=2.11.3",
26
26
  ]
27
27
  dynamic = ["version"]
28
28
 
@@ -8,8 +8,15 @@ from typing import Any, Optional
8
8
 
9
9
  from httpx import AsyncClient, ReadTimeout
10
10
 
11
- from .constants import Endpoint, Headers, Model
12
- from .exceptions import AuthError, APIError, TimeoutError, GeminiError
11
+ from .constants import Endpoint, ErrorCode, Headers, Model
12
+ from .exceptions import (
13
+ AuthError,
14
+ APIError,
15
+ TimeoutError,
16
+ GeminiError,
17
+ UsageLimitExceeded,
18
+ ModelInvalid,
19
+ )
13
20
  from .types import WebImage, GeneratedImage, Candidate, ModelOutput
14
21
  from .utils import (
15
22
  upload_file,
@@ -376,10 +383,27 @@ class GeminiClient:
376
383
  raise Exception
377
384
  except Exception:
378
385
  await self.close()
379
- logger.debug(f"Invalid response: {response.text}")
380
- raise APIError(
381
- "Failed to generate contents. Invalid response data received. Client will try to re-initialize on next request."
382
- )
386
+
387
+ try:
388
+ match ErrorCode(response_json[0][5][2][0][1][0]):
389
+ case ErrorCode.USAGE_LIMIT_EXCEEDED:
390
+ raise UsageLimitExceeded(
391
+ f"Failed to generate contents. Usage limit of {model.model_name} model has exceeded. Please try switching to another model."
392
+ )
393
+ case ErrorCode.MODEL_HEADER_INVALID:
394
+ raise ModelInvalid(
395
+ "Failed to generate contents. The specified model is not available. Please update gemini_webapi to the latest version. "
396
+ "If the error persists and is caused by the package, please report it on GitHub."
397
+ )
398
+ case _:
399
+ raise Exception
400
+ except GeminiError:
401
+ raise
402
+ except Exception:
403
+ logger.debug(f"Invalid response: {response.text}")
404
+ raise APIError(
405
+ "Failed to generate contents. Invalid response data received. Client will try to re-initialize on next request."
406
+ )
383
407
 
384
408
  try:
385
409
  candidates = []
@@ -27,24 +27,24 @@ class Model(Enum):
27
27
  UNSPECIFIED = ("unspecified", {}, False)
28
28
  G_2_0_FLASH = (
29
29
  "gemini-2.0-flash",
30
- {"x-goog-ext-525001261-jspb": '[null,null,null,null,"f299729663a2343f"]'},
30
+ {"x-goog-ext-525001261-jspb": '[1,null,null,null,"f299729663a2343f"]'},
31
31
  False,
32
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
33
  G_2_0_FLASH_THINKING = (
39
34
  "gemini-2.0-flash-thinking",
40
- {"x-goog-ext-525001261-jspb": '[null,null,null,null,"9c17b1863f581b8a"]'},
35
+ {"x-goog-ext-525001261-jspb": '[null,null,null,null,"7ca48d02d802f20a"]'},
36
+ False,
37
+ ) # Deprecated
38
+ G_2_5_FLASH = (
39
+ "gemini-2.5-flash",
40
+ {"x-goog-ext-525001261-jspb": '[1,null,null,null,"35609594dbe934d8"]'},
41
41
  False,
42
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"]'},
43
+ G_2_5_PRO = (
44
+ "gemini-2.5-pro",
45
+ {"x-goog-ext-525001261-jspb": '[1,null,null,null,"2525e3954d185b3c"]'},
46
46
  False,
47
- ) # Deprecated, should be removed in the future
47
+ )
48
48
  G_2_0_EXP_ADVANCED = (
49
49
  "gemini-2.0-exp-advanced",
50
50
  {"x-goog-ext-525001261-jspb": '[null,null,null,null,"b1e46a6037e6aa9f"]'},
@@ -55,21 +55,6 @@ class Model(Enum):
55
55
  {"x-goog-ext-525001261-jspb": '[null,null,null,null,"203e6bb81620bcfe"]'},
56
56
  True,
57
57
  )
58
- G_1_5_FLASH = (
59
- "gemini-1.5-flash",
60
- {"x-goog-ext-525001261-jspb": '[null,null,null,null,"418ab5ea040b5c43"]'},
61
- False,
62
- ) # Deprecated, should be removed in the future
63
- G_1_5_PRO = (
64
- "gemini-1.5-pro",
65
- {"x-goog-ext-525001261-jspb": '[null,null,null,null,"9d60dfae93c9ff1f"]'},
66
- True,
67
- ) # Deprecated, should be removed in the future
68
- G_1_5_PRO_RESEARCH = (
69
- "gemini-1.5-pro-research",
70
- {"x-goog-ext-525001261-jspb": '[null,null,null,null,"e5a44cb1dae2b489"]'},
71
- True,
72
- ) # Deprecated, should be removed in the future
73
58
 
74
59
  def __init__(self, name, header, advanced_only):
75
60
  self.model_name = name
@@ -84,3 +69,12 @@ class Model(Enum):
84
69
  raise ValueError(
85
70
  f"Unknown model name: {name}. Available models: {', '.join([model.model_name for model in cls])}"
86
71
  )
72
+
73
+
74
+ class ErrorCode(Enum):
75
+ """
76
+ Known error codes returned from server.
77
+ """
78
+
79
+ USAGE_LIMIT_EXCEEDED = 1037
80
+ MODEL_HEADER_INVALID = 1052
@@ -28,3 +28,19 @@ class TimeoutError(GeminiError):
28
28
  """
29
29
 
30
30
  pass
31
+
32
+
33
+ class UsageLimitExceeded(GeminiError):
34
+ """
35
+ Exception for model usage limit exceeded errors.
36
+ """
37
+
38
+ pass
39
+
40
+
41
+ class ModelInvalid(GeminiError):
42
+ """
43
+ Exception for invalid model header string errors.
44
+ """
45
+
46
+ pass
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemini-webapi
3
- Version: 1.10.1
3
+ Version: 1.11.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,8 @@ 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: pydantic~=2.11.3
682
682
  Dynamic: license-file
683
683
 
684
684
  <p align="center">
@@ -822,18 +822,16 @@ You can specify which language model to use by passing `model` argument to `Gemi
822
822
 
823
823
  Currently available models (as of Feb 5, 2025):
824
824
 
825
- - `unspecified` - Default model (same as `gemini-2.0-flash` if account does NOT have Gemini Advanced subscription)
825
+ - `unspecified` - Default model
826
826
  - `gemini-2.0-flash` - Gemini 2.0 Flash
827
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
828
+ - `gemini-2.5-flash` - Gemini 2.5 Flash
829
+ - `gemini-2.5-pro` - Gemini 2.5 Pro (daily usage limit imposed)
830
830
 
831
831
  Models pending update (may not work as expected):
832
832
 
833
833
  - `gemini-2.5-exp-advanced` - Gemini 2.5 Experimental Advanced **(requires Gemini Advanced account)**
834
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
835
 
838
836
  ```python
839
837
  from gemini_webapi.constants import Model
@@ -1,3 +1,3 @@
1
1
  httpx[http2]~=0.28.1
2
- pydantic~=2.10.5
3
2
  loguru~=0.7.3
3
+ pydantic~=2.11.3
@@ -7,6 +7,7 @@ from loguru import logger
7
7
 
8
8
  from gemini_webapi import GeminiClient, AuthError, set_log_level
9
9
  from gemini_webapi.constants import Model
10
+ from gemini_webapi.exceptions import UsageLimitExceeded, ModelInvalid
10
11
 
11
12
  logging.getLogger("asyncio").setLevel(logging.ERROR)
12
13
  set_log_level("DEBUG")
@@ -19,22 +20,23 @@ class TestGeminiClient(unittest.IsolatedAsyncioTestCase):
19
20
  )
20
21
 
21
22
  try:
22
- await self.geminiclient.init()
23
+ await self.geminiclient.init(timeout=60)
23
24
  except AuthError as e:
24
25
  self.skipTest(e)
25
26
 
26
27
  @logger.catch(reraise=True)
27
28
  async def test_successful_request(self):
28
29
  response = await self.geminiclient.generate_content(
29
- "Hello World!", model=Model.G_2_0_FLASH
30
+ "Tell me a fact about today in history and illustrate it with a youtube video",
31
+ model=Model.G_2_5_FLASH,
30
32
  )
31
33
  logger.debug(response.text)
32
34
 
33
35
  @logger.catch(reraise=True)
34
36
  async def test_thinking_model(self):
35
37
  response = await self.geminiclient.generate_content(
36
- "Tell me a fact about today in history and illustrate it with a youtube video",
37
- model=Model.G_2_0_FLASH_THINKING,
38
+ "1+1=?",
39
+ model=Model.G_2_5_FLASH,
38
40
  )
39
41
  logger.debug(response.thoughts)
40
42
  logger.debug(response.text)
@@ -46,11 +48,16 @@ class TestGeminiClient(unittest.IsolatedAsyncioTestCase):
46
48
  logger.debug(f"Model {model.model_name} requires an advanced account")
47
49
  continue
48
50
 
49
- response = await self.geminiclient.generate_content(
50
- "What's you language model version? Reply version number only.",
51
- model=model,
52
- )
53
- logger.debug(f"Model version ({model.model_name}): {response.text}")
51
+ try:
52
+ response = await self.geminiclient.generate_content(
53
+ "What's you language model version? Reply version number only.",
54
+ model=model,
55
+ )
56
+ logger.debug(f"Model version ({model.model_name}): {response.text}")
57
+ except UsageLimitExceeded:
58
+ logger.debug(f"Model {model.model_name} usage limit exceeded")
59
+ except ModelInvalid:
60
+ logger.debug(f"Model {model.model_name} is not available anymore")
54
61
 
55
62
  @logger.catch(reraise=True)
56
63
  async def test_upload_files(self):
File without changes
File without changes