mirror of
https://github.com/xtekky/gpt4free.git
synced 2025-12-05 18:20:35 -08:00
Refactor Cloudflare and LMArena providers to enhance authentication handling and improve WebSocket communication
This commit is contained in:
parent
63315df501
commit
da6c00e2a2
6 changed files with 58 additions and 74 deletions
57
.gitignore
vendored
57
.gitignore
vendored
|
|
@ -1,48 +1,11 @@
|
|||
# Default ignored files
|
||||
/shelf/
|
||||
/workspace.xml
|
||||
# Editor-based HTTP Client requests
|
||||
/httpRequests/
|
||||
# Datasource local storage ignored files
|
||||
/dataSources/
|
||||
/dataSources.local.xml
|
||||
|
||||
# Ignore local python virtual environment
|
||||
venv/
|
||||
|
||||
# Ignore streamlit_chat_app.py conversations pickle
|
||||
conversations.pkl
|
||||
*.pkl
|
||||
.idea/
|
||||
**/__pycache__/
|
||||
__pycache__/
|
||||
|
||||
*.log
|
||||
*.pyc
|
||||
*.egg-info/
|
||||
*.egg
|
||||
*.egg-info
|
||||
.DS_Store
|
||||
*~
|
||||
*.gguf
|
||||
.buildozer
|
||||
har_and_cookies
|
||||
bin
|
||||
dist
|
||||
__pycache__
|
||||
generated_media
|
||||
site-packages
|
||||
projects
|
||||
node_modules
|
||||
models
|
||||
projects/windows/g4f
|
||||
generated_images/
|
||||
generated_media/
|
||||
projects/windows/
|
||||
|
||||
*.bak
|
||||
*.backup
|
||||
.env
|
||||
g4f.dev/
|
||||
|
||||
# Build artifacts
|
||||
build/
|
||||
dist/
|
||||
*.spec
|
||||
pyproject.toml.bak
|
||||
debian/
|
||||
winget/
|
||||
g4f.egg-info
|
||||
models/models.json
|
||||
pyvenv.cfg
|
||||
lib64
|
||||
|
|
|
|||
|
|
@ -568,15 +568,22 @@ class LMArena(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
|
|||
pass
|
||||
elif has_nodriver or cls.share_url is None:
|
||||
async def callback(page):
|
||||
element = await page.select('[style="display: grid;"]')
|
||||
if element:
|
||||
await click_trunstile(page, 'document.querySelector(\'[style="display: grid;"]\')')
|
||||
await page.find("Ask anything…", 120)
|
||||
button = await page.find("Accept Cookies")
|
||||
if button:
|
||||
await button.click()
|
||||
else:
|
||||
debug.log("No 'Accept Cookies' button found, skipping.")
|
||||
await asyncio.sleep(1)
|
||||
textarea = await page.find("Ask anything…")
|
||||
if textarea:
|
||||
await textarea.send_keys("Hello")
|
||||
await asyncio.sleep(1)
|
||||
button = await page.select('[type="submit"]:has([data-sentry-element="ArrowUp"])')
|
||||
if button:
|
||||
await button.click()
|
||||
element = await page.select('[style="display: grid;"]')
|
||||
if element:
|
||||
await click_trunstile(page, 'document.querySelector(\'[style="display: grid;"]\')')
|
||||
if not await page.evaluate('document.cookie.indexOf("arena-auth-prod-v1") >= 0'):
|
||||
debug.log("No authentication cookie found, trying to authenticate.")
|
||||
await page.select('#cf-turnstile', 300)
|
||||
|
|
@ -628,7 +635,7 @@ class LMArena(AsyncGeneratorProvider, ProviderModelMixin, AuthFileMixin):
|
|||
elif model in cls.image_models:
|
||||
model_id = cls.image_models[model]
|
||||
else:
|
||||
raise ModelNotFoundError(f"Model '{model}' is not supported by LMArena Beta.")
|
||||
raise ModelNotFoundError(f"Model '{model}' is not supported by LMArena provider.")
|
||||
|
||||
userMessageId = str(uuid.uuid7())
|
||||
modelAMessageId = str(uuid.uuid7())
|
||||
|
|
|
|||
|
|
@ -1,5 +1,6 @@
|
|||
from __future__ import annotations
|
||||
|
||||
import os
|
||||
import asyncio
|
||||
from typing import Optional
|
||||
from aiohttp import ClientSession, ClientTimeout
|
||||
|
|
@ -10,13 +11,13 @@ from aiohttp import ClientSession
|
|||
try:
|
||||
import nodriver
|
||||
from nodriver.core.connection import ProtocolException
|
||||
has_nodriver = True
|
||||
except:
|
||||
pass
|
||||
has_nodriver = False
|
||||
|
||||
from ...typing import Messages, AsyncResult
|
||||
from ...providers.response import VideoResponse, Reasoning, ContinueResponse, ProviderInfo
|
||||
from ...requests import get_nodriver
|
||||
from ...errors import MissingRequirementsError
|
||||
from ..base_provider import AsyncGeneratorProvider, ProviderModelMixin
|
||||
from ..helper import format_media_prompt
|
||||
from ... import debug
|
||||
|
|
@ -53,7 +54,7 @@ class Video(AsyncGeneratorProvider, ProviderModelMixin):
|
|||
"sora": "https://sora.chatgpt.com/explore",
|
||||
#"veo": "https://aistudio.google.com/generate-video"
|
||||
}
|
||||
api_url = f"{PUBLIC_URL}/backend-api/v2/create?provider=Video&cache=true&prompt="
|
||||
api_path = f"?provider=Video&cache=true&prompt="
|
||||
drive_url = "https://www.googleapis.com/drive/v3/"
|
||||
|
||||
active_by_default = True
|
||||
|
|
@ -62,10 +63,11 @@ class Video(AsyncGeneratorProvider, ProviderModelMixin):
|
|||
video_models = models
|
||||
|
||||
needs_auth = True
|
||||
working = True
|
||||
working = has_nodriver
|
||||
|
||||
browser = None
|
||||
stop_browser = None
|
||||
share_url: Optional[str] = None
|
||||
|
||||
@classmethod
|
||||
async def create_async_generator(
|
||||
|
|
@ -77,6 +79,8 @@ class Video(AsyncGeneratorProvider, ProviderModelMixin):
|
|||
aspect_ratio: str = None,
|
||||
**kwargs
|
||||
) -> AsyncResult:
|
||||
if cls.share_url is None:
|
||||
cls.share_url = os.getenv("G4F_SHARE_URL")
|
||||
if not model:
|
||||
model = cls.default_model
|
||||
if model not in cls.video_models:
|
||||
|
|
@ -94,10 +98,12 @@ class Video(AsyncGeneratorProvider, ProviderModelMixin):
|
|||
yield Reasoning(label="Open browser")
|
||||
browser, stop_browser = await get_nodriver(proxy=proxy)
|
||||
except Exception as e:
|
||||
if cls.share_url is None:
|
||||
raise
|
||||
debug.error(f"Error getting nodriver:", e)
|
||||
async with ClientSession() as session:
|
||||
yield Reasoning(label="Generating")
|
||||
async with session.get(cls.api_url + quote(prompt)) as response:
|
||||
async with session.get(f"{cls.share_url}{cls.api_path + quote(prompt)}") as response:
|
||||
if not response.ok:
|
||||
debug.error(f"Failed to generate Video: {response.status}")
|
||||
else:
|
||||
|
|
@ -108,7 +114,7 @@ class Video(AsyncGeneratorProvider, ProviderModelMixin):
|
|||
return
|
||||
yield VideoResponse(str(response.url), prompt)
|
||||
return
|
||||
raise MissingRequirementsError("Video provider requires a browser to be installed.")
|
||||
raise
|
||||
page = None
|
||||
try:
|
||||
yield ContinueResponse("Timeout waiting for Video URL")
|
||||
|
|
@ -123,7 +129,7 @@ class Video(AsyncGeneratorProvider, ProviderModelMixin):
|
|||
RequestConfig.headers = {}
|
||||
for key, value in event.request.headers.items():
|
||||
RequestConfig.headers[key.lower()] = value
|
||||
for _, urls in RequestConfig.urls.items():
|
||||
for urls in RequestConfig.urls.values():
|
||||
if event.request.url in urls:
|
||||
return
|
||||
debug.log(f"Adding URL: {event.request.url}")
|
||||
|
|
|
|||
|
|
@ -14,9 +14,7 @@ class QwenCode(OpenaiTemplate):
|
|||
needs_auth = True
|
||||
active_by_default = True
|
||||
default_model = "qwen3-coder-plus"
|
||||
default_vision_model = "qwen-vl-max-latest"
|
||||
models = [default_model, default_vision_model]
|
||||
vision_models = [default_vision_model]
|
||||
models = [default_model]
|
||||
client = QwenContentGenerator(QwenOAuth2Client())
|
||||
|
||||
@classmethod
|
||||
|
|
@ -48,9 +46,12 @@ class QwenCode(OpenaiTemplate):
|
|||
api_base=creds.get("endpoint", api_base),
|
||||
**kwargs
|
||||
):
|
||||
if chunk != last_chunk:
|
||||
if isinstance(chunk, str):
|
||||
if chunk != last_chunk:
|
||||
yield chunk
|
||||
last_chunk = chunk
|
||||
else:
|
||||
yield chunk
|
||||
last_chunk = chunk
|
||||
except TokenManagerError:
|
||||
await cls.client.shared_manager.getValidCredentials(cls.client.qwen_client, True)
|
||||
creds = await cls.client.get_valid_token()
|
||||
|
|
@ -62,8 +63,11 @@ class QwenCode(OpenaiTemplate):
|
|||
api_base=creds.get("endpoint"),
|
||||
**kwargs
|
||||
):
|
||||
if chunk != last_chunk:
|
||||
if isinstance(chunk, str):
|
||||
if chunk != last_chunk:
|
||||
yield chunk
|
||||
last_chunk = chunk
|
||||
else:
|
||||
yield chunk
|
||||
last_chunk = chunk
|
||||
except:
|
||||
raise
|
||||
|
|
@ -239,8 +239,7 @@ class Api:
|
|||
user_g4f_api_key = await self.get_g4f_api_key(request)
|
||||
except HTTPException:
|
||||
user_g4f_api_key = await self.security(request)
|
||||
if hasattr(user_g4f_api_key, "credentials"):
|
||||
user_g4f_api_key = user_g4f_api_key.credentials
|
||||
user_g4f_api_key = getattr(user_g4f_api_key, "credentials", user_g4f_api_key)
|
||||
if AppConfig.demo and user is None:
|
||||
ip = request.headers.get("X-Forwarded-For", "")[:4].strip(":.")
|
||||
country = request.headers.get("Cf-Ipcountry", "")
|
||||
|
|
@ -265,14 +264,14 @@ class Api:
|
|||
debug.log(f"User: '{user}' G4F API key expires in {hours}h {minutes}m {seconds}s")
|
||||
if expires < 0:
|
||||
return ErrorResponse.from_message("G4F API key expired", HTTP_401_UNAUTHORIZED)
|
||||
count = 0
|
||||
for char in user:
|
||||
if char.isupper():
|
||||
count += 1
|
||||
if count > 4:
|
||||
return ErrorResponse.from_message("Invalid user name (screaming)", HTTP_401_UNAUTHORIZED)
|
||||
else:
|
||||
user = "admin"
|
||||
count = 0
|
||||
for char in string:
|
||||
if char.isupper():
|
||||
count += 1
|
||||
if count > 4:
|
||||
return ErrorResponse.from_message("Invalid user name", HTTP_401_UNAUTHORIZED)
|
||||
path = request.url.path
|
||||
if path.startswith("/v1") or path.startswith("/api/") or (AppConfig.demo and path == '/backend-api/v2/upload_cookies'):
|
||||
if request.method != "OPTIONS" and not path.endswith("/models"):
|
||||
|
|
|
|||
|
|
@ -107,6 +107,11 @@ def is_data_an_media(data, filename: str = None) -> str:
|
|||
return content_type
|
||||
if isinstance(data, bytes):
|
||||
return is_accepted_format(data)
|
||||
if isinstance(data, str) and data.startswith("http"):
|
||||
path = urlparse(data).path
|
||||
extension = get_extension(path)
|
||||
if extension is not None:
|
||||
return EXTENSIONS_MAP[extension]
|
||||
return is_data_uri_an_image(data)
|
||||
|
||||
def is_valid_media(data: ImageType = None, filename: str = None) -> str:
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue