XFE Git
XFE Studio Git
Git 首页 全局搜索
XFE 主站 文档 NuGet
公开
关注 0 Fork 0 Star 1
返回提交历史

XFEstudio/gpt4free

Add needs auth to provierds, Add PerplexityApi provider Add proxy support to nodriver

24c5502d
Heiner Lohaus <hlohaus@users.noreply.github.com>
提交于

代码差异

10 个文件 +72 -43
Modified g4f/Provider/DeepInfra.py +1 -2
@@ -8,8 +8,7 @@ class DeepInfra(Openai):
8 8 label = "DeepInfra"
9 9 url = "https://deepinfra.com"
10 10 working = True
11 needs_auth = False
12 has_auth = True
11 needs_auth = True
13 12 supports_stream = True
14 13 supports_message_history = True
15 14 default_model = "meta-llama/Meta-Llama-3-70b-instruct"
Modified g4f/Provider/Reka.py +13 -13
@@ -9,6 +9,7 @@ from ..image import to_bytes
9 9 class Reka(AbstractProvider):
10 10 url = "https://chat.reka.ai/"
11 11 working = True
12 needs_auth = True
12 13 supports_stream = True
13 14 default_vision_model = "reka"
14 15 cookies = {}
@@ -20,13 +21,12 @@ class Reka(AbstractProvider):
20 21 messages: Messages,
21 22 stream: bool,
22 23 proxy: str = None,
23 timeout: int = 180,
24 24 api_key: str = None,
25 25 image: ImageType = None,
26 26 **kwargs
27 27 ) -> CreateResult:
28 28 cls.proxy = proxy
29
29
30 30 if not api_key:
31 31 cls.cookies = get_cookies("chat.reka.ai")
32 32 if not cls.cookies:
@@ -34,19 +34,19 @@ class Reka(AbstractProvider):
34 34 elif "appSession" not in cls.cookies:
35 35 raise ValueError("No appSession found in cookies for chat.reka.ai, log in or provide bearer_auth")
36 36 api_key = cls.get_access_token(cls)
37
37
38 38 conversation = []
39 39 for message in messages:
40 40 conversation.append({
41 41 "type": "human",
42 42 "text": message["content"],
43 43 })
44
44
45 45 if image:
46 46 image_url = cls.upload_image(cls, api_key, image)
47 47 conversation[-1]["image_url"] = image_url
48 48 conversation[-1]["media_type"] = "image"
49
49
50 50 headers = {
51 51 'accept': '*/*',
52 52 '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):
64 64 'sec-fetch-site': 'same-origin',
65 65 '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',
66 66 }
67
67
68 68 json_data = {
69 69 'conversation_history': conversation,
70 70 'stream': True,
@@ -73,7 +73,7 @@ class Reka(AbstractProvider):
73 73 'model_name': 'reka-core',
74 74 'random_seed': int(time.time() * 1000),
75 75 }
76
76
77 77 tokens = ''
78 78
79 79 response = requests.post('https://chat.reka.ai/api/chat',
@@ -82,11 +82,11 @@ class Reka(AbstractProvider):
82 82 for completion in response.iter_lines():
83 83 if b'data' in completion:
84 84 token_data = json.loads(completion.decode('utf-8')[5:])['text']
85
85
86 86 yield (token_data.replace(tokens, ''))
87
87
88 88 tokens = token_data
89
89
90 90 def upload_image(cls, access_token, image: ImageType) -> str:
91 91 boundary_token = os.urandom(8).hex()
92 92
@@ -120,7 +120,7 @@ class Reka(AbstractProvider):
120 120 cookies=cls.cookies, headers=headers, proxies=cls.proxy, data=data.encode('latin-1'))
121 121
122 122 return response.json()['media_url']
123
123
124 124 def get_access_token(cls):
125 125 headers = {
126 126 'accept': '*/*',
@@ -141,8 +141,8 @@ class Reka(AbstractProvider):
141 141 try:
142 142 response = requests.get('https://chat.reka.ai/bff/auth/access_token',
143 143 cookies=cls.cookies, headers=headers, proxies=cls.proxy)
144
144
145 145 return response.json()['accessToken']
146
146
147 147 except Exception as e:
148 148 raise ValueError(f"Failed to get access token: {e}, refresh your cookies / log in into chat.reka.ai")
Modified g4f/Provider/Replicate.py +1 -0
@@ -10,6 +10,7 @@ from ..errors import ResponseError, MissingAuthError
10 10 class Replicate(AsyncGeneratorProvider, ProviderModelMixin):
11 11 url = "https://replicate.com"
12 12 working = True
13 needs_auth = True
13 14 default_model = "meta/meta-llama-3-70b-instruct"
14 15 model_aliases = {
15 16 "meta-llama/Meta-Llama-3-70B-Instruct": default_model
Modified g4f/Provider/You.py +3 -10
@@ -1,3 +1,5 @@
1 from __future__ import annotations
2
1 3 import re
2 4 import json
3 5 import base64
@@ -42,7 +44,6 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
42 44 ]
43 45 model_aliases = {
44 46 "claude-v2": "claude-2",
45 "gpt-4o": "gpt-4o",
46 47 }
47 48 _cookies = None
48 49 _cookies_used = 0
@@ -185,15 +186,7 @@ class You(AsyncGeneratorProvider, ProviderModelMixin):
185 186 @classmethod
186 187 async def create_cookies(cls, client: StreamSession) -> Cookies:
187 188 if not cls._telemetry_ids:
188 try:
189 cls._telemetry_ids = await get_telemetry_ids()
190 except RuntimeError as e:
191 if str(e) == "Event loop is closed":
192 if debug.logging:
193 print("Event loop is closed error occurred in create_cookies.")
194 else:
195 raise
196
189 cls._telemetry_ids = await get_telemetry_ids()
197 190 user_uuid = str(uuid.uuid4())
198 191 telemetry_id = cls._telemetry_ids.pop()
199 192 if debug.logging:
Modified g4f/Provider/needs_auth/Gemini.py +6 -3
@@ -59,7 +59,7 @@ class Gemini(AsyncGeneratorProvider):
59 59 _cookies: Cookies = None
60 60
61 61 @classmethod
62 async def nodriver_login(cls) -> AsyncIterator[str]:
62 async def nodriver_login(cls, proxy: str = None) -> AsyncIterator[str]:
63 63 try:
64 64 import nodriver as uc
65 65 except ImportError:
@@ -71,7 +71,10 @@ class Gemini(AsyncGeneratorProvider):
71 71 user_data_dir = None
72 72 if debug.logging:
73 73 print(f"Open nodriver with user_dir: {user_data_dir}")
74 browser = await uc.start(user_data_dir=user_data_dir)
74 browser = await uc.start(
75 user_data_dir=user_data_dir,
76 browser_args=None if proxy is None else [f"--proxy-server={proxy}"],
77 )
75 78 login_url = os.environ.get("G4F_LOGIN_URL")
76 79 if login_url:
77 80 yield f"Please login: [Google Gemini]({login_url})\n\n"
@@ -134,7 +137,7 @@ class Gemini(AsyncGeneratorProvider):
134 137 ) as session:
135 138 snlm0e = await cls.fetch_snlm0e(session, cls._cookies) if cls._cookies else None
136 139 if not snlm0e:
137 async for chunk in cls.nodriver_login():
140 async for chunk in cls.nodriver_login(proxy):
138 141 yield chunk
139 142 if cls._cookies is None:
140 143 async for chunk in cls.webdriver_login(proxy):
Modified g4f/Provider/needs_auth/OpenaiChat.py +6 -3
@@ -403,7 +403,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
403 403 except NoValidHarFileError as e:
404 404 error = e
405 405 if cls._api_key is None:
406 await cls.nodriver_access_token()
406 await cls.nodriver_access_token(proxy)
407 407 if cls._api_key is None and cls.needs_auth:
408 408 raise error
409 409 cls.default_model = cls.get_model(await cls.get_default_model(session, cls._headers))
@@ -625,7 +625,7 @@ this.fetch = async (url, options) => {
625 625 cls._update_cookie_header()
626 626
627 627 @classmethod
628 async def nodriver_access_token(cls):
628 async def nodriver_access_token(cls, proxy: str = None):
629 629 try:
630 630 import nodriver as uc
631 631 except ImportError:
@@ -637,7 +637,10 @@ this.fetch = async (url, options) => {
637 637 user_data_dir = None
638 638 if debug.logging:
639 639 print(f"Open nodriver with user_dir: {user_data_dir}")
640 browser = await uc.start(user_data_dir=user_data_dir)
640 browser = await uc.start(
641 user_data_dir=user_data_dir,
642 browser_args=None if proxy is None else [f"--proxy-server={proxy}"],
643 )
641 644 page = await browser.get("https://chatgpt.com/")
642 645 await page.select("[id^=headlessui-menu-button-]", 240)
643 646 api_key = await page.evaluate(
Added g4f/Provider/needs_auth/PerplexityApi.py +31 -0
@@ -0,0 +1,31 @@
1 from __future__ import annotations
2
3 from .Openai import Openai
4 from ...typing import AsyncResult, Messages
5
6 class PerplexityApi(Openai):
7 label = "Perplexity API"
8 url = "https://www.perplexity.ai"
9 working = True
10 default_model = "llama-3-sonar-large-32k-online"
11 models = [
12 "llama-3-sonar-small-32k-chat",
13 "llama-3-sonar-small-32k-online",
14 "llama-3-sonar-large-32k-chat",
15 "llama-3-sonar-large-32k-online",
16 "llama-3-8b-instruct",
17 "llama-3-70b-instruct",
18 "mixtral-8x7b-instruct"
19 ]
20
21 @classmethod
22 def create_async_generator(
23 cls,
24 model: str,
25 messages: Messages,
26 api_base: str = "https://api.perplexity.ai",
27 **kwargs
28 ) -> AsyncResult:
29 return super().create_async_generator(
30 model, messages, api_base=api_base, **kwargs
31 )
Modified g4f/Provider/needs_auth/__init__.py +2 -1
@@ -7,4 +7,5 @@ from .Poe import Poe
7 7 from .Openai import Openai
8 8 from .Groq import Groq
9 9 from .OpenRouter import OpenRouter
10 from .OpenaiAccount import OpenaiAccount
10 from .OpenaiAccount import OpenaiAccount
11 from .PerplexityApi import PerplexityApi
Modified g4f/Provider/you/har_file.py +8 -10
@@ -88,36 +88,34 @@ async def get_telemetry_ids(proxy: str = None) -> list:
88 88 except NoValidHarFileError as e:
89 89 if debug.logging:
90 90 logging.error(e)
91 if debug.logging:
92 logging.error('Getting telemetry_id for you.com with nodriver')
91
93 92 try:
94 93 from nodriver import start
95 94 except ImportError:
96 95 raise MissingRequirementsError('Add .har file from you.com or install "nodriver" package | pip install -U nodriver')
97 page = None
96 if debug.logging:
97 logging.error('Getting telemetry_id for you.com with nodriver')
98
99 browser = page = None
98 100 try:
99 browser = await start()
101 browser = await start(
102 browser_args=None if proxy is None else [f"--proxy-server={proxy}"],
103 )
100 104 page = await browser.get("https://you.com")
101
102 105 while not await page.evaluate('"GetTelemetryID" in this'):
103 106 await page.sleep(1)
104
105 107 async def get_telemetry_id():
106 108 return await page.evaluate(
107 109 f'this.GetTelemetryID("{public_token}", "{telemetry_url}");',
108 110 await_promise=True
109 111 )
110
111 112 return [await get_telemetry_id()]
112
113 113 finally:
114 114 try:
115 115 if page is not None:
116 116 await page.close()
117
118 117 if browser is not None:
119 118 await browser.close()
120
121 119 except Exception as e:
122 120 if debug.logging:
123 121 logging.error(e)
Modified g4f/providers/retry_provider.py +1 -1
@@ -133,7 +133,7 @@ class NewBaseRetryProvider(BaseRetryProvider):
133 133 if not stream:
134 134 yield await provider.create_async(model, messages, **kwargs)
135 135 elif hasattr(provider, "create_async_generator"):
136 async for token in provider.create_async_generator(model, messages, stream, **kwargs):
136 async for token in provider.create_async_generator(model, messages, stream=stream, **kwargs):
137 137 yield token
138 138 else:
139 139 for token in provider.create_completion(model, messages, stream, **kwargs):