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.
Files changed (39) hide show
  1. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/PKG-INFO +8 -4
  2. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/README.md +7 -3
  3. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/__init__.py +1 -1
  4. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/client.py +2 -2
  5. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/constants.py +3 -3
  6. gemini_webapi-1.13.0/src/gemini_webapi/utils/logger.py +37 -0
  7. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/PKG-INFO +8 -4
  8. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/SOURCES.txt +0 -1
  9. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/tests/test_client_features.py +2 -4
  10. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/tests/test_rotate_cookies.py +1 -3
  11. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/tests/test_save_image.py +2 -3
  12. gemini_webapi-1.12.2/src/gemini_webapi/utils/logger.py +0 -39
  13. gemini_webapi-1.12.2/tests/test_html_entity_decode.py +0 -48
  14. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.github/dependabot.yml +0 -0
  15. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.github/workflows/github-release.yml +0 -0
  16. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.github/workflows/pypi-publish.yml +0 -0
  17. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.gitignore +0 -0
  18. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.vscode/launch.json +0 -0
  19. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/.vscode/settings.json +0 -0
  20. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/LICENSE +0 -0
  21. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/banner.png +0 -0
  22. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/favicon.png +0 -0
  23. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/logo.svg +0 -0
  24. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/assets/sample.pdf +0 -0
  25. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/pyproject.toml +0 -0
  26. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/setup.cfg +0 -0
  27. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/exceptions.py +0 -0
  28. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/__init__.py +0 -0
  29. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/candidate.py +0 -0
  30. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/image.py +0 -0
  31. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/types/modeloutput.py +0 -0
  32. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/__init__.py +0 -0
  33. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/get_access_token.py +0 -0
  34. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/load_browser_cookies.py +0 -0
  35. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/rotate_1psidts.py +0 -0
  36. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi/utils/upload_file.py +0 -0
  37. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/dependency_links.txt +0 -0
  38. {gemini_webapi-1.12.2 → gemini_webapi-1.13.0}/src/gemini_webapi.egg-info/requires.txt +0 -0
  39. {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.12.2
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
- - [Control log level](#control-log-level)
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
- ### Control log level
1039
+ ### Logging Configuration
1040
1040
 
1041
- You can set the log level of the package to one of the following values: `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL`. The default value is `INFO`.
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
- - [Control log level](#control-log-level)
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
- ### Control log level
356
+ ### Logging Configuration
357
357
 
358
- You can set the log level of the package to one of the following values: `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL`. The default value is `INFO`.
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)
@@ -1,4 +1,4 @@
1
1
  from .client import GeminiClient, ChatSession # noqa: F401
2
2
  from .exceptions import * # noqa: F401, F403
3
3
  from .types import * # noqa: F401, F403
4
- from .utils import set_log_level # noqa: F401
4
+ from .utils import set_log_level, logger # noqa: F401
@@ -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+$", text
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,"9ec249fc9ad08861"]'},
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.12.2
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
- - [Control log level](#control-log-level)
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
- ### Control log level
1039
+ ### Logging Configuration
1040
1040
 
1041
- You can set the log level of the package to one of the following values: `DEBUG`, `INFO`, `WARNING`, `ERROR` and `CRITICAL`. The default value is `INFO`.
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)
@@ -31,6 +31,5 @@ src/gemini_webapi/utils/logger.py
31
31
  src/gemini_webapi/utils/rotate_1psidts.py
32
32
  src/gemini_webapi/utils/upload_file.py
33
33
  tests/test_client_features.py
34
- tests/test_html_entity_decode.py
35
34
  tests/test_rotate_cookies.py
36
35
  tests/test_save_image.py
@@ -3,9 +3,7 @@ import unittest
3
3
  import logging
4
4
  from pathlib import Path
5
5
 
6
- from loguru import logger
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
 
@@ -1,9 +1,7 @@
1
1
  import os
2
2
  import asyncio
3
3
 
4
- from loguru import logger
5
-
6
- from gemini_webapi import GeminiClient, set_log_level
4
+ from gemini_webapi import GeminiClient, set_log_level, logger
7
5
 
8
6
  set_log_level("DEBUG")
9
7
 
@@ -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 &lt;b&gt;HTML&lt;/b&gt; 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 = "&lt;div&gt;This has &amp;amp; character\n and &quot;quotes&quot;&lt;/div&gt;"
40
- expected_decoded = '<div>This has &amp; 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