summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorH Lohaus <hlohaus@users.noreply.github.com>2024-05-16 20:06:57 +0200
committerGitHub <noreply@github.com>2024-05-16 20:06:57 +0200
commit0332c0c0dd01dd71aabca62f007ad9e8809ee48f (patch)
treef9a4170ef8c5b0358bc4cf7189f997e3098ee0f3
parentUpdate README.md (diff)
parentAdd needs auth to provierds, Add PerplexityApi provider (diff)
downloadgpt4free-0332c0c0dd01dd71aabca62f007ad9e8809ee48f.tar
gpt4free-0332c0c0dd01dd71aabca62f007ad9e8809ee48f.tar.gz
gpt4free-0332c0c0dd01dd71aabca62f007ad9e8809ee48f.tar.bz2
gpt4free-0332c0c0dd01dd71aabca62f007ad9e8809ee48f.tar.lz
gpt4free-0332c0c0dd01dd71aabca62f007ad9e8809ee48f.tar.xz
gpt4free-0332c0c0dd01dd71aabca62f007ad9e8809ee48f.tar.zst
gpt4free-0332c0c0dd01dd71aabca62f007ad9e8809ee48f.zip
-rw-r--r--g4f/Provider/DeepInfra.py3
-rw-r--r--g4f/Provider/Reka.py26
-rw-r--r--g4f/Provider/Replicate.py1
-rw-r--r--g4f/Provider/You.py13
-rw-r--r--g4f/Provider/needs_auth/Gemini.py9
-rw-r--r--g4f/Provider/needs_auth/OpenaiChat.py9
-rw-r--r--g4f/Provider/needs_auth/PerplexityApi.py31
-rw-r--r--g4f/Provider/needs_auth/__init__.py3
-rw-r--r--g4f/Provider/you/har_file.py18
-rw-r--r--g4f/providers/retry_provider.py2
10 files changed, 72 insertions, 43 deletions
diff --git a/g4f/Provider/DeepInfra.py b/g4f/Provider/DeepInfra.py
index 9691539e..763b960a 100644
--- a/g4f/Provider/DeepInfra.py
+++ b/g4f/Provider/DeepInfra.py
@@ -8,8 +8,7 @@ class DeepInfra(Openai):
label = "DeepInfra"
url = "https://deepinfra.com"
working = True
- needs_auth = False
- has_auth = True
+ needs_auth = True
supports_stream = True
supports_message_history = True
default_model = "meta-llama/Meta-Llama-3-70b-instruct"
diff --git a/g4f/Provider/Reka.py b/g4f/Provider/Reka.py
index 09164b07..2306149e 100644
--- a/g4f/Provider/Reka.py
+++ b/g4f/Provider/Reka.py
@@ -9,6 +9,7 @@ from ..image import to_bytes
class Reka(AbstractProvider):
url = "https://chat.reka.ai/"
working = True
+ needs_auth = True
supports_stream = True
default_vision_model = "reka"
cookies = {}
@@ -20,13 +21,12 @@ class Reka(AbstractProvider):
messages: Messages,
stream: bool,
proxy: str = None,
- timeout: int = 180,
api_key: str = None,
image: ImageType = None,
**kwargs
) -> CreateResult:
cls.proxy = proxy
-
+
if not api_key:
cls.cookies = get_cookies("chat.reka.ai")
if not cls.cookies:
@@ -34,19 +34,19 @@ class Reka(AbstractProvider):
elif "appSession" not in cls.cookies:
raise ValueError("No appSession found in cookies for chat.reka.ai, log in or provide bearer_auth")
api_key = cls.get_access_token(cls)
-
+
conversation = []
for message in messages:
conversation.append({
"type": "human",
"text": message["content"],
})
-
+
if image:
image_url = cls.upload_image(cls, api_key, image)
conversation[-1]["image_url"] = image_url
conversation[-1]["media_type"] = "image"
-
+
headers = {
'accept': '*/*',
'accept-language': 'en,fr-FR;q=0.9,fr;q=0.8,es-ES;q=0.7,es;q=0.6,en-US;q=0.5,am;q=0.4,de;q=0.3',
@@ -64,7 +64,7 @@ class Reka(AbstractProvider):
'sec-fetch-site': 'same-origin',
'user-agent': 'Mozilla/5.0 (Macintosh; Intel Mac OS X 10_15_7) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/124.0.0.0 Safari/537.36',
}
-
+
json_data = {
'conversation_history': conversation,
'stream': True,
@@ -73,7 +73,7 @@ class Reka(AbstractProvider):
'model_name': 'reka-core',
'random_seed': int(time.time() * 1000),
}
-
+
tokens = ''
response = requests.post('https://chat.reka.ai/api/chat',
@@ -82,11 +82,11 @@ class Reka(AbstractProvider):
for completion in response.iter_lines():
if b'data' in completion:
token_data = json.loads(completion.decode('utf-8')[5:])['text']
-
+
yield (token_data.replace(tokens, ''))
-
+
tokens = token_data
-
+
def upload_image(cls, access_token, image: ImageType) -> str:
boundary_token = os.urandom(8).hex()
@@ -120,7 +120,7 @@ class Reka(AbstractProvider):
cookies=cls.cookies, headers=headers, proxies=cls.proxy, data=data.encode('latin-1'))
return response.json()['media_url']
-
+
def get_access_token(cls):
headers = {
'accept': '*/*',
@@ -141,8 +141,8 @@ class Reka(AbstractProvider):
try:
response = requests.get('https://chat.reka.ai/bff/auth/access_token',
cookies=cls.cookies, headers=headers, proxies=cls.proxy)
-
+
return response.json()['accessToken']
-
+
except Exception as e:
raise ValueError(f"Failed to get access token: {e}, refresh your cookies / log in into chat.reka.ai") \ No newline at end of file
diff --git a/g4f/Provider/Replicate.py b/g4f/Provider/Replicate.py
index 89777cf2..7ff8ad65 100644
--- a/g4f/Provider/Replicate.py
+++ b/g4f/Provider/Replicate.py
@@ -10,6 +10,7 @@ from ..errors import ResponseError, MissingAuthError
class Replicate(AsyncGeneratorProvider, ProviderModelMixin):
url = "https://replicate.com"
working = True
+ needs_auth = True
default_model = "meta/meta-llama-3-70b-instruct"
model_aliases = {
"meta-llama/Meta-Llama-3-70B-Instruct": default_model
diff --git a/g4f/Provider/You.py b/g4f/Provider/You.py
index b4892035..2b08b38a 100644
--- a/g4f/Provider/You.py
+++ b/g4f/Provider/You.py
@@ -1,3 +1,5 @@
+from __future__ import annotations
+
import re
import json
import base64
@@ -42,7 +44,6 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
]
model_aliases = {
"claude-v2": "claude-2",
- "gpt-4o": "gpt-4o",
}
_cookies = None
_cookies_used = 0
@@ -185,15 +186,7 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
@classmethod
async def create_cookies(cls, client: StreamSession) -> Cookies:
if not cls._telemetry_ids:
- try:
- cls._telemetry_ids = await get_telemetry_ids()
- except RuntimeError as e:
- if str(e) == "Event loop is closed":
- if debug.logging:
- print("Event loop is closed error occurred in create_cookies.")
- else:
- raise
-
+ cls._telemetry_ids = await get_telemetry_ids()
user_uuid = str(uuid.uuid4())
telemetry_id = cls._telemetry_ids.pop()
if debug.logging:
diff --git a/g4f/Provider/needs_auth/Gemini.py b/g4f/Provider/needs_auth/Gemini.py
index 25ad1c6e..e468f64a 100644
--- a/g4f/Provider/needs_auth/Gemini.py
+++ b/g4f/Provider/needs_auth/Gemini.py
@@ -59,7 +59,7 @@ class Gemini(AsyncGeneratorProvider):
_cookies: Cookies = None
@classmethod
- async def nodriver_login(cls) -> AsyncIterator[str]:
+ async def nodriver_login(cls, proxy: str = None) -> AsyncIterator[str]:
try:
import nodriver as uc
except ImportError:
@@ -71,7 +71,10 @@ class Gemini(AsyncGeneratorProvider):
user_data_dir = None
if debug.logging:
print(f"Open nodriver with user_dir: {user_data_dir}")
- browser = await uc.start(user_data_dir=user_data_dir)
+ browser = await uc.start(
+ user_data_dir=user_data_dir,
+ browser_args=None if proxy is None else [f"--proxy-server={proxy}"],
+ )
login_url = os.environ.get("G4F_LOGIN_URL")
if login_url:
yield f"Please login: [Google Gemini]({login_url})\n\n"
@@ -134,7 +137,7 @@ class Gemini(AsyncGeneratorProvider):
) as session:
snlm0e = await cls.fetch_snlm0e(session, cls._cookies) if cls._cookies else None
if not snlm0e:
- async for chunk in cls.nodriver_login():
+ async for chunk in cls.nodriver_login(proxy):
yield chunk
if cls._cookies is None:
async for chunk in cls.webdriver_login(proxy):
diff --git a/g4f/Provider/needs_auth/OpenaiChat.py b/g4f/Provider/needs_auth/OpenaiChat.py
index 03ea4539..b4b8bb02 100644
--- a/g4f/Provider/needs_auth/OpenaiChat.py
+++ b/g4f/Provider/needs_auth/OpenaiChat.py
@@ -403,7 +403,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
except NoValidHarFileError as e:
error = e
if cls._api_key is None:
- await cls.nodriver_access_token()
+ await cls.nodriver_access_token(proxy)
if cls._api_key is None and cls.needs_auth:
raise error
cls.default_model = cls.get_model(await cls.get_default_model(session, cls._headers))
@@ -625,7 +625,7 @@ this.fetch = async (url, options) => {
cls._update_cookie_header()
@classmethod
- async def nodriver_access_token(cls):
+ async def nodriver_access_token(cls, proxy: str = None):
try:
import nodriver as uc
except ImportError:
@@ -637,7 +637,10 @@ this.fetch = async (url, options) => {
user_data_dir = None
if debug.logging:
print(f"Open nodriver with user_dir: {user_data_dir}")
- browser = await uc.start(user_data_dir=user_data_dir)
+ browser = await uc.start(
+ user_data_dir=user_data_dir,
+ browser_args=None if proxy is None else [f"--proxy-server={proxy}"],
+ )
page = await browser.get("https://chatgpt.com/")
await page.select("[id^=headlessui-menu-button-]", 240)
api_key = await page.evaluate(
diff --git a/g4f/Provider/needs_auth/PerplexityApi.py b/g4f/Provider/needs_auth/PerplexityApi.py
new file mode 100644
index 00000000..35d8d9d6
--- /dev/null
+++ b/g4f/Provider/needs_auth/PerplexityApi.py
@@ -0,0 +1,31 @@
+from __future__ import annotations
+
+from .Openai import Openai
+from ...typing import AsyncResult, Messages
+
+class PerplexityApi(Openai):
+ label = "Perplexity API"
+ url = "https://www.perplexity.ai"
+ working = True
+ default_model = "llama-3-sonar-large-32k-online"
+ models = [
+ "llama-3-sonar-small-32k-chat",
+ "llama-3-sonar-small-32k-online",
+ "llama-3-sonar-large-32k-chat",
+ "llama-3-sonar-large-32k-online",
+ "llama-3-8b-instruct",
+ "llama-3-70b-instruct",
+ "mixtral-8x7b-instruct"
+ ]
+
+ @classmethod
+ def create_async_generator(
+ cls,
+ model: str,
+ messages: Messages,
+ api_base: str = "https://api.perplexity.ai",
+ **kwargs
+ ) -> AsyncResult:
+ return super().create_async_generator(
+ model, messages, api_base=api_base, **kwargs
+ ) \ No newline at end of file
diff --git a/g4f/Provider/needs_auth/__init__.py b/g4f/Provider/needs_auth/__init__.py
index 805d9fca..b5463b71 100644
--- a/g4f/Provider/needs_auth/__init__.py
+++ b/g4f/Provider/needs_auth/__init__.py
@@ -7,4 +7,5 @@ from .Poe import Poe
from .Openai import Openai
from .Groq import Groq
from .OpenRouter import OpenRouter
-from .OpenaiAccount import OpenaiAccount \ No newline at end of file
+from .OpenaiAccount import OpenaiAccount
+from .PerplexityApi import PerplexityApi \ No newline at end of file
diff --git a/g4f/Provider/you/har_file.py b/g4f/Provider/you/har_file.py
index cfdca12f..969ba96c 100644
--- a/g4f/Provider/you/har_file.py
+++ b/g4f/Provider/you/har_file.py
@@ -88,36 +88,34 @@ async def get_telemetry_ids(proxy: str = None) -> list:
except NoValidHarFileError as e:
if debug.logging:
logging.error(e)
- if debug.logging:
- logging.error('Getting telemetry_id for you.com with nodriver')
+
try:
from nodriver import start
except ImportError:
raise MissingRequirementsError('Add .har file from you.com or install "nodriver" package | pip install -U nodriver')
- page = None
+ if debug.logging:
+ logging.error('Getting telemetry_id for you.com with nodriver')
+
+ browser = page = None
try:
- browser = await start()
+ browser = await start(
+ browser_args=None if proxy is None else [f"--proxy-server={proxy}"],
+ )
page = await browser.get("https://you.com")
-
while not await page.evaluate('"GetTelemetryID" in this'):
await page.sleep(1)
-
async def get_telemetry_id():
return await page.evaluate(
f'this.GetTelemetryID("{public_token}", "{telemetry_url}");',
await_promise=True
)
-
return [await get_telemetry_id()]
-
finally:
try:
if page is not None:
await page.close()
-
if browser is not None:
await browser.close()
-
except Exception as e:
if debug.logging:
logging.error(e)
diff --git a/g4f/providers/retry_provider.py b/g4f/providers/retry_provider.py
index e2520437..cde8c848 100644
--- a/g4f/providers/retry_provider.py
+++ b/g4f/providers/retry_provider.py
@@ -133,7 +133,7 @@ class NewBaseRetryProvider(BaseRetryProvider):
if not stream:
yield await provider.create_async(model, messages, **kwargs)
elif hasattr(provider, "create_async_generator"):
- async for token in provider.create_async_generator(model, messages, stream, **kwargs):
+ async for token in provider.create_async_generator(model, messages, stream=stream, **kwargs):
yield token
else:
for token in provider.create_completion(model, messages, stream, **kwargs):