gemini-webapi 1.11.1__py3-none-any.whl → 1.12.0__py3-none-any.whl

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/client.py CHANGED
@@ -12,6 +12,7 @@ from .constants import Endpoint, ErrorCode, Headers, Model
12
12
  from .exceptions import (
13
13
  AuthError,
14
14
  APIError,
15
+ ImageGenerationError,
15
16
  TimeoutError,
16
17
  GeminiError,
17
18
  UsageLimitExceeded,
@@ -62,10 +63,15 @@ def running(retry: int = 0) -> callable:
62
63
  )
63
64
  else:
64
65
  return await func(client, *args, **kwargs)
65
- except APIError:
66
+ except APIError as e:
67
+ # Image generation takes too long, only retry once
68
+ if isinstance(e, ImageGenerationError):
69
+ retry = min(1, retry)
70
+
66
71
  if retry > 0:
67
72
  await asyncio.sleep(1)
68
73
  return await wrapper(client, *args, retry=retry - 1, **kwargs)
74
+
69
75
  raise
70
76
 
71
77
  return wrapper
@@ -371,11 +377,12 @@ class GeminiClient:
371
377
  response_json = json.loads(response.text.split("\n")[2])
372
378
 
373
379
  body = None
374
- for part in response_json:
380
+ body_index = 0
381
+ for part_index, part in enumerate(response_json):
375
382
  try:
376
383
  main_part = json.loads(part[2])
377
384
  if main_part[4]:
378
- body = main_part
385
+ body_index, body = part_index, main_part
379
386
  break
380
387
  except (IndexError, TypeError, ValueError):
381
388
  continue
@@ -412,7 +419,7 @@ class GeminiClient:
412
419
 
413
420
  try:
414
421
  candidates = []
415
- for i, candidate in enumerate(body[4]):
422
+ for candidate_index, candidate in enumerate(body[4]):
416
423
  text = candidate[1][0]
417
424
  if re.match(
418
425
  r"^http://googleusercontent\.com/card_content/\d+$", text
@@ -429,45 +436,59 @@ class GeminiClient:
429
436
  and candidate[12][1]
430
437
  and [
431
438
  WebImage(
432
- url=image[0][0][0],
433
- title=image[7][0],
434
- alt=image[0][4],
439
+ url=web_image[0][0][0],
440
+ title=web_image[7][0],
441
+ alt=web_image[0][4],
435
442
  proxy=self.proxy,
436
443
  )
437
- for image in candidate[12][1]
444
+ for web_image in candidate[12][1]
438
445
  ]
439
446
  or []
440
447
  )
441
448
 
442
449
  generated_images = []
443
450
  if candidate[12] and candidate[12][7] and candidate[12][7][0]:
444
- image_generation_body = json.loads(response_json[1][2])
445
- image_generation_candidate = image_generation_body[4][i]
451
+ img_body = None
452
+ for img_part_index, part in enumerate(response_json):
453
+ if img_part_index < body_index:
454
+ continue
455
+
456
+ try:
457
+ img_part = json.loads(part[2])
458
+ if img_part[4][candidate_index][12][7][0]:
459
+ img_body = img_part
460
+ break
461
+ except (IndexError, TypeError, ValueError):
462
+ continue
463
+
464
+ if not img_body:
465
+ raise ImageGenerationError(
466
+ "Failed to parse generated images. Please update gemini_webapi to the latest version. "
467
+ "If the error persists and is caused by the package, please report it on GitHub."
468
+ )
469
+
470
+ img_candidate = img_body[4][candidate_index]
471
+
446
472
  text = re.sub(
447
473
  r"http://googleusercontent\.com/image_generation_content/\d+$",
448
474
  "",
449
- image_generation_candidate[1][0],
475
+ img_candidate[1][0],
450
476
  ).rstrip()
451
477
 
452
- if (
453
- image_generation_candidate[12]
454
- and image_generation_candidate[12][7]
455
- and image_generation_candidate[12][7][0]
456
- ):
457
- generated_images = [
458
- GeneratedImage(
459
- url=image[0][3][3],
460
- title=f"[Generated Image {image[3][6]}]",
461
- alt=len(image[3][5]) > i
462
- and image[3][5][i]
463
- or image[3][5][0],
464
- proxy=self.proxy,
465
- cookies=self.cookies,
466
- )
467
- for i, image in enumerate(
468
- image_generation_candidate[12][7][0]
469
- )
470
- ]
478
+ generated_images = [
479
+ GeneratedImage(
480
+ url=generated_image[0][3][3],
481
+ title=f"[Generated Image {generated_image[3][6]}]",
482
+ alt=len(generated_image[3][5]) > image_index
483
+ and generated_image[3][5][image_index]
484
+ or generated_image[3][5][0],
485
+ proxy=self.proxy,
486
+ cookies=self.cookies,
487
+ )
488
+ for image_index, generated_image in enumerate(
489
+ img_candidate[12][7][0]
490
+ )
491
+ ]
471
492
 
