summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorHeiner Lohaus <heiner@lohaus.eu>2023-10-03 22:12:56 +0200
committerHeiner Lohaus <heiner@lohaus.eu>2023-10-03 22:12:56 +0200
commitbe9b8f796cb01483cf6dd807dfc6a71c51433c16 (patch)
tree831accf2f06811e865e68dd29ece3e5ecc473e5b
parentBing Updates: (diff)
downloadgpt4free-be9b8f796cb01483cf6dd807dfc6a71c51433c16.tar
gpt4free-be9b8f796cb01483cf6dd807dfc6a71c51433c16.tar.gz
gpt4free-be9b8f796cb01483cf6dd807dfc6a71c51433c16.tar.bz2
gpt4free-be9b8f796cb01483cf6dd807dfc6a71c51433c16.tar.lz
gpt4free-be9b8f796cb01483cf6dd807dfc6a71c51433c16.tar.xz
gpt4free-be9b8f796cb01483cf6dd807dfc6a71c51433c16.tar.zst
gpt4free-be9b8f796cb01483cf6dd807dfc6a71c51433c16.zip
-rw-r--r--g4f/Provider/OpenaiChat.py73
-rw-r--r--g4f/Provider/helper.py26
2 files changed, 75 insertions, 24 deletions
diff --git a/g4f/Provider/OpenaiChat.py b/g4f/Provider/OpenaiChat.py
index f7dc8298..fbd26d7c 100644
--- a/g4f/Provider/OpenaiChat.py
+++ b/g4f/Provider/OpenaiChat.py
@@ -1,14 +1,14 @@
from __future__ import annotations
-from curl_cffi.requests import AsyncSession
import uuid
import json
-from .base_provider import AsyncProvider, get_cookies, format_prompt
+from .base_provider import AsyncGeneratorProvider
+from .helper import get_browser, get_cookies, format_prompt
from ..typing import AsyncGenerator
+from ..requests import StreamSession
-
-class OpenaiChat(AsyncProvider):
+class OpenaiChat(AsyncGeneratorProvider):
url = "https://chat.openai.com"
needs_auth = True
working = True
@@ -16,7 +16,7 @@ class OpenaiChat(AsyncProvider):
_access_token = None
@classmethod
- async def create_async(
+ async def create_async_generator(
cls,
model: str,
messages: list[dict[str, str]],
@@ -32,7 +32,7 @@ class OpenaiChat(AsyncProvider):
"Accept": "text/event-stream",
"Authorization": f"Bearer {access_token}",
}
- async with AsyncSession(proxies=proxies, headers=headers, impersonate="chrome107") as session:
+ async with StreamSession(proxies=proxies, headers=headers, impersonate="chrome107") as session:
messages = [
{
"id": str(uuid.uuid4()),
@@ -48,31 +48,58 @@ class OpenaiChat(AsyncProvider):
"model": "text-davinci-002-render-sha",
"history_and_training_disabled": True,
}
- response = await session.post("https://chat.openai.com/backend-api/conversation", json=data)
- response.raise_for_status()
- last_message = None
- for line in response.content.decode().splitlines():
- if line.startswith("data: "):
- line = line[6:]
- if line == "[DONE]":
- break
- line = json.loads(line)
- if "message" in line:
- last_message = line["message"]["content"]["parts"][0]
- return last_message
+ async with session.post(f"{cls.url}/backend-api/conversation", json=data) as response:
+ response.raise_for_status()
+ last_message = ""
+ async for line in response.iter_lines():
+ if line.startswith(b"data: "):
+ line = line[6:]
+ if line == b"[DONE]":
+ break
+ line = json.loads(line)
+ if "message" in line and not line["message"]["end_turn"]:
+ new_message = line["message"]["content"]["parts"][0]
+ yield new_message[len(last_message):]
+ last_message = new_message
+
+ @classmethod
+ def fetch_access_token(cls) -> str:
+ try:
+ from selenium.webdriver.common.by import By
+ from selenium.webdriver.support.ui import WebDriverWait
+ from selenium.webdriver.support import expected_conditions as EC
+ except ImportError:
+ return
+ driver = get_browser()
+ if not driver:
+ return
+
+ driver.get(f"{cls.url}/")
+ try:
+ WebDriverWait(driver, 1200).until(
+ EC.presence_of_element_located((By.ID, "prompt-textarea"))
+ )
+ javascript = "return (await (await fetch('/api/auth/session')).json())['accessToken']"
+ return driver.execute_script(javascript)
+ finally:
+ driver.quit()
@classmethod
async def get_access_token(cls, cookies: dict = None, proxies: dict = None) -> str:
if not cls._access_token:
cookies = cookies if cookies else get_cookies("chat.openai.com")
- async with AsyncSession(proxies=proxies, cookies=cookies, impersonate="chrome107") as session:
- response = await session.get("https://chat.openai.com/api/auth/session")
- response.raise_for_status()
- cls._access_token = response.json()["accessToken"]
+ async with StreamSession(proxies=proxies, cookies=cookies, impersonate="chrome107") as session:
+ async with session.get(f"{cls.url}/api/auth/session") as response:
+ response.raise_for_status()
+ auth = await response.json()
+ if "accessToken" in auth:
+ cls._access_token = auth["accessToken"]
+ cls._access_token = cls.fetch_access_token()
+ if not cls._access_token:
+ raise RuntimeError("Missing access token")
return cls._access_token
-
@classmethod
@property
def params(cls):
diff --git a/g4f/Provider/helper.py b/g4f/Provider/helper.py
index 234cdaa1..8f09239a 100644
--- a/g4f/Provider/helper.py
+++ b/g4f/Provider/helper.py
@@ -56,4 +56,28 @@ def format_prompt(messages: list[dict[str, str]], add_special_tokens=False):
)
return f"{formatted}\nAssistant:"
else:
- return messages[0]["content"] \ No newline at end of file
+ return messages[0]["content"]
+
+
+def get_browser(user_data_dir: str = None):
+ try:
+ from undetected_chromedriver import Chrome
+ except ImportError:
+ return None
+
+ def get_user_data_dir():
+ dirs = [
+ '~/.config/google-chrome/Default',
+ '~/.var/app/com.google.Chrome/config/google-chrome/Default',
+ '%LOCALAPPDATA%\\Google\\Chrome\\User Data\\Default',
+ '~/Library/Application Support/Google/Chrome/Default',
+ ]
+ from os import path
+ for dir in dirs:
+ dir = path.expandvars(dir)
+ if path.exists(dir):
+ return dir
+ if not user_data_dir:
+ user_data_dir = get_user_data_dir()
+
+ return Chrome(user_data_dir=user_data_dir) \ No newline at end of file