mirror of
https://github.com/xtekky/gpt4free.git
synced 2024-11-23 00:22:09 +03:00
Move raise_for_status, Create FormData wrapper
This commit is contained in:
parent
8cc6000ffb
commit
b7eee50930
@ -5,7 +5,7 @@ import json
|
||||
import base64
|
||||
import uuid
|
||||
try:
|
||||
from curl_cffi import CurlMime
|
||||
from ..requests.curl_cffi import FormData
|
||||
has_curl_cffi = True
|
||||
except ImportError:
|
||||
has_curl_cffi = False
|
||||
@ -123,13 +123,11 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
|
||||
) as response:
|
||||
await raise_for_status(response)
|
||||
upload_nonce = await response.text()
|
||||
#data = FormData()
|
||||
#data.add_field('file', file, filename=filename)
|
||||
multipart = CurlMime()
|
||||
multipart.addpart(name="file", filename=filename, data=file)
|
||||
data = FormData()
|
||||
data.add_field('file', file, filename=filename)
|
||||
async with client.post(
|
||||
f"{cls.url}/api/upload",
|
||||
multipart=multipart,
|
||||
data=data,
|
||||
headers={
|
||||
"X-Upload-Nonce": upload_nonce,
|
||||
},
|
||||
|
@ -1,24 +1,39 @@
|
||||
import webview
|
||||
from functools import partial
|
||||
try:
|
||||
from platformdirs import user_config_dir
|
||||
has_platformdirs = True
|
||||
except ImportError:
|
||||
has_platformdirs = False
|
||||
|
||||
from g4f.gui import run_gui
|
||||
from g4f.gui.run import gui_parser
|
||||
import g4f.version
|
||||
import g4f.debug
|
||||
|
||||
def run_webview(host: str = "0.0.0.0", port: int = 8080, debug: bool = True):
|
||||
webview.create_window(f"g4f - {g4f.version.utils.current_version}", f"http://{host}:{port}/")
|
||||
if debug:
|
||||
g4f.debug.logging = True
|
||||
def run_webview(
|
||||
host: str = "0.0.0.0",
|
||||
port: int = 8080,
|
||||
debug: bool = False,
|
||||
storage_path: str = None
|
||||
):
|
||||
webview.create_window(
|
||||
f"g4f - {g4f.version.utils.current_version}",
|
||||
f"http://{host}:{port}/",
|
||||
text_select=True
|
||||
)
|
||||
if has_platformdirs and storage_path is None:
|
||||
storage_path = user_config_dir("g4f-webview")
|
||||
webview.start(
|
||||
partial(run_gui, host, port),
|
||||
private_mode=False,
|
||||
storage_path=user_config_dir("g4f-webview"),
|
||||
storage_path=storage_path,
|
||||
debug=debug
|
||||
)
|
||||
|
||||
if __name__ == "__main__":
|
||||
parser = gui_parser()
|
||||
args = parser.parse_args()
|
||||
if args.debug:
|
||||
g4f.debug.logging = True
|
||||
run_webview(args.host, args.port, args.debug)
|
45
g4f/gui/webview.spec
Normal file
45
g4f/gui/webview.spec
Normal file
@ -0,0 +1,45 @@
|
||||
# -*- mode: python ; coding: utf-8 -*-
|
||||
|
||||
|
||||
block_cipher = None
|
||||
|
||||
|
||||
a = Analysis(
|
||||
['webview.py'],
|
||||
pathex=[],
|
||||
binaries=[],
|
||||
datas=[],
|
||||
hiddenimports=[],
|
||||
hookspath=[],
|
||||
hooksconfig={},
|
||||
runtime_hooks=[],
|
||||
excludes=[],
|
||||
win_no_prefer_redirects=False,
|
||||
win_private_assemblies=False,
|
||||
cipher=block_cipher,
|
||||
noarchive=False,
|
||||
)
|
||||
pyz = PYZ(a.pure, a.zipped_data, cipher=block_cipher)
|
||||
|
||||
exe = EXE(
|
||||
pyz,
|
||||
a.scripts,
|
||||
a.binaries,
|
||||
Tree('client', prefix='client'),
|
||||
a.zipfiles,
|
||||
a.datas,
|
||||
[],
|
||||
name='webview',
|
||||
debug=False,
|
||||
bootloader_ignore_signals=False,
|
||||
strip=False,
|
||||
upx=True,
|
||||
upx_exclude=[],
|
||||
runtime_tmpdir=None,
|
||||
console=False,
|
||||
disable_windowed_traceback=False,
|
||||
argv_emulation=False,
|
||||
target_arch=None,
|
||||
codesign_identity=None,
|
||||
entitlements_file=None,
|
||||
)
|
@ -1,16 +1,12 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
from aiohttp import ClientResponse
|
||||
from requests import Response as RequestsResponse
|
||||
|
||||
try:
|
||||
from curl_cffi.requests import Session, Response
|
||||
from .curl_cffi import StreamResponse, StreamSession
|
||||
from .curl_cffi import StreamResponse, StreamSession, FormData
|
||||
has_curl_cffi = True
|
||||
except ImportError:
|
||||
from typing import Type as Session, Type as Response
|
||||
from .aiohttp import StreamResponse, StreamSession
|
||||
from .aiohttp import StreamResponse, StreamSession, FormData
|
||||
has_curl_cffi = False
|
||||
try:
|
||||
import webview
|
||||
@ -19,12 +15,13 @@ try:
|
||||
except ImportError:
|
||||
has_webview = False
|
||||
|
||||
from .raise_for_status import raise_for_status
|
||||
from ..webdriver import WebDriver, WebDriverSession
|
||||
from ..webdriver import bypass_cloudflare, get_driver_cookies
|
||||
from ..errors import MissingRequirementsError, RateLimitError, ResponseStatusError
|
||||
from ..errors import MissingRequirementsError
|
||||
from .defaults import DEFAULT_HEADERS, WEBVIEW_HAEDERS
|
||||
|
||||
async def get_args_from_webview(url: str):
|
||||
async def get_args_from_webview(url: str) -> dict:
|
||||
if not has_webview:
|
||||
raise MissingRequirementsError('Install "webview" package')
|
||||
window = webview.create_window("", url, hidden=True)
|
||||
@ -109,26 +106,3 @@ def get_session_from_browser(url: str, webdriver: WebDriver = None, proxy: str =
|
||||
timeout=timeout,
|
||||
impersonate="chrome"
|
||||
)
|
||||
|
||||
def is_cloudflare(text: str):
|
||||
return '<div id="cf-please-wait">' in text or "<title>Just a moment...</title>" in text
|
||||
|
||||
async def raise_for_status_async(response: Union[StreamResponse, ClientResponse], message: str = None):
|
||||
if response.status in (429, 402):
|
||||
raise RateLimitError(f"Response {response.status}: Rate limit reached")
|
||||
message = await response.text() if not response.ok and message is None else message
|
||||
if response.status == 403 and is_cloudflare(message):
|
||||
raise ResponseStatusError(f"Response {response.status}: Cloudflare detected")
|
||||
elif not response.ok:
|
||||
raise ResponseStatusError(f"Response {response.status}: {message}")
|
||||
|
||||
def raise_for_status(response: Union[StreamResponse, ClientResponse, Response, RequestsResponse], message: str = None):
|
||||
if hasattr(response, "status"):
|
||||
return raise_for_status_async(response, message)
|
||||
|
||||
if response.status_code in (429, 402):
|
||||
raise RateLimitError(f"Response {response.status_code}: Rate limit reached")
|
||||
elif response.status_code == 403 and is_cloudflare(response.text):
|
||||
raise ResponseStatusError(f"Response {response.status_code}: Cloudflare detected")
|
||||
elif not response.ok:
|
||||
raise ResponseStatusError(f"Response {response.status_code}: {response.text if message is None else message}")
|
@ -44,7 +44,3 @@ def get_connector(connector: BaseConnector = None, proxy: str = None, rdns: bool
|
||||
except ImportError:
|
||||
raise MissingRequirementsError('Install "aiohttp_socks" package for proxy support')
|
||||
return connector
|
||||
|
||||
class CurlMime(FormData):
|
||||
def addpart(self, name: str, content_type: str = None, filename: str = None, data: bytes = None):
|
||||
self.add_field(name, data, content_type=content_type, filename=filename)
|
@ -1,6 +1,6 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from curl_cffi.requests import AsyncSession, Response
|
||||
from curl_cffi.requests import AsyncSession, Response, CurlMime
|
||||
from typing import AsyncGenerator, Any
|
||||
from functools import partialmethod
|
||||
import json
|
||||
@ -65,6 +65,8 @@ class StreamSession(AsyncSession):
|
||||
def request(
|
||||
self, method: str, url: str, **kwargs
|
||||
) -> StreamResponse:
|
||||
if isinstance(kwargs.get("data"), CurlMime):
|
||||
kwargs["multipart"] = kwargs.pop("data")
|
||||
"""Create and return a StreamResponse object for the given HTTP request."""
|
||||
return StreamResponse(super().request(method, url, stream=True, **kwargs))
|
||||
|
||||
@ -75,3 +77,7 @@ class StreamSession(AsyncSession):
|
||||
put = partialmethod(request, "PUT")
|
||||
patch = partialmethod(request, "PATCH")
|
||||
delete = partialmethod(request, "DELETE")
|
||||
|
||||
class FormData(CurlMime):
|
||||
def add_field(self, name, data=None, content_type: str = None, filename: str = None) -> None:
|
||||
self.addpart(name, content_type=content_type, filename=filename, data=data)
|
34
g4f/requests/raise_for_status.py
Normal file
34
g4f/requests/raise_for_status.py
Normal file
@ -0,0 +1,34 @@
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import Union
|
||||
from aiohttp import ClientResponse
|
||||
from requests import Response as RequestsResponse
|
||||
|
||||
from ..errors import ResponseStatusError, RateLimitError
|
||||
from . import Response, StreamResponse
|
||||
|
||||
class CloudflareError(ResponseStatusError):
|
||||
...
|
||||
|
||||
def is_cloudflare(text: str) -> bool:
|
||||
return '<div id="cf-please-wait">' in text or "<title>Just a moment...</title>" in text
|
||||
|
||||
async def raise_for_status_async(response: Union[StreamResponse, ClientResponse], message: str = None):
|
||||
if response.status in (429, 402):
|
||||
raise RateLimitError(f"Response {response.status}: Rate limit reached")
|
||||
message = await response.text() if not response.ok and message is None else message
|
||||
if response.status == 403 and is_cloudflare(message):
|
||||
raise CloudflareError(f"Response {response.status}: Cloudflare detected")
|
||||
elif not response.ok:
|
||||
raise ResponseStatusError(f"Response {response.status}: {message}")
|
||||
|
||||
def raise_for_status(response: Union[Response, StreamResponse, ClientResponse, RequestsResponse], message: str = None):
|
||||
if hasattr(response, "status"):
|
||||
return raise_for_status_async(response, message)
|
||||
|
||||
if response.status_code in (429, 402):
|
||||
raise RateLimitError(f"Response {response.status_code}: Rate limit reached")
|
||||
elif response.status_code == 403 and is_cloudflare(response.text):
|
||||
raise CloudflareError(f"Response {response.status_code}: Cloudflare detected")
|
||||
elif not response.ok:
|
||||
raise ResponseStatusError(f"Response {response.status_code}: {response.text if message is None else message}")
|
Loading…
Reference in New Issue
Block a user