Skip to content

Commit

Permalink
feat: uploading file and saving image now will inherit proxy settings…
Browse files Browse the repository at this point in the history
… from GeminiClient
  • Loading branch information
HanaokaYuzu committed Mar 15, 2024
1 parent afdbc3a commit 0922a14
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 24 deletions.
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@ Secure_1PSID = "COOKIE VALUE HERE"
Secure_1PSIDTS = "COOKIE VALUE HERE"

async def main():
client = GeminiClient(Secure_1PSID, Secure_1PSIDTS, proxy=None)
client = GeminiClient(Secure_1PSID, Secure_1PSIDTS, proxies=None)
await client.init(timeout=30, auto_close=False, close_delay=300)

asyncio.run(main())
Expand Down
14 changes: 8 additions & 6 deletions src/gemini_webapi/client.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,13 +43,13 @@ class GeminiClient:
__Secure-1PSID cookie value.
secure_1psidts: `str`, optional
__Secure-1PSIDTS cookie value, some google accounts don't require this value, provide only if it's in the cookie list.
proxy: `dict`, optional
proxies: `dict`, optional
Dict of proxies.
"""

__slots__ = [
"cookies",
"proxy",
"proxies",
"client",
"access_token",
"running",
Expand All @@ -62,10 +62,10 @@ def __init__(
self,
secure_1psid: str,
secure_1psidts: Optional[str] = None,
proxy: Optional[dict] = None,
proxies: Optional[dict] = None,
):
self.cookies = {"__Secure-1PSID": secure_1psid}
self.proxy = proxy
self.proxies = proxies
self.client: AsyncClient = None
self.access_token: str = None
self.running: bool = False
Expand Down Expand Up @@ -95,7 +95,7 @@ async def init(
try:
self.client = AsyncClient(
timeout=timeout,
proxies=self.proxy,
proxies=self.proxies,
follow_redirects=True,
headers=Headers.GEMINI.value,
cookies=self.cookies,
Expand Down Expand Up @@ -199,7 +199,7 @@ async def generate_content(
prompt,
0,
None,
[[[await upload_file(image), 1]]],
[[[await upload_file(image, self.proxies), 1]]],
]
or [prompt],
None,
Expand Down Expand Up @@ -249,6 +249,7 @@ async def generate_content(
url=image[0][0][0],
title=image[2],
alt=image[0][4],
proxies=self.proxies,
)
for image in candidate[4]
]
Expand All @@ -265,6 +266,7 @@ async def generate_content(
alt=len(image[3][5]) > i
and image[3][5][i]
or image[3][5][0],
proxies=self.proxies,
cookies=self.cookies,
)
for i, image in enumerate(candidate[12][7][0])
Expand Down
35 changes: 20 additions & 15 deletions src/gemini_webapi/types/image.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,9 +2,9 @@
from pathlib import Path
from datetime import datetime

from loguru import logger
from httpx import AsyncClient, HTTPError
from pydantic import BaseModel, field_validator
from loguru import logger


class Image(BaseModel):
Expand All @@ -14,16 +14,19 @@ class Image(BaseModel):
Parameters
----------
url: `str`
URL of the image
URL of the image.
title: `str`, optional
Title of the image, by default is "[Image]"
Title of the image, by default is "[Image]".
alt: `str`, optional
Optional description of the image
Optional description of the image.
proxies: `dict`, optional
Dict of proxies used when saving image.
"""

url: str
title: str = "[Image]"
alt: str = ""
proxies: dict | None = None

def __str__(self):
return f"{self.title}({self.url}) - {self.alt}"
Expand All @@ -45,25 +48,25 @@ async def save(
Parameters
----------
path: `str`, optional
Path to save the image, by default will save to ./temp
Path to save the image, by default will save to "./temp".
filename: `str`, optional
File name to save the image, by default will use the original file name from the URL
File name to save the image, by default will use the original file name from the URL.
cookies: `dict`, optional
Cookies used for requesting the content of the image
Cookies used for requesting the content of the image.
verbose : `bool`, optional
If True, print the path of the saved file or warning for invalid file name, by default False
If True, print the path of the saved file or warning for invalid file name, by default False.
skip_invalid_filename: `bool`, optional
If True, will only save the image if the file name and extension are valid, by default False
If True, will only save the image if the file name and extension are valid, by default False.
Returns
-------
`str | None`
Absolute path of the saved image if successful, None if filename is invalid and `skip_invalid_filename` is True
Absolute path of the saved image if successful, None if filename is invalid and `skip_invalid_filename` is True.
Raises
------
`httpx.HTTPError`
If the network request failed
If the network request failed.
"""
filename = filename or self.url.split("/")[-1].split("?")[0]
try:
Expand All @@ -74,7 +77,9 @@ async def save(
if skip_invalid_filename:
return None

async with AsyncClient(follow_redirects=True, cookies=cookies) as client:
async with AsyncClient(
follow_redirects=True, cookies=cookies, proxies=self.proxies
) as client:
response = await client.get(self.url)
if response.status_code == 200:
content_type = response.headers.get("content-type")
Expand Down Expand Up @@ -115,7 +120,7 @@ class GeneratedImage(Image):
----------
cookies: `dict`
Cookies used for requesting the content of the generated image, inherit from GeminiClient object or manually set.
Must contain valid "__Secure-1PSID" and "__Secure-1PSIDTS" values
Should contain valid "__Secure-1PSID" and "__Secure-1PSIDTS" values.
"""

cookies: dict[str, str]
Expand All @@ -138,9 +143,9 @@ async def save(self, **kwargs) -> None:
----------
filename: `str`, optional
Filename to save the image, generated images are always in .png format, but file extension will not be included in the URL.
And since the URL ends with a long hash, by default will use timestamp + end of the hash as the filename
And since the URL ends with a long hash, by default will use timestamp + end of the hash as the filename.
**kwargs: `dict`, optional
Other arguments to pass to `Image.save`
Other arguments to pass to `Image.save`.
"""
await super().save(
filename=kwargs.pop("filename", None)
Expand Down
6 changes: 4 additions & 2 deletions src/gemini_webapi/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,14 +5,16 @@


@validate_call
async def upload_file(file: bytes | str) -> str:
async def upload_file(file: bytes | str, proxies: dict | None = None) -> str:
"""
Upload a file to Google's server and return its identifier.
Parameters
----------
file : `bytes` | `str`
File data in bytes, or path to the file to be uploaded.
proxies: `dict`, optional
Dict of proxies.
Returns
-------
Expand All @@ -30,7 +32,7 @@ async def upload_file(file: bytes | str) -> str:
with open(file, "rb") as f:
file = f.read()

async with AsyncClient() as client:
async with AsyncClient(proxies=proxies) as client:
response = await client.post(
url=Endpoint.UPLOAD.value,
headers=Headers.UPLOAD.value,
Expand Down

0 comments on commit 0922a14

Please sign in to comment.