gemini-webapi 1.14.2__py3-none-any.whl → 1.14.4__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
@@ -1,14 +1,13 @@
1
1
  import asyncio
2
- import functools
3
- import itertools
4
2
  import re
5
3
  from asyncio import Task
6
4
  from pathlib import Path
7
5
  from typing import Any, Optional
8
6
 
9
7
  import orjson as json
10
- from httpx import AsyncClient, ReadTimeout
8
+ from httpx import AsyncClient, ReadTimeout, Response
11
9
 
10
+ from .components import GemMixin
12
11
  from .constants import Endpoint, ErrorCode, Headers, Model
13
12
  from .exceptions import (
14
13
  AuthError,
@@ -20,67 +19,27 @@ from .exceptions import (
20
19
  ModelInvalid,
21
20
  TemporarilyBlocked,
22
21
  )
23
- from .types import WebImage, GeneratedImage, Candidate, ModelOutput, Gem, GemJar
22
+ from .types import (
23
+ WebImage,
24
+ GeneratedImage,
25
+ Candidate,
26
+ ModelOutput,
27
+ Gem,
28
+ RPCData,
29
+ )
24
30
  from .utils import (
25
31
  upload_file,
26
32
  parse_file_name,
27
33
  rotate_1psidts,
28
34
  get_access_token,
29
35
  load_browser_cookies,
36
+ running,
30
37
  rotate_tasks,
31
38
  logger,
32
39
  )
33
40
 
34
41
 
35
- def running(retry: int = 0) -> callable:
36
- """
37
- Decorator to check if client is running before making a request.
38
-
39
- Parameters
40
- ----------
41
- retry: `int`, optional
42
- Max number of retries when `gemini_webapi.APIError` is raised.
43
- """
44
-
45
- def decorator(func):
46
- @functools.wraps(func)
47
- async def wrapper(client: "GeminiClient", *args, retry=retry, **kwargs):
48
- try:
49
- if not client.running:
50
- await client.init(
51
- timeout=client.timeout,
52
- auto_close=client.auto_close,
53
- close_delay=client.close_delay,
54
- auto_refresh=client.auto_refresh,
55
- refresh_interval=client.refresh_interval,
56
- verbose=False,
57
- )
58
- if client.running:
59
- return await func(client, *args, **kwargs)
60
-
61
- # Should not reach here
62
- raise APIError(
63
- f"Invalid function call: GeminiClient.{func.__name__}. Client initialization failed."
64
- )
65
- else:
66
- return await func(client, *args, **kwargs)
67
- except APIError as e:
68
- # Image generation takes too long, only retry once
69
- if isinstance(e, ImageGenerationError):
70
- retry = min(1, retry)
71
-
72
- if retry > 0:
73
- await asyncio.sleep(1)
74
- return await wrapper(client, *args, retry=retry - 1, **kwargs)
75
-
76
- raise
77
-
78
- return wrapper
79
-
80
- return decorator
81
-
82
-
83
- class GeminiClient:
42
+ class GeminiClient(GemMixin):
84
43
  """
85
44
  Async httpx client interface for gemini.google.com.
86
45
 
@@ -117,7 +76,7 @@ class GeminiClient:
117
76
  "close_task",
118
77
  "auto_refresh",
119
78
  "refresh_interval",
120
- "_gems",
79
+ "_gems", # From GemMixin
121
80
  "kwargs",
122
81
  ]
123
82
 
@@ -128,6 +87,7 @@ class GeminiClient:
128
87
  proxy: str | None = None,
129
88
  **kwargs,
130
89
  ):
90
+ super().__init__()
131
91
  self.cookies = {}
132
92
  self.proxy = proxy
133
93
  self.running: bool = False
@@ -139,7 +99,6 @@ class GeminiClient:
139
99
  self.close_task: Task | None = None
140
100
  self.auto_refresh: bool = True
141
101
  self.refresh_interval: float = 540
142
- self._gems: GemJar | None = None
143
102
  self.kwargs = kwargs
144
103
 
145
104
  # Validate cookies
@@ -277,125 +236,6 @@ class GeminiClient:
277
236
  self.cookies["__Secure-1PSIDTS"] = new_1psidts
278
237
  await asyncio.sleep(self.refresh_interval)
279
238
 
280
- @property
281
- def gems(self) -> GemJar:
282
- """
283
- Returns a `GemJar` object containing cached gems.
284
- Only available after calling `GeminiClient.fetch_gems()`.
285
-
286
- Returns
287
- -------
288
- :class:`GemJar`
289
- Refer to `gemini_webapi.types.GemJar`.
290
-
291
- Raises
292
- ------
293
- `RuntimeError`
294
- If `GeminiClient.fetch_gems()` has not been called before accessing this property.
295
- """
296
-
297
- if self._gems is None:
298
- raise RuntimeError(
299
- "Gems not fetched yet. Call `GeminiClient.fetch_gems()` method to fetch gems from gemini.google.com."
300
- )
301
-
302
- return self._gems
303
-
304
- @running(retry=2)
305
- async def fetch_gems(self, **kwargs) -> GemJar:
306
- """
307
- Get a list of available gems from gemini, including system predefined gems and user-created custom gems.
308
-
309
- Note that network request will be sent every time this method is called.
310
- Once the gems are fetched, they will be cached and accessible via `GeminiClient.gems` property.
311
-
312
- Returns
313
- -------
314
- :class:`GemJar`
315
- Refer to `gemini_webapi.types.GemJar`.
316
- """
317
-
318
- try:
319
- response = await self.client.post(
320
- Endpoint.BATCH_EXEC,
321
- data={
322
- "at": self.access_token,
323
- "f.req": json.dumps(
324
- [
325
- [
326
- ["CNgdBe", '[2,["en"],0]', None, "custom"],
327
- ["CNgdBe", '[3,["en"],0]', None, "system"],
328
- ]
329
- ]
330
- ).decode(),
331
- },
332
- **kwargs,
333
- )
334
- except ReadTimeout:
335
- raise TimeoutError(
336
- "Fetch gems request timed out, please try again. If the problem persists, "
337
- "consider setting a higher `timeout` value when initializing GeminiClient."
338
- )
339
-
340
- if response.status_code != 200:
341
- raise APIError(
342
- f"Failed to fetch gems. Request failed with status code {response.status_code}"
343
- )
344
- else:
345
- try:
346
- response_json = json.loads(response.text.split("\n")[2])
347
-
348
- predefined_gems, custom_gems = [], []
349
-
350
- for part in response_json:
351
- if part[-1] == "system":
352
- predefined_gems = json.loads(part[2])[2]
353
- elif part[-1] == "custom":
354
- if custom_gems_container := json.loads(part[2]):
355
- custom_gems = custom_gems_container[2]
356
-
357
- if not predefined_gems and not custom_gems:
358
- raise Exception
359
- except Exception:
360
- await self.close()
361
- logger.debug(f"Invalid response: {response.text}")
362
- raise APIError(
363
- "Failed to fetch gems. Invalid response data received. Client will try to re-initialize on next request."
364
- )
365
-
366
- self._gems = GemJar(
367
- itertools.chain(
368
- (
369
- (
370
- gem[0],
371
- Gem(
372
- id=gem[0],
373
- name=gem[1][0],
374
- description=gem[1][1],
375
- prompt=gem[2] and gem[2][0] or None,
376
- predefined=True,
377
- ),
378
- )
379
- for gem in predefined_gems
380
- ),
381
- (
382
- (
383
- gem[0],
384
- Gem(
385
- id=gem[0],
386
- name=gem[1][0],
387
- description=gem[1][1],
388
- prompt=gem[2] and gem[2][0] or None,
389
- predefined=False,
390
- ),
391
- )
392
- for gem in custom_gems
393
- ),
394
- )
395
- )
396
-
397
- return self._gems
398
-
399
239
  @running(retry=2)
400
240
  async def generate_content(
401
241
  self,
@@ -609,10 +449,21 @@ class GeminiClient:
609
449
  generated_images = [
610
450
  GeneratedImage(
611
451
  url=generated_image[0][3][3],
612
- title=f"[Generated Image {generated_image[3][6]}]",
613
- alt=len(generated_image[3][5]) > image_index
614
- and generated_image[3][5][image_index]
615
- or generated_image[3][5][0],
452
+ title=(
453
+ f"[Generated Image {generated_image[3][6]}]"
454
+ if generated_image[3][6]
455
+ else "[Generated Image]"
456
+ ),
457
+ alt=(
458
+ generated_image[3][5][image_index]
459
+ if generated_image[3][5]
460
+ and len(generated_image[3][5]) > image_index
461
+ else (
462
+ generated_image[3][5][0]
463
+ if generated_image[3][5]
464
+ else ""
465
+ )
466
+ ),
616
467
  proxy=self.proxy,
617
468
  cookies=self.cookies,
618
469
  )
@@ -665,6 +516,53 @@ class GeminiClient:
665
516
 
666
517
  return ChatSession(geminiclient=self, **kwargs)
667
518
 
519
+ async def _batch_execute(self, payloads: list[RPCData], **kwargs) -> Response:
520
+ """
521
+ Execute a batch of requests to Gemini API.
522
+
523
+ Parameters
524
+ ----------
525
+ payloads: `list[GRPC]`
526
+ List of `gemini_webapi.types.GRPC` objects to be executed.
527
+ kwargs: `dict`, optional
528
+ Additional arguments which will be passed to the post request.
529
+ Refer to `httpx.AsyncClient.request` for more information.
530
+
531
+ Returns
532
+ -------
533
+ :class:`httpx.Response`
534
+ Response object containing the result of the batch execution.
535
+ """
536
+
537
+ try:
538
+ response = await self.client.post(
539
+ Endpoint.BATCH_EXEC,
540
+ data={
541
+ "at": self.access_token,
542
+ "f.req": json.dumps(
543
+ [[payload.serialize() for payload in payloads]]
544
+ ).decode(),
545
+ },
546
+ **kwargs,
547
+ )
548
+ except ReadTimeout:
549
+ raise TimeoutError(
550
+ "Batch execute request timed out, please try again. If the problem persists, "
551
+ "consider setting a higher `timeout` value when initializing GeminiClient."
552
+ )
553
+
554
+ if response.status_code != 200:
555
+ logger.debug(
556
+ f"Batch execution failed with status code {response.status_code}. "
557
+ f"RPC: {', '.join({payload.rpcid.name for payload in payloads})}; "
558
+ f"Invalid response: {response.text}"
559
+ )
560
+ raise APIError(
561
+ f"Batch execution failed with status code {response.status_code}"
562
+ )
563
+
564
+ return response
565
+
668
566
 
669
567
  class ChatSession:
670
568
  """
@@ -0,0 +1,3 @@
1
+ # flake8: noqa
2
+
3
+ from .gem_mixin import GemMixin
@@ -0,0 +1,151 @@
1
+ import itertools
2
+
3
+ import orjson as json
4
+
5
+ from ..constants import GRPC
6
+ from ..exceptions import APIError
7
+ from ..types import Gem, GemJar, RPCData
8
+ from ..utils import running, logger
9
+
10
+
11
+ class GemMixin:
12
+ """
13
+ Mixin class providing gem-related functionality for GeminiClient.
14
+ """
15
+
16
+ def __init__(self, *args, **kwargs):
17
+ super().__init__(*args, **kwargs)
18
+ self._gems: GemJar | None = None
19
+
20
+ @property
21
+ def gems(self) -> GemJar:
22
+ """
23
+ Returns a `GemJar` object containing cached gems.
24
+ Only available after calling `GeminiClient.fetch_gems()`.
25
+
26
+ Returns
27
+ -------
28
+ :class:`GemJar`
29
+ Refer to `gemini_webapi.types.GemJar`.
30
+
31
+ Raises
32
+ ------
33
+ `RuntimeError`
34
+ If `GeminiClient.fetch_gems()` has not been called before accessing this property.
35
+ """
36
+
37
+ if self._gems is None:
38
+ raise RuntimeError(
39
+ "Gems not fetched yet. Call `GeminiClient.fetch_gems()` method to fetch gems from gemini.google.com."
40
+ )
41
+
42
+ return self._gems
43
+
44
+ @running(retry=2)
45
+ async def fetch_gems(self, include_hidden: bool = False, **kwargs) -> GemJar:
46
+ """
47
+ Get a list of available gems from gemini, including system predefined gems and user-created custom gems.
48
+
49
+ Note that network request will be sent every time this method is called.
50
+ Once the gems are fetched, they will be cached and accessible via `GeminiClient.gems` property.
51
+
52
+ Parameters
53
+ ----------
54
+ include_hidden: `bool`, optional
55
+ There are some predefined gems that by default are not shown to users (and therefore may not work properly).
56
+ Set this parameter to `True` to include them in the fetched gem list.
57
+
58
+ Returns
59
+ -------
60
+ :class:`GemJar`
61
+ Refer to `gemini_webapi.types.GemJar`.
62
+ """
63
+
64
+ response = await self._batch_execute(
65
+ [
66
+ RPCData(
67
+ rpcid=GRPC.LIST_GEMS,
68
+ payload="[4]" if include_hidden else "[3]",
69
+ identifier="system",
70
+ ),
71
+ RPCData(
72
+ rpcid=GRPC.LIST_GEMS,
73
+ payload="[2]",
74
+ identifier="custom",
75
+ ),
76
+ ],
77
+ **kwargs,
78
+ )
79
+
80
+ try:
81
+ response_json = json.loads(response.text.split("\n")[2])
82
+
83
+ predefined_gems, custom_gems = [], []
84
+
85
+ for part in response_json:
86
+ if part[-1] == "system":
87
+ predefined_gems = json.loads(part[2])[2]
88
+ elif part[-1] == "custom":
89
+ if custom_gems_container := json.loads(part[2]):
90
+ custom_gems = custom_gems_container[2]
91
+
92
+ if not predefined_gems and not custom_gems:
93
+ raise Exception
94
+ except Exception:
95
+ await self.close()
96
+ logger.debug(f"Invalid response: {response.text}")
97
+ raise APIError(
98
+ "Failed to fetch gems. Invalid response data received. Client will try to re-initialize on next request."
99
+ )
100
+
101
+ self._gems = GemJar(
102
+ itertools.chain(
103
+ (
104
+ (
105
+ gem[0],
106
+ Gem(
107
+ id=gem[0],
108
+ name=gem[1][0],
109
+ description=gem[1][1],
110
+ prompt=gem[2] and gem[2][0] or None,
111
+ predefined=True,
112
+ ),
113
+ )
114
+ for gem in predefined_gems
115
+ ),
116
+ (
117
+ (
118
+ gem[0],
119
+ Gem(
120
+ id=gem[0],
121
+ name=gem[1][0],
122
+ description=gem[1][1],
123
+ prompt=gem[2] and gem[2][0] or None,
124
+ predefined=False,
125
+ ),
126
+ )
127
+ for gem in custom_gems
128
+ ),
129
+ )
130
+ )
131
+
132
+ return self._gems
133
+
134
+ @running(retry=2)
135
+ async def delete_gem(self, gem: Gem | str, **kwargs) -> None:
136
+ """
137
+ Delete a custom gem from gemini.google.com.
138
+
139
+ Parameters
140
+ ----------
141
+ gem: `Gem | str`
142
+ Gem to delete, can be either a `gemini_webapi.types.Gem` object or a gem id string.
143
+ """
144
+
145
+ if isinstance(gem, Gem):
146
+ gem = gem.id
147
+
148
+ await self._batch_execute(
149
+ [RPCData(rpcid=GRPC.DELETE_GEM, payload=[gem])],
150
+ **kwargs,
151
+ )
@@ -10,6 +10,19 @@ class Endpoint(StrEnum):
10
10
  BATCH_EXEC = "https://gemini.google.com/_/BardChatUi/data/batchexecute"
11
11
 
12
12
 
13
+ class GRPC(StrEnum):
14
+ """
15
+ Google RPC ids used in Gemini API.
16
+ """
17
+
18
+ # Chat methods
19
+ READ_CHAT = "hNvQHb"
20
+
21
+ # Gem methods
22
+ LIST_GEMS = "CNgdBe"
23
+ DELETE_GEM = "UXcSJb"
24
+
25
+
13
26
  class Headers(Enum):
14
27
  GEMINI = {
15
28
  "Content-Type": "application/x-www-form-urlencoded;charset=utf-8",
@@ -2,5 +2,6 @@
2
2
 
3
3
  from .candidate import Candidate
4
4
  from .gem import Gem, GemJar
5
+ from .grpc import RPCData
5
6
  from .image import Image, WebImage, GeneratedImage
6
7
  from .modeloutput import ModelOutput
@@ -0,0 +1,34 @@
1
+ from pydantic import BaseModel
2
+
3
+ from ..constants import GRPC
4
+
5
+
6
+ class RPCData(BaseModel):
7
+ """
8
+ Helper class containing necessary data for Google RPC calls.
9
+
10
+ Parameters
11
+ ----------
12
+ rpcid : GRPC
13
+ Google RPC ID.
14
+ payload : str
15
+ Payload for the RPC call.
16
+ identifier : str, optional
17
+ Identifier/order for the RPC call, defaults to "generic".
18
+ Makes sense if there are multiple RPC calls in a batch, where this identifier
19
+ can be used to distinguish between responses.
20
+ """
21
+
22
+ rpcid: GRPC
23
+ payload: str
24
+ identifier: str = "generic"
25
+
26
+ def __repr__(self):
27
+ return f"GRPC(rpcid='{self.rpcid}', payload='{self.payload}', identifier='{self.identifier}')"
28
+
29
+ def serialize(self) -> list:
30
+ """
31
+ Serializes object into formatted payload ready for RPC call.
32
+ """
33
+
34
+ return [self.rpcid, self.payload, None, self.identifier]
@@ -30,10 +30,10 @@ class Image(BaseModel):
30
30
  proxy: str | None = None
31
31
 
32
32
  def __str__(self):
33
- return f"{self.title}({self.url}) - {self.alt}"
34
-
35
- def __repr__(self):
36
- return f"Image(title='{self.title}', url='{len(self.url) <= 20 and self.url or self.url[:8] + '...' + self.url[-12:]}', alt='{self.alt}')"
33
+ return (
34
+ f"Image(title='{self.title}', alt='{self.alt}', "
35
+ f"url='{len(self.url) <= 20 and self.url or self.url[:8] + '...' + self.url[-12:]}')"
36
+ )
37
37
 
38
38
  async def save(
39
39
  self,
@@ -2,6 +2,7 @@
2
2
 
3
3
  from asyncio import Task
4
4
 
5
+ from .decorators import running
5
6
  from .upload_file import upload_file, parse_file_name
6
7
  from .rotate_1psidts import rotate_1psidts
7
8
  from .get_access_token import get_access_token
@@ -0,0 +1,52 @@
1
+ import asyncio
2
+ import functools
3
+
4
+ from ..exceptions import APIError, ImageGenerationError
5
+
6
+
7
+ def running(retry: int = 0) -> callable:
8
+ """
9
+ Decorator to check if GeminiClient is running before making a request.
10
+
11
+ Parameters
12
+ ----------
13
+ retry: `int`, optional
14
+ Max number of retries when `gemini_webapi.APIError` is raised.
15
+ """
16
+
17
+ def decorator(func):
18
+ @functools.wraps(func)
19
+ async def wrapper(client, *args, retry=retry, **kwargs):
20
+ try:
21
+ if not client.running:
22
+ await client.init(
23
+ timeout=client.timeout,
24
+ auto_close=client.auto_close,
25
+ close_delay=client.close_delay,
26
+ auto_refresh=client.auto_refresh,
27
+ refresh_interval=client.refresh_interval,
28
+ verbose=False,
29
+ )
30
+ if client.running:
31
+ return await func(client, *args, **kwargs)
32
+
33
+ # Should not reach here
34
+ raise APIError(
35
+ f"Invalid function call: GeminiClient.{func.__name__}. Client initialization failed."
36
+ )
37
+ else:
38
+ return await func(client, *args, **kwargs)
39
+ except APIError as e:
40
+ # Image generation takes too long, only retry once
41
+ if isinstance(e, ImageGenerationError):
42
+ retry = min(1, retry)
43
+
44
+ if retry > 0:
45
+ await asyncio.sleep(1)
46
+ return await wrapper(client, *args, retry=retry - 1, **kwargs)
47
+
48
+ raise
49
+
50
+ return wrapper
51
+
52
+ return decorator
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: gemini-webapi
3
- Version: 1.14.2
3
+ Version: 1.14.4
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
@@ -678,7 +678,7 @@ Description-Content-Type: text/markdown
678
678
  License-File: LICENSE
679
679
  Requires-Dist: httpx[http2]~=0.28.1
680
680
  Requires-Dist: loguru~=0.7.3
681
- Requires-Dist: orjson~=3.10.18
681
+ Requires-Dist: orjson~=3.11.1
682
682
  Requires-Dist: pydantic~=2.11.5
683
683
  Dynamic: license-file
684
684
 
@@ -931,10 +931,14 @@ asyncio.run(main())
931
931
 
932
932
  System prompt can be applied to conversations via [Gemini Gems](https://gemini.google.com/gems/view). To use a gem, you can pass `gem` argument to `GeminiClient.generate_content` or `GeminiClient.start_chat`. `gem` can be either a string of gem id or a `gemini_webapi.Gem` object. Only one gem can be applied to a single conversation.
933
933
 
934
+ > [!TIP]
935
+ >
936
+ > There are some system predefined gems that by default are not shown to users (and therefore may not work properly). Use `client.fetch_gems(include_hidden=True)` to include them in the fetch result.
937
+
934
938
  ```python
935
939
  async def main():
936
940
  # Fetch all gems for the current account, including both predefined and user-created ones
937
- await client.fetch_gems()
941
+ await client.fetch_gems(include_hidden=False)
938
942
 
939
943
  # Once fetched, gems will be cached in `GeminiClient.gems`
940
944
  gems = client.gems
@@ -0,0 +1,24 @@
1
+ gemini_webapi/__init__.py,sha256=7ELCiUoI10ea3daeJxnv0UwqLVKpM7rxsgOZsPMstO8,150
2
+ gemini_webapi/client.py,sha256=nnInjBRsBLLLcc07f2oFv4HjwMXXCBx5Y_RMwo8NYtM,26891
3
+ gemini_webapi/constants.py,sha256=Ulj38JVv8lPW7GZRTb25sLM2utuY-q7aDTrgm-bXbrU,2545
4
+ gemini_webapi/exceptions.py,sha256=qkXrIpr0L7LtGbq3VcTO8D1xZ50pJtt0dDRp5I3uDSg,1038
5
+ gemini_webapi/components/__init__.py,sha256=wolxuAJJ32-jmHOKgpsesexP7hXea1JMo5vI52wysTI,48
6
+ gemini_webapi/components/gem_mixin.py,sha256=HUrTBHQC9Lzc53Le2droi_UoFxTOZMRLMbn6MRdcHfI,4727
7
+ gemini_webapi/types/__init__.py,sha256=1DU4JEw2KHQJbtOgOuvoEXtzQCMwAkyo0koSFVdT9JY,192
8
+ gemini_webapi/types/candidate.py,sha256=67BhY75toE5mVuB21cmHcTFtw332V_KmCjr3-9VTbJo,1477
9
+ gemini_webapi/types/gem.py,sha256=3Ppjq9V22Zp4Lb9a9ZnDviDKQpfSQf8UZxqOEjeEWd4,4070
10
+ gemini_webapi/types/grpc.py,sha256=S64h1oeC7ZJC50kmS_C2CQ7WVTanhJ4kqTFx5ZYayXI,917
11
+ gemini_webapi/types/image.py,sha256=NhW1QY2Agzb6UbrIjZLnqxqukabDSGbmoCsVguzko10,5395
12
+ gemini_webapi/types/modeloutput.py,sha256=h07kQOkL5r-oPLvZ59uVtO1eP4FGy5ZpzuYQzAeQdr8,1196
13
+ gemini_webapi/utils/__init__.py,sha256=RIU1MBqYNjih0XMMt7wCxAA-X9KVF53nDbAjaxaGTo8,352
14
+ gemini_webapi/utils/decorators.py,sha256=AuY6sU1_6_ZqeL92dTAi3eRPQ7zubB5VuBZEiz16aBM,1741
15
+ gemini_webapi/utils/get_access_token.py,sha256=eNn1omFO41wWXco1eM-KXR2CEi0Tb-chlph7H-PCNjg,6137
16
+ gemini_webapi/utils/load_browser_cookies.py,sha256=A5n_VsB7Rm8ck5lpy856UNJEhv30l3dvQ3j0g3ln1fE,1535
17
+ gemini_webapi/utils/logger.py,sha256=0VcxhVLhHBRDQutNCpapP1y_MhPoQ2ud1uIFLqxC3Z8,958
18
+ gemini_webapi/utils/rotate_1psidts.py,sha256=NyQ9OYPLBOcvpc8bodvEYDIVFrsYN0kdfc831lPEctM,1680
19
+ gemini_webapi/utils/upload_file.py,sha256=SJOMr6kryK_ClrKmqI96fqZBNFOMPsyAvFINAGAU3rk,1468
20
+ gemini_webapi-1.14.4.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
21
+ gemini_webapi-1.14.4.dist-info/METADATA,sha256=-d9j4G1z2fh6ohTAOeNW0I2O2HzlG0D48TKH67KCXFE,59156
22
+ gemini_webapi-1.14.4.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
23
+ gemini_webapi-1.14.4.dist-info/top_level.txt,sha256=dtWtug_ZrmnUqCYuu8NmGzTgWglHeNzhHU_hXmqZGWE,14
24
+ gemini_webapi-1.14.4.dist-info/RECORD,,
@@ -1,20 +0,0 @@
1
- gemini_webapi/__init__.py,sha256=7ELCiUoI10ea3daeJxnv0UwqLVKpM7rxsgOZsPMstO8,150
2
- gemini_webapi/client.py,sha256=azxKBqpLJ1Vdlq-I6GYO5743TNeZRgi6sgI2XuxIk2A,30368
3
- gemini_webapi/constants.py,sha256=rkugkck9qXW_f-9dc0XXEjVIzJ9Ja4gHBVYDP71BESg,2352
4
- gemini_webapi/exceptions.py,sha256=qkXrIpr0L7LtGbq3VcTO8D1xZ50pJtt0dDRp5I3uDSg,1038
5
- gemini_webapi/types/__init__.py,sha256=Xap_FGOKOOC9mU3bmp_VT_1pQgFMuqbys_fOcyvTnuE,166
6
- gemini_webapi/types/candidate.py,sha256=67BhY75toE5mVuB21cmHcTFtw332V_KmCjr3-9VTbJo,1477
7
- gemini_webapi/types/gem.py,sha256=3Ppjq9V22Zp4Lb9a9ZnDviDKQpfSQf8UZxqOEjeEWd4,4070
8
- gemini_webapi/types/image.py,sha256=xCPaMzstIM5C09ZkJ0545vVPAsrF3y89XnRJrEWGz5k,5436
9
- gemini_webapi/types/modeloutput.py,sha256=h07kQOkL5r-oPLvZ59uVtO1eP4FGy5ZpzuYQzAeQdr8,1196
10
- gemini_webapi/utils/__init__.py,sha256=cJ9HQYxr8l0CsY61TFlho-5DdPxCaEOpRfjxPX-eils,320
11
- gemini_webapi/utils/get_access_token.py,sha256=eNn1omFO41wWXco1eM-KXR2CEi0Tb-chlph7H-PCNjg,6137
12
- gemini_webapi/utils/load_browser_cookies.py,sha256=A5n_VsB7Rm8ck5lpy856UNJEhv30l3dvQ3j0g3ln1fE,1535
13
- gemini_webapi/utils/logger.py,sha256=0VcxhVLhHBRDQutNCpapP1y_MhPoQ2ud1uIFLqxC3Z8,958
14
- gemini_webapi/utils/rotate_1psidts.py,sha256=NyQ9OYPLBOcvpc8bodvEYDIVFrsYN0kdfc831lPEctM,1680
15
- gemini_webapi/utils/upload_file.py,sha256=SJOMr6kryK_ClrKmqI96fqZBNFOMPsyAvFINAGAU3rk,1468
16
- gemini_webapi-1.14.2.dist-info/licenses/LICENSE,sha256=hIahDEOTzuHCU5J2nd07LWwkLW7Hko4UFO__ffsvB-8,34523
17
- gemini_webapi-1.14.2.dist-info/METADATA,sha256=O24rz39UbSBc0ZBGcDOOPHKD5BrP-4P-RSqWUP1jwMk,58925
18
- gemini_webapi-1.14.2.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
19
- gemini_webapi-1.14.2.dist-info/top_level.txt,sha256=dtWtug_ZrmnUqCYuu8NmGzTgWglHeNzhHU_hXmqZGWE,14
20
- gemini_webapi-1.14.2.dist-info/RECORD,,