上传 base64 编码的图片到上游服务器。 Args: data_url: data:image/xxx;base64,... 格式的图片数据 chat_id: 当前对话ID token: 认证令牌 user_id: 用户ID auth_mode: 当前鉴权模式,guest 模式下禁止上传 Returns: 上传成功返回完整的文件信息字典,失败返回 None
(
self,
data_url: str,
chat_id: str,
token: str,
user_id: str,
auth_mode: str = "authenticated",
)
| 1184 | await token_pool.record_token_failure(token, error) |
| 1185 | |
| 1186 | async def upload_image( |
| 1187 | self, |
| 1188 | data_url: str, |
| 1189 | chat_id: str, |
| 1190 | token: str, |
| 1191 | user_id: str, |
| 1192 | auth_mode: str = "authenticated", |
| 1193 | ) -> Optional[Dict]: |
| 1194 | """上传 base64 编码的图片到上游服务器。 |
| 1195 | |
| 1196 | Args: |
| 1197 | data_url: data:image/xxx;base64,... 格式的图片数据 |
| 1198 | chat_id: 当前对话ID |
| 1199 | token: 认证令牌 |
| 1200 | user_id: 用户ID |
| 1201 | auth_mode: 当前鉴权模式,guest 模式下禁止上传 |
| 1202 | |
| 1203 | Returns: |
| 1204 | 上传成功返回完整的文件信息字典,失败返回 None |
| 1205 | """ |
| 1206 | if auth_mode == "guest" or not data_url.startswith("data:"): |
| 1207 | return None |
| 1208 | |
| 1209 | try: |
| 1210 | # 解析 data URL |
| 1211 | header, encoded = data_url.split(",", 1) |
| 1212 | mime_type = header.split(";")[0].split(":")[1] if ":" in header else "image/jpeg" |
| 1213 | |
| 1214 | # 解码 base64 数据 |
| 1215 | image_data = base64.b64decode(encoded) |
| 1216 | filename = str(uuid.uuid4()) |
| 1217 | |
| 1218 | self.logger.debug(f"📤 上传图片: {filename}, 大小: {len(image_data)} bytes") |
| 1219 | |
| 1220 | # 构建上传请求 |
| 1221 | upload_url = f"{self.base_url}/api/v1/files/" |
| 1222 | headers = { |
| 1223 | "Accept": "*/*", |
| 1224 | "Accept-Language": "zh-CN,zh;q=0.9", |
| 1225 | "Cache-Control": "no-cache", |
| 1226 | "Connection": "keep-alive", |
| 1227 | "Origin": f"{self.base_url}", |
| 1228 | "Pragma": "no-cache", |
| 1229 | "Referer": ( |
| 1230 | f"{self.base_url}/c/{chat_id}" if chat_id else f"{self.base_url}/" |
| 1231 | ), |
| 1232 | "Sec-Ch-Ua": '"Microsoft Edge";v="141", "Not?A_Brand";v="8", "Chromium";v="141"', |
| 1233 | "Sec-Ch-Ua-Mobile": "?0", |
| 1234 | "Sec-Ch-Ua-Platform": '"Windows"', |
| 1235 | "Sec-Fetch-Dest": "empty", |
| 1236 | "Sec-Fetch-Mode": "cors", |
| 1237 | "Sec-Fetch-Site": "same-origin", |
| 1238 | "User-Agent": "Mozilla/5.0 (Windows NT 10.0; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/141.0.0.0 Safari/537.36 Edg/141.0.0.0", |
| 1239 | "Authorization": f"Bearer {token}", |
| 1240 | } |
| 1241 | |
| 1242 | # Get proxy configuration |
| 1243 | proxies = self._get_proxy_config() |
no test coverage detected