gemini-webapi 1.12.2__tar.gz → 1.13.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.12.2 → gemini_webapi-1.13.0}/PKG-INFO +8 -4
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/README.md +7 -3
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/__init__.py +1 -1
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/client.py +2 -2
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/constants.py +3 -3
- gemini_webapi-1.13.0/src/gemini_webapi/utils/logger.py +37 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/PKG-INFO +8 -4
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/SOURCES.txt +0 -1
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/tests/test_client_features.py +2 -4
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/tests/test_rotate_cookies.py +1 -3
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/tests/test_save_image.py +2 -3
- gemini_webapi-1.12.2/src/gemini_webapi/utils/logger.py +0 -39
- gemini_webapi-1.12.2/tests/test_html_entity_decode.py +0 -48
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.github/dependabot.yml +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.github/workflows/github-release.yml +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.github/workflows/pypi-publish.yml +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.gitignore +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.vscode/launch.json +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.vscode/settings.json +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/LICENSE +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/banner.png +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/favicon.png +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/logo.svg +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/sample.pdf +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/pyproject.toml +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/setup.cfg +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/exceptions.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/__init__.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/candidate.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/image.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/modeloutput.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/__init__.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/get_access_token.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/load_browser_cookies.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/rotate_1psidts.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/upload_file.py +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/dependency_links.txt +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/requires.txt +0 -0
- {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/top_level.txt +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gemini-webapi
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.13.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
|
|
@@ -736,7 +736,7 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
736
736
|
- [Generate images with Imagen3](#generate-images-with-imagen3)
|
|
737
737
|
- [Generate contents with Gemini extensions](#generate-contents-with-gemini-extensions)
|
|
738
738
|
- [Check and switch to other reply candidates](#check-and-switch-to-other-reply-candidates)
|
|
739
|
-
- [
|
|
739
|
+
- [Logging Configuration](#logging-configuration)
|
|
740
740
|
- [References](#references)
|
|
741
741
|
- [Stargazers](#stargazers)
|
|
742
742
|
|
|
@@ -1036,9 +1036,9 @@ async def main():
|
|
|
1036
1036
|
asyncio.run(main())
|
|
1037
1037
|
```
|
|
1038
1038
|
|
|
1039
|
-
###
|
|
1039
|
+
### Logging Configuration
|
|
1040
1040
|
|
|
1041
|
-
|
|
1041
|
+
This package uses [loguru](https://loguru.readthedocs.io/en/stable/) for logging, and exposes a function `set_log_level` to control log level. You can set log level to one of the following values: `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL`. The default value is `INFO`.
|
|
1042
1042
|
|
|
1043
1043
|
```python
|
|
1044
1044
|
from gemini_webapi import set_log_level
|
|
@@ -1046,6 +1046,10 @@ from gemini_webapi import set_log_level
|
|
|
1046
1046
|
set_log_level("DEBUG")
|
|
1047
1047
|
```
|
|
1048
1048
|
|
|
1049
|
+
> [!NOTE]
|
|
1050
|
+
>
|
|
1051
|
+
> Calling `set_log_level` for the first time will **globally** remove all existing loguru handlers. You may want to configure logging directly with loguru to avoid this issue and have more advanced control over logging behaviors.
|
|
1052
|
+
|
|
1049
1053
|
## References
|
|
1050
1054
|
|
|
1051
1055
|
[Google AI Studio](https://ai.google.dev/tutorials/ai-studio_quickstart)
|
|
@@ -53,7 +53,7 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
53
53
|
- [Generate images with Imagen3](#generate-images-with-imagen3)
|
|
54
54
|
- [Generate contents with Gemini extensions](#generate-contents-with-gemini-extensions)
|
|
55
55
|
- [Check and switch to other reply candidates](#check-and-switch-to-other-reply-candidates)
|
|
56
|
-
- [
|
|
56
|
+
- [Logging Configuration](#logging-configuration)
|
|
57
57
|
- [References](#references)
|
|
58
58
|
- [Stargazers](#stargazers)
|
|
59
59
|
|
|
@@ -353,9 +353,9 @@ async def main():
|
|
|
353
353
|
asyncio.run(main())
|
|
354
354
|
```
|
|
355
355
|
|
|
356
|
-
###
|
|
356
|
+
### Logging Configuration
|
|
357
357
|
|
|
358
|
-
|
|
358
|
+
This package uses [loguru](https://loguru.readthedocs.io/en/stable/) for logging, and exposes a function `set_log_level` to control log level. You can set log level to one of the following values: `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL`. The default value is `INFO`.
|
|
359
359
|
|
|
360
360
|
```python
|
|
361
361
|
from gemini_webapi import set_log_level
|
|
@@ -363,6 +363,10 @@ from gemini_webapi import set_log_level
|
|
|
363
363
|
set_log_level("DEBUG")
|
|
364
364
|
```
|
|
365
365
|
|
|
366
|
+
> [!NOTE]
|
|
367
|
+
>
|
|
368
|
+
> Calling `set_log_level` for the first time will **globally** remove all existing loguru handlers. You may want to configure logging directly with loguru to avoid this issue and have more advanced control over logging behaviors.
|
|
369
|
+
|
|
366
370
|
## References
|
|
367
371
|
|
|
368
372
|
[Google AI Studio](https://ai.google.dev/tutorials/ai-studio_quickstart)
|
|
@@ -422,7 +422,7 @@ class GeminiClient:
|
|
|
422
422
|
for candidate_index, candidate in enumerate(body[4]):
|
|
423
423
|
text = candidate[1][0]
|
|
424
424
|
if re.match(
|
|
425
|
-
r"^http://googleusercontent\.com/card_content/\d
|
|
425
|
+
r"^http://googleusercontent\.com/card_content/\d+", text
|
|
426
426
|
):
|
|
427
427
|
text = candidate[22] and candidate[22][0] or text
|
|
428
428
|
|
|
@@ -470,7 +470,7 @@ class GeminiClient:
|
|
|
470
470
|
img_candidate = img_body[4][candidate_index]
|
|
471
471
|
|
|
472
472
|
text = re.sub(
|
|
473
|
-
r"http://googleusercontent\.com/image_generation_content/\d
|
|
473
|
+
r"http://googleusercontent\.com/image_generation_content/\d+",
|
|
474
474
|
"",
|
|
475
475
|
img_candidate[1][0],
|
|
476
476
|
).rstrip()
|
|
@@ -27,7 +27,7 @@ class Model(Enum):
|
|
|
27
27
|
UNSPECIFIED = ("unspecified", {}, False)
|
|
28
28
|
G_2_5_FLASH = (
|
|
29
29
|
"gemini-2.5-flash",
|
|
30
|
-
{"x-goog-ext-525001261-jspb": '[1,null,null,null,"
|
|
30
|
+
{"x-goog-ext-525001261-jspb": '[1,null,null,null,"71c2d248d3b102ff"]'},
|
|
31
31
|
False,
|
|
32
32
|
)
|
|
33
33
|
G_2_5_PRO = (
|
|
@@ -49,12 +49,12 @@ class Model(Enum):
|
|
|
49
49
|
"gemini-2.0-exp-advanced",
|
|
50
50
|
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"b1e46a6037e6aa9f"]'},
|
|
51
51
|
True,
|
|
52
|
-
)
|
|
52
|
+
) # Deprecated
|
|
53
53
|
G_2_5_EXP_ADVANCED = (
|
|
54
54
|
"gemini-2.5-exp-advanced",
|
|
55
55
|
{"x-goog-ext-525001261-jspb": '[null,null,null,null,"203e6bb81620bcfe"]'},
|
|
56
56
|
True,
|
|
57
|
-
)
|
|
57
|
+
) # Deprecated
|
|
58
58
|
|
|
59
59
|
def __init__(self, name, header, advanced_only):
|
|
60
60
|
self.model_name = name
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
import sys
|
|
2
|
+
from loguru import logger as _logger
|
|
3
|
+
|
|
4
|
+
_handler_id = None
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
def set_log_level(level: str | int) -> None:
|
|
8
|
+
"""
|
|
9
|
+
Set the log level for gemini_webapi. The default log level is "INFO".
|
|
10
|
+
|
|
11
|
+
Note: calling this function for the first time will globally remove all existing loguru
|
|
12
|
+
handlers. To avoid this, you may want to set logging behaviors directly with loguru.
|
|
13
|
+
|
|
14
|
+
Parameters
|
|
15
|
+
----------
|
|
16
|
+
level : `str | int`
|
|
17
|
+
Log level: "TRACE", "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"
|
|
18
|
+
|
|
19
|
+
Examples
|
|
20
|
+
--------
|
|
21
|
+
>>> from gemini_webapi import set_log_level
|
|
22
|
+
>>> set_log_level("DEBUG") # Show debug messages
|
|
23
|
+
>>> set_log_level("ERROR") # Only show errors
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
global _handler_id
|
|
27
|
+
|
|
28
|
+
_logger.remove(_handler_id)
|
|
29
|
+
|
|
30
|
+
_handler_id = _logger.add(
|
|
31
|
+
sys.stderr,
|
|
32
|
+
level=level,
|
|
33
|
+
filter=lambda record: record["extra"].get("name") == "gemini_webapi",
|
|
34
|
+
)
|
|
35
|
+
|
|
36
|
+
|
|
37
|
+
logger = _logger.bind(name="gemini_webapi")
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: gemini-webapi
|
|
3
|
-
Version: 1.
|
|
3
|
+
Version: 1.13.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
|
|
@@ -736,7 +736,7 @@ A reverse-engineered asynchronous python wrapper for [Google Gemini](https://gem
|
|
|
736
736
|
- [Generate images with Imagen3](#generate-images-with-imagen3)
|
|
737
737
|
- [Generate contents with Gemini extensions](#generate-contents-with-gemini-extensions)
|
|
738
738
|
- [Check and switch to other reply candidates](#check-and-switch-to-other-reply-candidates)
|
|
739
|
-
- [
|
|
739
|
+
- [Logging Configuration](#logging-configuration)
|
|
740
740
|
- [References](#references)
|
|
741
741
|
- [Stargazers](#stargazers)
|
|
742
742
|
|
|
@@ -1036,9 +1036,9 @@ async def main():
|
|
|
1036
1036
|
asyncio.run(main())
|
|
1037
1037
|
```
|
|
1038
1038
|
|
|
1039
|
-
###
|
|
1039
|
+
### Logging Configuration
|
|
1040
1040
|
|
|
1041
|
-
|
|
1041
|
+
This package uses [loguru](https://loguru.readthedocs.io/en/stable/) for logging, and exposes a function `set_log_level` to control log level. You can set log level to one of the following values: `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL`. The default value is `INFO`.
|
|
1042
1042
|
|
|
1043
1043
|
```python
|
|
1044
1044
|
from gemini_webapi import set_log_level
|
|
@@ -1046,6 +1046,10 @@ from gemini_webapi import set_log_level
|
|
|
1046
1046
|
set_log_level("DEBUG")
|
|
1047
1047
|
```
|
|
1048
1048
|
|
|
1049
|
+
> [!NOTE]
|
|
1050
|
+
>
|
|
1051
|
+
> Calling `set_log_level` for the first time will **globally** remove all existing loguru handlers. You may want to configure logging directly with loguru to avoid this issue and have more advanced control over logging behaviors.
|
|
1052
|
+
|
|
1049
1053
|
## References
|
|
1050
1054
|
|
|
1051
1055
|
[Google AI Studio](https://ai.google.dev/tutorials/ai-studio_quickstart)
|
|
@@ -3,9 +3,7 @@ import unittest
|
|
|
3
3
|
import logging
|
|
4
4
|
from pathlib import Path
|
|
5
5
|
|
|
6
|
-
from
|
|
7
|
-
|
|
8
|
-
from gemini_webapi import GeminiClient, AuthError, set_log_level
|
|
6
|
+
from gemini_webapi import GeminiClient, AuthError, set_log_level, logger
|
|
9
7
|
from gemini_webapi.constants import Model
|
|
10
8
|
from gemini_webapi.exceptions import UsageLimitExceeded, ModelInvalid
|
|
11
9
|
|
|
@@ -20,7 +18,7 @@ class TestGeminiClient(unittest.IsolatedAsyncioTestCase):
|
|
|
20
18
|
)
|
|
21
19
|
|
|
22
20
|
try:
|
|
23
|
-
await self.geminiclient.init(timeout=60)
|
|
21
|
+
await self.geminiclient.init(timeout=60, auto_refresh=False)
|
|
24
22
|
except AuthError as e:
|
|
25
23
|
self.skipTest(e)
|
|
26
24
|
|
|
@@ -3,9 +3,8 @@ import unittest
|
|
|
3
3
|
import logging
|
|
4
4
|
|
|
5
5
|
from httpx import HTTPError
|
|
6
|
-
from loguru import logger
|
|
7
6
|
|
|
8
|
-
from gemini_webapi import GeminiClient, AuthError, set_log_level
|
|
7
|
+
from gemini_webapi import GeminiClient, AuthError, set_log_level, logger
|
|
9
8
|
|
|
10
9
|
logging.getLogger("asyncio").setLevel(logging.ERROR)
|
|
11
10
|
set_log_level("DEBUG")
|
|
@@ -18,7 +17,7 @@ class TestGeminiClient(unittest.IsolatedAsyncioTestCase):
|
|
|
18
17
|
)
|
|
19
18
|
|
|
20
19
|
try:
|
|
21
|
-
await self.geminiclient.init()
|
|
20
|
+
await self.geminiclient.init(auto_refresh=False)
|
|
22
21
|
except AuthError:
|
|
23
22
|
self.skipTest("Test was skipped due to invalid cookies")
|
|
24
23
|
|
|
@@ -1,39 +0,0 @@
|
|
|
1
|
-
import atexit
|
|
2
|
-
from sys import stderr
|
|
3
|
-
|
|
4
|
-
from loguru._logger import Core as _Core
|
|
5
|
-
from loguru._logger import Logger as _Logger
|
|
6
|
-
|
|
7
|
-
logger = _Logger(
|
|
8
|
-
core=_Core(),
|
|
9
|
-
exception=None,
|
|
10
|
-
depth=0,
|
|
11
|
-
record=False,
|
|
12
|
-
lazy=False,
|
|
13
|
-
colors=False,
|
|
14
|
-
raw=False,
|
|
15
|
-
capture=True,
|
|
16
|
-
patchers=[],
|
|
17
|
-
extra={},
|
|
18
|
-
)
|
|
19
|
-
|
|
20
|
-
if stderr:
|
|
21
|
-
logger.add(stderr, level="INFO")
|
|
22
|
-
|
|
23
|
-
atexit.register(logger.remove)
|
|
24
|
-
|
|
25
|
-
|
|
26
|
-
def set_log_level(level: str):
|
|
27
|
-
"""
|
|
28
|
-
Set the log level for the whole module. Default is "INFO". Set to "DEBUG" to see more detailed logs.
|
|
29
|
-
|
|
30
|
-
Parameters
|
|
31
|
-
----------
|
|
32
|
-
level : str
|
|
33
|
-
The log level to set. Must be one of "DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL".
|
|
34
|
-
"""
|
|
35
|
-
|
|
36
|
-
assert level in ["DEBUG", "INFO", "WARNING", "ERROR", "CRITICAL"]
|
|
37
|
-
|
|
38
|
-
logger.remove()
|
|
39
|
-
logger.add(stderr, level=level)
|
|
@@ -1,48 +0,0 @@
|
|
|
1
|
-
import unittest
|
|
2
|
-
from gemini_webapi.types.candidate import Candidate
|
|
3
|
-
|
|
4
|
-
|
|
5
|
-
class TestHtmlEntityDecode(unittest.TestCase):
|
|
6
|
-
def test_html_entity_decoding(self):
|
|
7
|
-
# Test HTML entity decoding functionality
|
|
8
|
-
html_encoded_text = (
|
|
9
|
-
"This is a code snippet: <code>print('Hello, World!')</code>"
|
|
10
|
-
)
|
|
11
|
-
expected_decoded_text = (
|
|
12
|
-
"This is a code snippet: <code>print('Hello, World!')</code>"
|
|
13
|
-
)
|
|
14
|
-
|
|
15
|
-
# Create Candidate instance which should automatically decode HTML entities
|
|
16
|
-
candidate = Candidate(
|
|
17
|
-
rcid="test_rcid",
|
|
18
|
-
text=html_encoded_text,
|
|
19
|
-
thoughts="Testing <b>HTML</b> entity decoding",
|
|
20
|
-
)
|
|
21
|
-
|
|
22
|
-
# Verify that text property is correctly decoded
|
|
23
|
-
self.assertEqual(candidate.text, expected_decoded_text)
|
|
24
|
-
|
|
25
|
-
# Verify that thoughts property is correctly decoded
|
|
26
|
-
self.assertEqual(candidate.thoughts, "Testing <b>HTML</b> entity decoding")
|
|
27
|
-
|
|
28
|
-
def test_non_html_text(self):
|
|
29
|
-
# Test plain text without any HTML entities
|
|
30
|
-
plain_text = "This is regular text with no HTML entities"
|
|
31
|
-
|
|
32
|
-
candidate = Candidate(rcid="test_rcid", text=plain_text)
|
|
33
|
-
|
|
34
|
-
# Verify the text remains unchanged
|
|
35
|
-
self.assertEqual(candidate.text, plain_text)
|
|
36
|
-
|
|
37
|
-
def test_complex_html_entities(self):
|
|
38
|
-
# Test more complex combinations of HTML entities
|
|
39
|
-
complex_html = "<div>This has &amp; character\n and "quotes"</div>"
|
|
40
|
-
expected_decoded = '<div>This has & character\n and "quotes"</div>'
|
|
41
|
-
|
|
42
|
-
candidate = Candidate(rcid="test_rcid", text=complex_html)
|
|
43
|
-
|
|
44
|
-
self.assertEqual(candidate.text, expected_decoded)
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
if __name__ == "__main__":
|
|
48
|
-
unittest.main()
|
|
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.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/load_browser_cookies.py
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|
{gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/dependency_links.txt
RENAMED
|
File without changes
|
|
File without changes
|
|
File without changes
|