472
493
  candidates.append(
473
494
  Candidate(
@@ -14,6 +14,14 @@ class APIError(Exception):
14
14
  pass
15
15
 
16
16
 
17
+ class ImageGenerationError(APIError):
18
+ """
19
+ Exception for generated image parsing errors.
20
+ """
21
+
22
+ pass
23
+
24
+
17
25
  class GeminiError(Exception):
18
26
  """
19
27
  Exception for errors returned from Gemini server which are not handled by the package.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemini-webapi
3
- Version: 1.11.1
3
+ Version: 1.12.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
@@ -1,7 +1,7 @@
1
1
  gemini_webapi/__init__.py,sha256=28uNIywK4vCXxENaSagNWUzhqr1RyNtLzDF6WRRM4KQ,194
2
- gemini_webapi/client.py,sha256=waD8cnC8ol00T64F9NHihB43Wxzui9guYwrOpTvGw-8,24460
2
+ gemini_webapi/client.py,sha256=sxzFXfi4OGn2yLuPywVLyWo40LcHNdSWL3YXivTaJ1o,25398
3
3
  gemini_webapi/constants.py,sha256=xQloL6yHngniVEX5UnrsEKGTmMAieqxH7UUceefUVd8,2530
4
- gemini_webapi/exceptions.py,sha256=7p6R5WZsAgwmggqoTM3No0i76PhYbPAFBdS7iqBExLE,922
4
+ gemini_webapi/exceptions.py,sha256=qkXrIpr0L7LtGbq3VcTO8D1xZ50pJtt0dDRp5I3uDSg,1038
5
5
  gemini_webapi/types/__init__.py,sha256=d2kvXnE004s2E2KDmPPLi5N-BQ59FgDSlrGrO3Wphww,163
6
6
  gemini_webapi/types/candidate.py,sha256=dMoGr53WR7FYDRrXpG9Yd_n9YTHGwGaFHZ8zPt8RMWw,1178
7
7
  gemini_webapi/types/image.py,sha256=4BC8hxAWJrYFwzA60CivF1di4RZkzPKjcaSPPFKmRdY,5237
@@ -12,8 +12,8 @@ gemini_webapi/utils/load_browser_cookies.py,sha256=A5n_VsB7Rm8ck5lpy856UNJEhv30l
12
12
  gemini_webapi/utils/logger.py,sha256=PF4ROQq7scRRrWzeYdeYiYs2S2Jqr0bgjyrPbXVOCqE,816
13
13
  gemini_webapi/utils/rotate_1psidts.py,sha256=NyQ9OYPLBOcvpc8bodvEYDIVFrsYN0kdfc831lPEctM,1680
14
14
  gemini_webapi/utils/upload_file.py,sha256=SJOMr6kryK_ClrKmqI96fqZBNFOMPsyAvFINAGAU3rk,1468
15
- gemini_webapi-1.11.1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
16
- gemini_webapi-1.11.1.dist-info/METADATA,sha256=ClvGwberW9SgN8v81Zz0t0drx1ulluD6WQclybfzKnY,57167
17
- gemini_webapi-1.11.1.dist-info/WHEEL,sha256=pxyMxgL8-pra_rKaQ4drOZAegBVuX-G_4nRHjjgWbmo,91
18
- gemini_webapi-1.11.1.dist-info/top_level.txt,sha256=dtWtug_ZrmnUqCYuu8NmGzTgWglHeNzhHU_hXmqZGWE,14
19
- gemini_webapi-1.11.1.dist-info/RECORD,,
15
+ gemini_webapi-1.12.0.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
16
+ gemini_webapi-1.12.0.dist-info/METADATA,sha256=lCgrSQ-CJuWI6yyHaYE5JKJtyfbCTLzSDqOgPBIDYdM,57167
17
+ gemini_webapi-1.12.0.dist-info/WHEEL,sha256=DnLRTWE75wApRYVsjgc6wsVswC54sMSJhAEd4xhDpBk,91
18
+ gemini_webapi-1.12.0.dist-info/top_level.txt,sha256=dtWtug_ZrmnUqCYuu8NmGzTgWglHeNzhHU_hXmqZGWE,14
19
+ gemini_webapi-1.12.0.dist-info/RECORD,,
@@ -1,5 +1,5 @@
1
1
  Wheel-Version: 1.0
2
- Generator: setuptools (79.0.0)
2
+ Generator: setuptools (80.4.0)
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
5
5