gemini-webapi 1.8.0__tar.gz → 1.8.2__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 (36) hide show
  1. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/.github/workflows/pypi-publish.yml +1 -1
  2. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/PKG-INFO +6 -3
  3. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/README.md +4 -1
  4. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/client.py +26 -15
  5. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/constants.py +20 -2
  6. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi.egg-info/PKG-INFO +6 -3
  7. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/tests/test_client_features.py +15 -1
  8. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/.github/dependabot.yml +0 -0
  9. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/.github/workflows/github-release.yml +0 -0
  10. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/.gitignore +0 -0
  11. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/.vscode/launch.json +0 -0
  12. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/.vscode/settings.json +0 -0
  13. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/LICENSE +0 -0
  14. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/assets/banner.png +0 -0
  15. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/assets/favicon.png +0 -0
  16. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/assets/logo.svg +0 -0
  17. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/pyproject.toml +0 -0
  18. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/setup.cfg +0 -0
  19. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/__init__.py +0 -0
  20. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/exceptions.py +0 -0
  21. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/types/__init__.py +0 -0
  22. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/types/candidate.py +0 -0
  23. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/types/image.py +0 -0
  24. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/types/modeloutput.py +0 -0
  25. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/utils/__init__.py +0 -0
  26. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/utils/get_access_token.py +0 -0
  27. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/utils/load_browser_cookies.py +0 -0
  28. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/utils/logger.py +0 -0
  29. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/utils/rotate_1psidts.py +0 -0
  30. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi/utils/upload_file.py +0 -0
  31. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi.egg-info/SOURCES.txt +0 -0
  32. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi.egg-info/dependency_links.txt +0 -0
  33. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi.egg-info/requires.txt +0 -0
  34. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/src/gemini_webapi.egg-info/top_level.txt +0 -0
  35. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/tests/test_rotate_cookies.py +0 -0
  36. {gemini_webapi-1.8.0 → gemini_webapi-1.8.2}/tests/test_save_image.py +0 -0
@@ -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.4.3
39
+ uses: actions/upload-artifact@v4.5.0
40
40
  with:
41
41
  name: dist
42
42
  path: dist
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: gemini-webapi
3
- Version: 1.8.0
3
+ Version: 1.8.2
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
@@ -944,9 +944,12 @@ You can choose a specified language model version by passing `model` argument to
944
944
 
945
945
  Currently available models (as of Dec 21, 2024):
946
946
 
947
- - `unspecified` - Default model (Gemini 1.5 Flash)
947
+ - `unspecified` - Default model (Gemini 1.5 Pro if account has Gemini Advanced subscription, otherwise Gemini 1.5 Flash)
948
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)**
949
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)**
950
953
 
951
954
  ```python
952
955
  from gemini_webapi.constants import Model
@@ -262,9 +262,12 @@ You can choose a specified language model version by passing `model` argument to
262
262
 
263
263
  Currently available models (as of Dec 21, 2024):
264
264
 
265
- - `unspecified` - Default model (Gemini 1.5 Flash)
265
+ - `unspecified` - Default model (Gemini 1.5 Pro if account has Gemini Advanced subscription, otherwise Gemini 1.5 Flash)
266
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)**
267
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)**
268
271
 
269
272
  ```python
270
273
  from gemini_webapi.constants import Model
@@ -381,7 +381,7 @@ class GeminiClient:
381
381
  for i, candidate in enumerate(body[4]):
382
382
  text = candidate[1][0]
383
383
  if re.match(
384
- r"^http://googleusercontent.com/card_content/\d+$", text
384
+ r"^http://googleusercontent\.com/card_content/\d+$", text
385
385
  ):
386
386
  text = candidate[22] and candidate[22][0] or text
387
387
 
@@ -404,20 +404,31 @@ class GeminiClient:
404
404
  if candidate[12] and candidate[12][7] and candidate[12][7][0]:
405
405
  image_generation_body = json.loads(response_json[1][2])
406
406
  image_generation_candidate = image_generation_body[4][i]
407
- generated_images = [
408
- GeneratedImage(
409
- url=image[0][3][3],
410
- title=f"[Generated Image {image[3][6]}]",
411
- alt=len(image[3][5]) > i
412
- and image[3][5][i]
413
- or image[3][5][0],
414
- proxy=self.proxy,
415
- cookies=self.cookies,
416
- )
417
- for i, image in enumerate(
418
- image_generation_candidate[12][7][0]
419
- )
420
- ] or []
407
+ text = re.sub(
408
+ r"http://googleusercontent\.com/image_generation_content/\d+$",
409
+ "",
410
+ image_generation_candidate[1][0],
411
+ ).rstrip()
412
+
413
+ if (
414
+ image_generation_candidate[12]
415
+ and image_generation_candidate[12][7]
416
+ and image_generation_candidate[12][7][0]
417
+ ):
418
+ generated_images = [
419
+ GeneratedImage(
420
+ url=image[0][3][3],
421
+ title=f"[Generated Image {image[3][6]}]",
422
+ alt=len(image[3][5]) > i
423
+ and image[3][5][i]
424
+ or image[3][5][0],
425
+ proxy=self.proxy,
426
+ cookies=self.cookies,
427
+ )
428
+ for i, image in enumerate(
429
+ image_generation_candidate[12][7][0]
430
+ )
431
+ ]
421
432
 
