gemini-webapi 1.17.1__py3-none-any.whl → 1.17.2__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
@@ -68,7 +68,7 @@ class GeminiClient(GemMixin):
68
68
  __slots__ = [
69
69
  "cookies",
70
70
  "proxy",
71
- "running",
71
+ "_running",
72
72
  "client",
73
73
  "access_token",
74
74
  "timeout",
@@ -91,7 +91,7 @@ class GeminiClient(GemMixin):
91
91
  super().__init__()
92
92
  self.cookies = {}
93
93
  self.proxy = proxy
94
- self.running: bool = False
94
+ self._running: bool = False
95
95
  self.client: AsyncClient | None = None
96
96
  self.access_token: str | None = None
97
97
  self.timeout: float = 300
@@ -152,7 +152,7 @@ class GeminiClient(GemMixin):
152
152
  )
153
153
  self.access_token = access_token
154
154
  self.cookies = valid_cookies
155
- self.running = True
155
+ self._running = True
156
156
 
157
157
  self.timeout = timeout
158
158
  self.auto_close = auto_close
@@ -188,7 +188,7 @@ class GeminiClient(GemMixin):
188
188
  if delay:
189
189
  await asyncio.sleep(delay)
190
190
 
191
- self.running = False
191
+ self._running = False
192
192
 
193
193
  if self.close_task:
194
194
  self.close_task.cancel()
@@ -229,7 +229,7 @@ class GeminiClient(GemMixin):
229
229
 
230
230
  if new_1psidts:
231
231
  self.cookies["__Secure-1PSIDTS"] = new_1psidts
232
- if self.running:
232
+ if self._running:
233
233
  self.client.cookies.set("__Secure-1PSIDTS", new_1psidts)
234
234
  logger.debug("Cookies refreshed. New __Secure-1PSIDTS applied.")
235
235
 
@@ -380,7 +380,7 @@ class GeminiClient(GemMixin):
380
380
 
381
381
  try:
382
382
  error_code = get_nested_value(response_json, [0, 5, 2, 0, 1, 0], -1)
383
- match ErrorCode(error_code):
383
+ match error_code:
384
384
  case ErrorCode.USAGE_LIMIT_EXCEEDED:
