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

XFEstudio/gpt4free

Refactor Copilot authentication handling; streamline cookie management and access token retrieval

cd42fa6d
hlohaus <983577+hlohaus@users.noreply.github.com>
提交于

代码差异

3 个文件 +32 -71
Modified g4f/Provider/Copilot.py +29 -46
@@ -75,18 +75,30 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
75 75 websocket_url = "wss://copilot.microsoft.com/c/api/chat?api-version=2"
76 76 conversation_url = f"{url}/c/api/conversations"
77 77
78 _access_token: str = None
79 _useridentitytype: str = None
80 _cookies: dict = {}
81
82 78 @classmethod
83 async def on_auth_async(cls, api_key: str = None, **kwargs) -> AsyncIterator:
84 cookies = cls.cookies_to_dict()
79 async def on_auth_async(cls, cookies: dict = None, api_key: str = None, proxy: str = None, **kwargs) -> AsyncIterator:
85 80 if api_key:
81 if not cookies:
82 cookies = {}
86 83 cookies[cls.anon_cookie_name] = api_key
84 elif cookies is None:
85 cookies = get_cookies(cls.cookie_domain, False, cache_result=False)
86 access_token = None
87 useridentitytype = None
88 if cls.needs_auth or cls.anon_cookie_name not in cookies:
89 try:
90 access_token, useridentitytype, cookies = readHAR(cls.url)
91 except NoValidHarFileError as h:
92 debug.log(f"Copilot: {h}")
93 if has_nodriver:
94 yield RequestLogin(cls.label, os.environ.get("G4F_LOGIN_URL", ""))
95 access_token, useridentitytype, cookies = await get_access_token_and_cookies(cls.url, proxy)
96 else:
97 raise h
87 98 yield AuthResult(
88 access_token=cls._access_token,
89 cookies=cls.cookies_to_dict() or get_cookies(cls.cookie_domain, False)
99 access_token=access_token,
100 useridentitytype=useridentitytype,
101 cookies=cookies
90 102 )
91 103
92 104 @classmethod
@@ -95,23 +107,6 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
95 107 model: str,
96 108 messages: Messages,
97 109 auth_result: AuthResult,
98 **kwargs
99 ) -> AsyncResult:
100 cls._access_token = getattr(auth_result, "access_token", None)
101 cls._cookies = getattr(auth_result, "cookies")
102 async for chunk in cls.create(model, messages, **kwargs):
103 yield chunk
104 auth_result.cookies = cls.cookies_to_dict()
105
106 @classmethod
107 def cookies_to_dict(cls):
108 return cls._cookies if isinstance(cls._cookies, dict) else {c.name: c.value for c in cls._cookies}
109
110 @classmethod
111 async def create(
112 cls,
113 model: str,
114 messages: Messages,
115 110 proxy: str = None,
116 111 timeout: int = 30,
117 112 prompt: str = None,
@@ -125,29 +120,17 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
125 120 model = cls.get_model(model)
126 121 websocket_url = cls.websocket_url
127 122 headers = None
128 if cls._access_token or cls.needs_auth:
129 if cls._access_token is None:
130 try:
131 cls._access_token, cls._useridentitytype, cls._cookies = readHAR(cls.url)
132 except NoValidHarFileError as h:
133 debug.log(f"Copilot: {h}")
134 if has_nodriver:
135 yield RequestLogin(cls.label, os.environ.get("G4F_LOGIN_URL", ""))
136 cls._access_token, cls._useridentitytype, cls._cookies = await get_access_token_and_cookies(cls.url, proxy)
137 else:
138 raise h
139 websocket_url = f"{websocket_url}&accessToken={quote(cls._access_token)}" + (f"&X-UserIdentityType={quote(cls._useridentitytype)}" if cls._useridentitytype else "")
140 headers = {"authorization": f"Bearer {cls._access_token}"}
141
123 if auth_result.access_token:
124 websocket_url = f"{websocket_url}&accessToken={quote(auth_result.access_token)}" + (f"&X-UserIdentityType={quote(auth_result.useridentitytype)}" if getattr(auth_result, "useridentitytype", None) else "")
125 headers = {"authorization": f"Bearer {auth_result.access_token}"}
142 126
143 127 async with AsyncSession(
144 128 timeout=timeout,
145 129 proxy=proxy,
146 130 impersonate="chrome",
147 131 headers=headers,
148 cookies=cls._cookies,
132 cookies=auth_result.cookies
149 133 ) as session:
150 cls._cookies = session.cookies.jar if hasattr(session.cookies, "jar") else session.cookies
151 134 if conversation is None:
152 135 # har_file = os.path.join(os.path.dirname(__file__), "copilot", "copilot.microsoft.com.har")
153 136 # with open(har_file, "r") as f:
@@ -179,7 +162,7 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
179 162 "https://copilot.microsoft.com/c/api/start",
180 163 headers={
181 164 "content-type": "application/json",
182 **({"x-useridentitytype": cls._useridentitytype} if cls._useridentitytype else {}),
165 **({"x-useridentitytype": auth_result.useridentitytype} if getattr(auth_result, "useridentitytype", None) else {}),
183 166 **(headers or {})
184 167 },
185 168 json=data
@@ -206,7 +189,7 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
206 189 # debug.log(f"Copilot: User: {user}")
207 190
208 191 uploaded_attachments = []
209 if cls._access_token is not None:
192 if auth_result.access_token:
210 193 # Upload regular media (images)
211 194 for media, _ in merge_media(media, messages):
212 195 if not isinstance(media, str):
@@ -216,7 +199,7 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
216 199 headers={
217 200 "content-type": is_accepted_format(data),
218 201 "content-length": str(len(data)),
219 **({"x-useridentitytype": cls._useridentitytype} if cls._useridentitytype else {})
202 **({"x-useridentitytype": auth_result.useridentitytype} if getattr(auth_result, "useridentitytype", None) else {})
220 203 },
221 204 data=data
222 205 )
@@ -239,7 +222,7 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
239 222 response = await session.post(
240 223 "https://copilot.microsoft.com/c/api/attachments",
241 224 multipart=data,
242 headers={"x-useridentitytype": cls._useridentitytype} if cls._useridentitytype else {}
225 headers={"x-useridentitytype": auth_result.useridentitytype} if getattr(auth_result, "useridentitytype", None) else {}
243 226 )
244 227 response.raise_for_status()
245 228 data = response.json()
@@ -312,7 +295,7 @@ class Copilot(AsyncAuthedProvider, ProviderModelMixin):
312 295 elif msg.get("event") not in ["received", "startMessage", "partCompleted", "connected"]:
313 296 debug.log(f"Copilot Message: {msg_txt[:100]}...")
314 297 if not done:
315 raise RuntimeError(f"Invalid response: {last_msg}")
298 raise MissingAuthError(f"Invalid response: {last_msg}")
316 299 if sources:
317 300 yield Sources(sources.values())
318 301 if not wss.closed:
Modified g4f/Provider/needs_auth/CopilotAccount.py +2 -24
@@ -1,12 +1,6 @@
1 1 from __future__ import annotations
2 2
3 import os
4 from typing import AsyncIterator
5
6 from ..Copilot import Copilot, readHAR, has_nodriver, get_access_token_and_cookies
7 from ...providers.response import AuthResult, RequestLogin
8 from ...errors import NoValidHarFileError
9 from ... import debug
3 from ..Copilot import Copilot
10 4
11 5 class CopilotAccount(Copilot):
12 6 needs_auth = True
@@ -19,20 +13,4 @@ class CopilotAccount(Copilot):
19 13 "gpt-4o": default_model,
20 14 "o1": "Think Deeper",
21 15 "dall-e-3": default_model
22 }
23
24 @classmethod
25 async def on_auth_async(cls, proxy: str = None, **kwargs) -> AsyncIterator:
26 try:
27 cls._access_token, cls._cookies = readHAR(cls.url)
28 except NoValidHarFileError as h:
29 debug.log(f"Copilot: {h}")
30 if has_nodriver:
31 yield RequestLogin(cls.label, os.environ.get("G4F_LOGIN_URL", ""))
32 cls._access_token, cls._useridentitytype, cls._cookies = await get_access_token_and_cookies(cls.url, proxy)
33 else:
34 raise h
35 yield AuthResult(
36 api_key=cls._access_token,
37 cookies=cls.cookies_to_dict()
38 )
16 }
Modified g4f/Provider/needs_auth/OpenaiChat.py +1 -1
@@ -531,7 +531,7 @@ class OpenaiChat(AsyncAuthedProvider, ProviderModelMixin):
531 531 headers=headers
532 532 ) as response:
533 533 cls._update_request_args(auth_result, session)
534 if response.status in (401, 403, 429):
534 if response.status in (401, 403, 429, 500):
535 535 raise MissingAuthError("Access token is not valid")
536 536 elif response.status == 422:
537 537 raise RuntimeError((await response.json()), data)