返回提交历史
Modified
g4f/Provider/Cloudflare.py
+17
-8
Modified
g4f/Provider/Copilot.py
+6
-2
Modified
g4f/Provider/needs_auth/Gemini.py
+1
-1
Modified
g4f/Provider/needs_auth/OpenaiChat.py
+32
-10
Modified
g4f/gui/client/static/css/style.css
+6
-4
Modified
g4f/gui/client/static/js/chat.v1.js
+3
-3
Modified
g4f/gui/server/api.py
+1
-1
XFEstudio/gpt4free
Fix issue with get_cookies from nodriver in OpenaiChat
af677717
代码差异
7 个文件
+66
-29
@@ -3,10 +3,16 @@ from __future__ import annotations
3
3
import asyncio
4
4
import json
5
5
6
try:
7
import nodriver
8
has_nodriver = True
9
except ImportError:
10
has_nodriver = False
11
6
12
from ..typing import AsyncResult, Messages, Cookies
7
13
from .base_provider import AsyncGeneratorProvider, ProviderModelMixin, get_running_loop
8
14
from ..requests import Session, StreamSession, get_args_from_nodriver, raise_for_status, merge_cookies, DEFAULT_HEADERS
9
from ..errors import ResponseStatusError, MissingRequirementsError
15
from ..errors import ResponseStatusError
10
16
11
17
class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
12
18
label = "Cloudflare AI"
@@ -35,12 +41,15 @@ class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
35
41
def get_models(cls) -> str:
36
42
if not cls.models:
37
43
if cls._args is None:
38
get_running_loop(check_nested=True)
39
args = get_args_from_nodriver(cls.url)
40
cls._args = asyncio.run(args)
44
if has_nodriver:
45
get_running_loop(check_nested=True)
46
args = get_args_from_nodriver(cls.url)
47
cls._args = asyncio.run(args)
48
else:
49
cls._args = {"headers": DEFAULT_HEADERS, "cookies": {}}
41
50
with Session(**cls._args) as session:
42
51
response = session.get(cls.models_url)
43
cls._args["cookies"] = merge_cookies(cls._args["cookies"] , response)
52
cls._args["cookies"] = merge_cookies(cls._args["cookies"], response)
44
53
try:
45
54
raise_for_status(response)
46
55
except ResponseStatusError:
@@ -62,10 +71,10 @@ class Cloudflare(AsyncGeneratorProvider, ProviderModelMixin):
62
71
**kwargs
63
72
) -> AsyncResult:
64
73
if cls._args is None:
65
try:
74
if has_nodriver:
66
75
cls._args = await get_args_from_nodriver(cls.url, proxy, timeout, cookies)
67
except MissingRequirementsError:
68
cls._args = {"headers": DEFAULT_HEADERS, cookies: {}}
76
else:
77
cls._args = {"headers": DEFAULT_HEADERS, "cookies": {}}
69
78
model = cls.get_model(model)
70
79
data = {
71
80
"messages": messages,
@@ -1,5 +1,6 @@
1
1
from __future__ import annotations
2
2
3
import os
3
4
import json
4
5
import asyncio
5
6
import base64
@@ -76,10 +77,13 @@ class Copilot(AbstractProvider, ProviderModelMixin):
76
77
cls._access_token, cls._cookies = readHAR(cls.url)
77
78
except NoValidHarFileError as h:
78
79
debug.log(f"Copilot: {h}")
79
try:
80
if has_nodriver:
81
login_url = os.environ.get("G4F_LOGIN_URL")
82
if login_url:
83
yield f"[Login to {cls.label}]({login_url})\n\n"
80
84
get_running_loop(check_nested=True)
81
85
cls._access_token, cls._cookies = asyncio.run(get_access_token_and_cookies(cls.url, proxy))
82
except MissingRequirementsError:
86
else:
83
87
raise h
84
88
debug.log(f"Copilot: Access token: {cls._access_token[:7]}...{cls._access_token[-5:]}")
85
89
websocket_url = f"{websocket_url}&accessToken={quote(cls._access_token)}"
@@ -81,7 +81,7 @@ class Gemini(AsyncGeneratorProvider, ProviderModelMixin):
81
81
browser = await get_nodriver(proxy=proxy, user_data_dir="gemini")
82
82
login_url = os.environ.get("G4F_LOGIN_URL")
83
83
if login_url:
84
yield f"Please login: [Google Gemini]({login_url})\n\n"
84
yield f"[Login to {cls.label}]({login_url})\n\n"
85
85
page = await browser.get(f"{cls.url}/app")
86
86
await page.select("div.ql-editor.textarea", 240)
87
87
cookies = {}
@@ -1,5 +1,6 @@
1
1
from __future__ import annotations
2
2
3
import os
3
4
import re
4
5
import asyncio
5
6
import uuid
@@ -8,6 +9,7 @@ import base64
8
9
import time
9
10
import requests
10
11
import random
12
from typing import AsyncIterator
11
13
from copy import copy
12
14
13
15
try:
@@ -314,7 +316,8 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
314
316
RuntimeError: If an error occurs during processing.
315
317
"""
316
318
if cls.needs_auth:
317
await cls.login(proxy)
319
async for message in cls.login(proxy):
320
yield message
318
321
async with StreamSession(
319
322
proxy=proxy,
320
323
impersonate="chrome",
@@ -504,7 +507,8 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
504
507
505
508
@classmethod
506
509
async def synthesize(cls, params: dict) -> AsyncIterator[bytes]:
507
await cls.login()
510
async for _ in cls.login():
511
pass
508
512
async with StreamSession(
509
513
impersonate="chrome",
510
514
timeout=0
@@ -519,23 +523,27 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
519
523
yield chunk
520
524
521
525
@classmethod
522
async def login(cls, proxy: str = None):
526
async def login(cls, proxy: str = None) -> AsyncIterator[str]:
523
527
if cls._expires is not None and cls._expires < time.time():
524
528
cls._headers = cls._api_key = None
525
529
try:
526
530
await get_request_config(proxy)
527
531
cls._create_request_args(RequestConfig.cookies, RequestConfig.headers)
528
cls._set_api_key(RequestConfig.access_token)
532
if RequestConfig.access_token is not None:
533
cls._set_api_key(RequestConfig.access_token)
529
534
except NoValidHarFileError:
530
535
if has_nodriver:
531
536
if cls._api_key is None:
537
login_url = os.environ.get("G4F_LOGIN_URL")
538
if login_url:
539
yield f"[Login to {cls.label}]({login_url})\n\n"
532
540
await cls.nodriver_auth(proxy)
533
541
else:
534
542
raise
535
543
536
544
@classmethod
537
545
async def nodriver_auth(cls, proxy: str = None):
538
browser = await get_nodriver(proxy=proxy, user_data_dir="chatgpt")
546
browser = await get_nodriver(proxy=proxy)
539
547
page = browser.main_tab
540
548
def on_request(event: nodriver.cdp.network.RequestWillBeSent):
541
549
if event.request.url == start_url or event.request.url.startswith(conversation_url):
@@ -548,7 +556,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
548
556
if "OpenAI-Sentinel-Turnstile-Token" in event.request.headers:
549
557
RequestConfig.turnstile_token = event.request.headers["OpenAI-Sentinel-Turnstile-Token"]
550
558
if "Authorization" in event.request.headers:
551
cls._set_api_key(event.request.headers["Authorization"].split()[-1])
559
cls._api_key = event.request.headers["Authorization"].split()[-1]
552
560
elif event.request.url == arkose_url:
553
561
RequestConfig.arkose_request = arkReq(
554
562
arkURL=event.request.url,
@@ -569,7 +577,7 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
569
577
if body:
570
578
match = re.search(r'"accessToken":"(.*?)"', body)
571
579
if match:
572
cls._set_api_key(match.group(1))
580
cls._api_key = match.group(1)
573
581
break
574
582
await asyncio.sleep(1)
575
583
while True:
@@ -577,10 +585,11 @@ class OpenaiChat(AsyncGeneratorProvider, ProviderModelMixin):
577
585
break
578
586
await asyncio.sleep(1)
579
587
RequestConfig.data_build = await page.evaluate("document.documentElement.getAttribute('data-build')")
580
for c in await page.send(nodriver.cdp.network.get_cookies([cls.url])):
581
RequestConfig.cookies[c.name] = c.value
588
for c in await page.send(get_cookies([cls.url])):
589
RequestConfig.cookies[c["name"]] = c["value"]
582
590
await page.close()
583
591
cls._create_request_args(RequestConfig.cookies, RequestConfig.headers, user_agent=user_agent)
592
cls._set_api_key(cls._api_key)
584
593
585
594
@staticmethod
586
595
def get_default_headers() -> dict:
@@ -623,4 +632,17 @@ class Conversation(BaseConversation):
623
632
self.conversation_id = conversation_id
624
633
self.message_id = message_id
625
634
self.finish_reason = finish_reason
626
self.is_recipient = False
635
self.is_recipient = False
636
637
def get_cookies(
638
urls: list[str] = None
639
):
640
params = dict()
641
if urls is not None:
642
params['urls'] = [i for i in urls]
643
cmd_dict = {
644
'method': 'Network.getCookies',
645
'params': params,
646
}
647
json = yield cmd_dict
648
return json['cookies']
@@ -81,6 +81,7 @@ body:not(.white) a:visited{
81
81
transform: translate(-50%, -50%);
82
82
filter: blur(var(--blur)) opacity(var(--opacity));
83
83
animation: zoom_gradient 6s infinite alternate;
84
display: none;
84
85
}
85
86
86
87
@keyframes zoom_gradient {
@@ -116,6 +117,8 @@ body:not(.white) a:visited{
116
117
font-weight: 500;
117
118
background-color: rgba(0, 0, 0, 0.5);
118
119
color: var(--colour-3);
120
border: var(--colour-1) 1px solid;
121
border-radius: var(--border-radius-1);
119
122
}
120
123
121
124
.white .new_version {
@@ -174,10 +177,6 @@ body:not(.white) a:visited{
174
177
color: var(--user-input)
175
178
}
176
179
177
body.white .gradient{
178
display: none;
179
}
180
181
180
.conversations {
182
181
display: flex;
183
182
flex-direction: column;
@@ -826,6 +825,9 @@ select:hover,
826
825
.count_total {
827
826
padding-left: 98px;
828
827
}
828
body:not(.white) .gradient{
829
display: block;
830
}
829
831
}
830
832
831
833
.input-box {
@@ -601,6 +601,7 @@ const ask_gpt = async (message_id, message_index = -1, regenerate = false, provi
601
601
api_key: api_key,
602
602
ignored: ignored,
603
603
}, files, message_id);
604
if (content_map.inner.dataset.timeout) clearTimeout(content_map.inner.dataset.timeout);
604
605
if (!error_storage[message_id]) {
605
606
html = markdown_render(message_storage[message_id]);
606
607
content_map.inner.innerHTML = html;
@@ -629,10 +630,9 @@ const ask_gpt = async (message_id, message_index = -1, regenerate = false, provi
629
630
regenerate
630
631
);
631
632
await safe_load_conversation(window.conversation_id, message_index == -1);
632
} else {
633
let cursorDiv = message_el.querySelector(".cursor");
634
if (cursorDiv) cursorDiv.parentNode.removeChild(cursorDiv);
635
633
}
634
let cursorDiv = message_el.querySelector(".cursor");
635
if (cursorDiv) cursorDiv.parentNode.removeChild(cursorDiv);
636
636
if (message_index == -1) {
637
637
await scroll_to_bottom();
638
638
}
@@ -181,7 +181,7 @@ class Api:
181
181
def handle_provider(self, provider_handler, model):
182
182
if isinstance(provider_handler, IterListProvider) and provider_handler.last_provider is not None:
183
183
provider_handler = provider_handler.last_provider
184
if hasattr(provider_handler, "last_model") and provider_handler.last_model is not None:
184
if not model and hasattr(provider_handler, "last_model") and provider_handler.last_model is not None:
185
185
model = provider_handler.last_model
186
186
return self._format_json("provider", {**provider_handler.get_dict(), "model": model})
187
187