385
385
  raise UsageLimitExceeded(
386
386
  f"Failed to generate contents. Usage limit of {model.model_name} model has exceeded. Please try switching to another model."
@@ -71,9 +71,10 @@ class Image(BaseModel):
71
71
  """
72
72
 
73
73
  filename = filename or self.url.split("/")[-1].split("?")[0]
74
- try:
75
- filename = re.search(r"^(.*\.\w+)", filename).group()
76
- except AttributeError:
74
+ match = re.search(r"^(.*\.\w+)", filename)
75
+ if match:
76
+ filename = match.group()
77
+ else:
77
78
  if verbose:
78
79
  logger.warning(f"Invalid filename: {filename}")
79
80
  if skip_invalid_filename:
@@ -137,19 +138,33 @@ class GeneratedImage(Image):
137
138
  return v
138
139
 
139
140
  # @override
140
- async def save(self, full_size=True, **kwargs) -> str | None:
141
+ async def save(
142
+ self,
143
+ path: str = "temp",
144
+ filename: str | None = None,
145
+ cookies: dict | None = None,
146
+ verbose: bool = False,
147
+ skip_invalid_filename: bool = False,
148
+ full_size: bool = True,
149
+ ) -> str | None:
141
150
  """
142
151
  Save the image to disk.
143
152
 
144
153
  Parameters
145
154
  ----------
155
+ path: `str`, optional
156
+ Path to save the image, by default will save to "./temp".
146
157
  filename: `str`, optional
147
158
  Filename to save the image, generated images are always in .png format, but file extension will not be included in the URL.
148
159
  And since the URL ends with a long hash, by default will use timestamp + end of the hash as the filename.
160
+ cookies: `dict`, optional
161
+ Cookies used for requesting the content of the image. If not provided, will use the cookies from the GeneratedImage instance.
162
+ verbose : `bool`, optional
163
+ If True, will print the path of the saved file or warning for invalid file name, by default False.
164
+ skip_invalid_filename: `bool`, optional
165
+ If True, will only save the image if the file name and extension are valid, by default False.
149
166
  full_size: `bool`, optional
150
- If True, will modify the default preview (512*512) URL to get the full size image.
151
- kwargs: `dict`, optional
152
- Other arguments to pass to `Image.save`.
167
+ If True, will modify the default preview (512*512) URL to get the full size image, by default True.
153
168
 
154
169
  Returns
155
170
  -------
@@ -161,8 +176,10 @@ class GeneratedImage(Image):
161
176
  self.url += "=s2048"
162
177
 
163
178
  return await super().save(
164
- filename=kwargs.pop("filename", None)
179
+ path=path,
180
+ filename=filename
165
181
  or f"{datetime.now().strftime('%Y%m%d%H%M%S')}_{self.url[-10:]}.png",
166
- cookies=self.cookies,
167
- **kwargs,
182
+ cookies=cookies or self.cookies,
183
+ verbose=verbose,
184
+ skip_invalid_filename=skip_invalid_filename,
168
185
  )
@@ -1,10 +1,11 @@
1
1
  import asyncio
2
2
  import functools
3
+ from collections.abc import Callable
3
4
 
4
5
  from ..exceptions import APIError, ImageGenerationError
5
6
 
6
7
 
7
- def running(retry: int = 0) -> callable:
8
+ def running(retry: int = 0) -> Callable:
8
9
  """
9
10
  Decorator to check if GeminiClient is running before making a request.
10
11
 
@@ -18,7 +19,7 @@ def running(retry: int = 0) -> callable:
18
19
  @functools.wraps(func)
19
20
  async def wrapper(client, *args, retry=retry, **kwargs):
20
21
  try:
21
- if not client.running:
22
+ if not client._running:
22
23
  await client.init(
23
24
  timeout=client.timeout,
24
25
  auto_close=client.auto_close,
@@ -27,7 +28,7 @@ def running(retry: int = 0) -> callable:
27
28
  refresh_interval=client.refresh_interval,
28
29
  verbose=False,
29
30
  )
30
- if client.running:
31
+ if client._running:
31
32
  return await func(client, *args, **kwargs)
32
33
 
33
34
  # Should not reach here
@@ -30,8 +30,8 @@ def get_nested_value(data: list, path: list[int], default: Any = None) -> Any:
30
30
  current_repr = f"{current_repr[:197]}..."
31
31
 
32
32
  logger.debug(
33
- f"{type(e).__name__}: parsing failed at path {path} (index {i}, key '{key}') "
34
- f"while attempting to get value from `{current_repr}`"
33
+ f"Safe navigation: path {path} ended at index {i} (key '{key}'), "
34
+ f"returning default. <Debug: {type(e).__name__}; Context: {current_repr}>"
35
35
  )
36
36
  return default
37
37
 
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemini-webapi
3
- Version: 1.17.1
3
+ Version: 1.17.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
@@ -1,5 +1,5 @@
1
1
  gemini_webapi/__init__.py,sha256=7ELCiUoI10ea3daeJxnv0UwqLVKpM7rxsgOZsPMstO8,150
2
- gemini_webapi/client.py,sha256=zcsJHaZAi_lOIOtwQ-6PqS2S6-8m_Jt3rZRK7cH0EBQ,29288
2
+ gemini_webapi/client.py,sha256=6A1K6Tq1cXdW_RGwLIFtDE0jhS1WAtrGvGqAY5-FREc,29282
3
3
  gemini_webapi/constants.py,sha256=tm9y8oKuD3QhKXUbVXZKroYCoPpqgBJdSTwoeue43Ss,3295
4
4
  gemini_webapi/exceptions.py,sha256=qkXrIpr0L7LtGbq3VcTO8D1xZ50pJtt0dDRp5I3uDSg,1038
5
5
  gemini_webapi/components/__init__.py,sha256=wolxuAJJ32-jmHOKgpsesexP7hXea1JMo5vI52wysTI,48
@@ -8,18 +8,18 @@ gemini_webapi/types/__init__.py,sha256=1DU4JEw2KHQJbtOgOuvoEXtzQCMwAkyo0koSFVdT9
8
8
  gemini_webapi/types/candidate.py,sha256=67BhY75toE5mVuB21cmHcTFtw332V_KmCjr3-9VTbJo,1477
9
9
  gemini_webapi/types/gem.py,sha256=3Ppjq9V22Zp4Lb9a9ZnDviDKQpfSQf8UZxqOEjeEWd4,4070
10
10
  gemini_webapi/types/grpc.py,sha256=S64h1oeC7ZJC50kmS_C2CQ7WVTanhJ4kqTFx5ZYayXI,917
11
- gemini_webapi/types/image.py,sha256=NhW1QY2Agzb6UbrIjZLnqxqukabDSGbmoCsVguzko10,5395
11
+ gemini_webapi/types/image.py,sha256=JotV2FA8XdIKPHCRIExEOwnE-167AQ-Qoy3bIIREvw4,6185
12
12
  gemini_webapi/types/modeloutput.py,sha256=h07kQOkL5r-oPLvZ59uVtO1eP4FGy5ZpzuYQzAeQdr8,1196
13
13
  gemini_webapi/utils/__init__.py,sha256=k8hV2zn6tD_BEpd1Xya6ED0deijsmzb1e9XxdFhJzIE,418
14
- gemini_webapi/utils/decorators.py,sha256=AuY6sU1_6_ZqeL92dTAi3eRPQ7zubB5VuBZEiz16aBM,1741
14
+ gemini_webapi/utils/decorators.py,sha256=uzIXoZOC0_Om19bbVXf_nw2w2NhI2qJL1o45FU6o6fI,1780
15
15
  gemini_webapi/utils/get_access_token.py,sha256=VjrHW8VMN3LPs6zCdXQtraWygurOjTY0SJZhe49aQwc,7265
16
16
  gemini_webapi/utils/load_browser_cookies.py,sha256=OHCfe27DpV_rloIDgW9Xpeb0mkfzbYONNiholw0ElXU,1791
17
17
  gemini_webapi/utils/logger.py,sha256=0VcxhVLhHBRDQutNCpapP1y_MhPoQ2ud1uIFLqxC3Z8,958
18
- gemini_webapi/utils/parsing.py,sha256=z-t0bDbXVIa0-3_ZmTK19PvL6zBM5vuy56z2jv1Yu1I,2105
18
+ gemini_webapi/utils/parsing.py,sha256=CJPf7V0R_EJz1srrbVQBuOOQkLFyZovqLOHwEFYbSbY,2113
19
19
  gemini_webapi/utils/rotate_1psidts.py,sha256=XjEeQnZS3ZI6wOl0Zb5CvsbIrg0BVVNas7cE6f3x_XE,1802
20
20
  gemini_webapi/utils/upload_file.py,sha256=SJOMr6kryK_ClrKmqI96fqZBNFOMPsyAvFINAGAU3rk,1468
21
- gemini_webapi-1.17.1.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
22
- gemini_webapi-1.17.1.dist-info/METADATA,sha256=OlCVaM8XIgS_w6zxowLrxLxc5ksPf-3W27oodzH2_MM,61763
23
- gemini_webapi-1.17.1.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
- gemini_webapi-1.17.1.dist-info/top_level.txt,sha256=dtWtug_ZrmnUqCYuu8NmGzTgWglHeNzhHU_hXmqZGWE,14
25
- gemini_webapi-1.17.1.dist-info/RECORD,,
21
+ gemini_webapi-1.17.2.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
22
+ gemini_webapi-1.17.2.dist-info/METADATA,sha256=PgjuOn0s9cY4sccrBUAglaLxu-SSaefZbQRnyzOc1Cg,61763
23
+ gemini_webapi-1.17.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
24
+ gemini_webapi-1.17.2.dist-info/top_level.txt,sha256=dtWtug_ZrmnUqCYuu8NmGzTgWglHeNzhHU_hXmqZGWE,14
25
+ gemini_webapi-1.17.2.dist-info/RECORD,,