422
433
  candidates.append(
423
434
  Candidate(
@@ -24,19 +24,37 @@ class Headers(Enum):
24
24
 
25
25
 
26
26
  class Model(Enum):
27
- UNSPECIFIED = ("unspecified", {})
27
+ UNSPECIFIED = ("unspecified", {}, False)
28
28
  G_1_5_FLASH = (
29
29
  "gemini-1.5-flash",
30
30
  {"x-goog-ext-525001261-jspb": '[null,null,null,null,"7daceb7ef88130f5"]'},
31
+ False,
32
+ )
33
+ G_1_5_PRO = (
34
+ "gemini-1.5-pro",
35
+ {"x-goog-ext-525001261-jspb": '[null,null,null,null,"9d60dfae93c9ff1f"]'},
36
+ True,
37
+ )
38
+ G_1_5_PRO_RESEARCH = (
39
+ "gemini-1.5-pro-research",
40
+ {"x-goog-ext-525001261-jspb": '[null,null,null,null,"e5a44cb1dae2b489"]'},
41
+ True,
31
42
  )
32
43
  G_2_0_FLASH_EXP = (
33
44
  "gemini-2.0-flash-exp",
34
45
  {"x-goog-ext-525001261-jspb": '[null,null,null,null,"948b866104ccf484"]'},
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,
35
52
  )
36
53
 
37
- def __init__(self, name, header):
54
+ def __init__(self, name, header, advanced_only):
38
55
  self.model_name = name
39
56
  self.model_header = header
57
+ self.advanced_only = advanced_only
40
58
 
41
59
  @classmethod
42
60
  def from_name(cls, name: str):
@@ -1,6 +1,6 @@
1
- Metadata-Version: 2.1
1
+ Metadata-Version: 2.2
2
2
  Name: gemini-webapi
3
- Version: 1.8.0
3
+ Version: 1.8.2
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
@@ -944,9 +944,12 @@ You can choose a specified language model version by passing `model` argument to
944
944
 
945
945
  Currently available models (as of Dec 21, 2024):
946
946
 
947
- - `unspecified` - Default model (Gemini 1.5 Flash)
947
+ - `unspecified` - Default model (Gemini 1.5 Pro if account has Gemini Advanced subscription, otherwise Gemini 1.5 Flash)
948
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)**
949
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)**
950
953
 
951
954
  ```python
952
955
  from gemini_webapi.constants import Model
@@ -31,6 +31,10 @@ class TestGeminiClient(unittest.IsolatedAsyncioTestCase):
31
31
  @logger.catch(reraise=True)
32
32
  async def test_switch_model(self):
33
33
  for model in Model:
34
+ if model.advanced_only:
35
+ logger.debug(f"Model {model.model_name} requires an advanced account")
36
+ continue
37
+
34
38
  response = await self.geminiclient.generate_content(
35
39
  "What's you language model version? Reply version number only.",
36
40
  model=model,
@@ -81,20 +85,30 @@ class TestGeminiClient(unittest.IsolatedAsyncioTestCase):
81
85
  "Send me some pictures of cats"
82
86
  )
83
87
  self.assertTrue(response.images)
88
+ logger.debug(response.text)
84
89
  for image in response.images:
85
90
  self.assertTrue(image.url)
86
91
  logger.debug(image)
87
92
 
88
93
  @logger.catch(reraise=True)
89
- async def test_ai_image_generation(self):
94
+ async def test_image_generation(self):
90
95
  response = await self.geminiclient.generate_content(
91
96
  "Generate some pictures of cats"
92
97
  )
93
98
  self.assertTrue(response.images)
99
+ logger.debug(response.text)
94
100
  for image in response.images:
95
101
  self.assertTrue(image.url)
96
102
  logger.debug(image)
97
103
 
104
+ @logger.catch(reraise=True)
105
+ async def test_image_generation_failure(self):
106
+ response = await self.geminiclient.generate_content(
107
+ "Generate some pictures of people"
108
+ )
109
+ self.assertFalse(response.images)
110
+ logger.debug(response.text)
111
+
98
112
  @logger.catch(reraise=True)
99
113
  async def test_card_content(self):
100
114
  response = await self.geminiclient.generate_content("How is today's weather?")
File without changes
File without changes
File without changes