gemini-webapi 1.11.0__tar.gz → 1.12.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.11.0 → gemini_webapi-1.12.0}/.github/workflows/pypi-publish.yml +1 -1
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/PKG-INFO +1 -1
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/client.py +56 -30
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/constants.py +1 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/exceptions.py +16 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi.egg-info/PKG-INFO +1 -1
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/.github/dependabot.yml +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/.github/workflows/github-release.yml +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/.gitignore +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/.vscode/launch.json +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/.vscode/settings.json +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/LICENSE +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/README.md +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/assets/banner.png +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/assets/favicon.png +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/assets/logo.svg +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/assets/sample.pdf +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/pyproject.toml +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/setup.cfg +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/__init__.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/types/__init__.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/types/candidate.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/types/image.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/types/modeloutput.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/utils/__init__.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/utils/get_access_token.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/utils/load_browser_cookies.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/utils/logger.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/utils/rotate_1psidts.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/utils/upload_file.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi.egg-info/SOURCES.txt +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi.egg-info/dependency_links.txt +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi.egg-info/requires.txt +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi.egg-info/top_level.txt +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/tests/test_client_features.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/tests/test_rotate_cookies.py +0 -0
- {gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/tests/test_save_image.py +0 -0
|
@@ -12,10 +12,12 @@ 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,
|
|
18
19
|
ModelInvalid,
|
|
20
|
+
TemporarilyBlocked,
|
|
19
21
|
)
|
|
20
22
|
from .types import WebImage, GeneratedImage, Candidate, ModelOutput
|
|
21
23
|
from .utils import (
|
|
@@ -61,10 +63,15 @@ def running(retry: int = 0) -> callable:
|
|
|
61
63
|
)
|
|
62
64
|
else:
|
|
63
65
|
return await func(client, *args, **kwargs)
|
|
64
|
-
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
|
+
|
|
65
71
|
if retry > 0:
|
|
66
72
|
await asyncio.sleep(1)
|
|
67
73
|
return await wrapper(client, *args, retry=retry - 1, **kwargs)
|
|
74
|
+
|
|
68
75
|
raise
|
|
69
76
|
|
|
70
77
|
return wrapper
|
|
@@ -370,11 +377,12 @@ class GeminiClient:
|
|
|
370
377
|
response_json = json.loads(response.text.split("\n")[2])
|
|
371
378
|
|
|
372
379
|
body = None
|
|
373
|
-
|
|
380
|
+
body_index = 0
|
|
381
|
+
for part_index, part in enumerate(response_json):
|
|
374
382
|
try:
|
|
375
383
|
main_part = json.loads(part[2])
|
|
376
384
|
if main_part[4]:
|
|
377
|
-
body = main_part
|
|
385
|
+
body_index, body = part_index, main_part
|
|
378
386
|
break
|
|
379
387
|
except (IndexError, TypeError, ValueError):
|
|
380
388
|
continue
|
|
@@ -395,6 +403,10 @@ class GeminiClient:
|
|
|
395
403
|
"Failed to generate contents. The specified model is not available. Please update gemini_webapi to the latest version. "
|
|
396
404
|
"If the error persists and is caused by the package, please report it on GitHub."
|
|
397
405
|
)
|
|
406
|
+
case ErrorCode.IP_TEMPORARILY_BLOCKED:
|
|
407
|
+
raise TemporarilyBlocked(
|
|
408
|
+
"Failed to generate contents. Your IP address is temporarily blocked by Google. Please try using a proxy or waiting for a while."
|
|
409
|
+
)
|
|
398
410
|
case _:
|
|
399
411
|
raise Exception
|
|
400
412
|
except GeminiError:
|
|
@@ -407,7 +419,7 @@ class GeminiClient:
|
|
|
407
419
|
|
|
408
420
|
try:
|
|
409
421
|
candidates = []
|
|
410
|
-
for
|
|
422
|
+
for candidate_index, candidate in enumerate(body[4]):
|
|
411
423
|
text = candidate[1][0]
|
|
412
424
|
if re.match(
|
|
413
425
|
r"^http://googleusercontent\.com/card_content/\d+$", text
|
|
@@ -424,45 +436,59 @@ class GeminiClient:
|
|
|
424
436
|
and candidate[12][1]
|
|
425
437
|
and [
|
|
426
438
|
WebImage(
|
|
427
|
-
url=
|
|
428
|
-
title=
|
|
429
|
-
alt=
|
|
439
|
+
url=web_image[0][0][0],
|
|
440
|
+
title=web_image[7][0],
|
|
441
|
+
alt=web_image[0][4],
|
|
430
442
|
proxy=self.proxy,
|
|
431
443
|
)
|
|
432
|
-
for
|
|
444
|
+
for web_image in candidate[12][1]
|
|
433
445
|
]
|
|
434
446
|
or []
|
|
435
447
|
)
|
|
436
448
|
|
|
437
449
|
generated_images = []
|
|
438
450
|
if candidate[12] and candidate[12][7] and candidate[12][7][0]:
|
|
439
|
-
|
|
440
|
-
|
|
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
|
+
|
|
441
472
|
text = re.sub(
|
|
442
473
|
r"http://googleusercontent\.com/image_generation_content/\d+$",
|
|
443
474
|
"",
|
|
444
|
-
|
|
475
|
+
img_candidate[1][0],
|
|
445
476
|
).rstrip()
|
|
446
477
|
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
)
|
|
462
|
-
for i, image in enumerate(
|
|
463
|
-
image_generation_candidate[12][7][0]
|
|
464
|
-
)
|
|
465
|
-
]
|
|
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
|
+
]
|
|
466
492
|
|
|
467
493
|
candidates.append(
|
|
468
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.
|
|
@@ -44,3 +52,11 @@ class ModelInvalid(GeminiError):
|
|
|
44
52
|
"""
|
|
45
53
|
|
|
46
54
|
pass
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class TemporarilyBlocked(GeminiError):
|
|
58
|
+
"""
|
|
59
|
+
Exception for 429 Too Many Requests when IP is temporarily blocked.
|
|
60
|
+
"""
|
|
61
|
+
|
|
62
|
+
pass
|
|
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
|
{gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi/utils/load_browser_cookies.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gemini_webapi-1.11.0 → gemini_webapi-1.12.0}/src/gemini_webapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|