mirror of
https://github.com/A-23187/trae-api.git
synced 2025-09-26 20:41:33 +08:00
trae-api
This commit is contained in:
11
.env.example
Normal file
11
.env.example
Normal file
@@ -0,0 +1,11 @@
|
||||
TRAE_APP_ID = ""
|
||||
TRAE_DEVICE_BRAND = ""
|
||||
TRAE_DEVICE_CPU = ""
|
||||
TRAE_DEVICE_ID = ""
|
||||
TRAE_DEVICE_TYPE = ""
|
||||
TRAE_IDE_TOKEN = ""
|
||||
TRAE_IDE_VERSION = ""
|
||||
TRAE_IDE_VERSION_CODE = ""
|
||||
TRAE_IDE_VERSION_TYPE = ""
|
||||
TRAE_MACHINE_ID = ""
|
||||
TRAE_OS_VERSION = ""
|
3
.gitignore
vendored
Normal file
3
.gitignore
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
.env
|
||||
.venv
|
||||
__pycache__
|
1
.python-version
Normal file
1
.python-version
Normal file
@@ -0,0 +1 @@
|
||||
3.13.2
|
21
LICENSE
Normal file
21
LICENSE
Normal file
@@ -0,0 +1,21 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2025 A23187
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
72
README.md
Normal file
72
README.md
Normal file
@@ -0,0 +1,72 @@
|
||||
# Trae to OpenAI API
|
||||
|
||||
为 Trae IDE 内置的大模型提供 OpenAI 兼容的 API
|
||||
|
||||
## 项目简介
|
||||
|
||||
本项目通过一个代理服务将 Trae IDE 内置的大模型暴露为 OpenAI 兼容的 API 接口,以在其他应用中使用
|
||||
|
||||
## 使用前提
|
||||
|
||||
1. 下载并安装 [Trae](https://www.trae.ai/download),本项目目前仅支持 Trae 海外版
|
||||
2. 浏览器需要安装 [油猴 Tampermonkey](https://www.tampermonkey.net) 扩展,用于安装脚本来获取并保存 Trae 登录凭证
|
||||
|
||||
## 快速开始
|
||||
|
||||
### 获取登录凭证
|
||||
|
||||
1. 安装油猴脚本 [auth.js](https://greasyfork.org/zh-CN/scripts/531978-%E8%8E%B7%E5%8F%96%E5%B9%B6%E4%BF%9D%E5%AD%98-trae-%E7%99%BB%E5%BD%95%E5%87%AD%E8%AF%81)
|
||||
2. 打开 Trae IDE 进行登录,若已登录则先退出登录
|
||||
3. 在自动打开的网页中,点击 `Login in and open Trae` 完成登录
|
||||
4. 回到刚才的网页,点击 `Save token to clipboard` 获取并保存登录凭证到剪贴板
|
||||
|
||||
### 运行代理服务
|
||||
|
||||
```shell
|
||||
# 克隆本项目仓库
|
||||
git clone https://github.com/A-23187/trae-api.git
|
||||
cd trae-api
|
||||
|
||||
# 编辑环境变量,填入前面通过脚本获取的凭证信息
|
||||
cp .env.example .env
|
||||
vim .env
|
||||
|
||||
# 运行服务,默认运行在 8000 端口
|
||||
uv run server.py
|
||||
```
|
||||
|
||||
### 设置 chat 客户端
|
||||
|
||||
> 以 [Cherry Studio](https://cherry-ai.com) 为例
|
||||
|
||||
1. 设置 > 模型服务 > 添加提供商 > 提供商类型选择 OpenAI
|
||||
2. API 密钥填入 `TRAE_IDE_TOKEN`
|
||||
3. API 地址填入 `http://localhost:8000`
|
||||
4. 添加模型 > 模型 ID 填入 `gpt-4o`,支持的模型可以通过 `GET /v1/models` 获取
|
||||
|
||||
## API 说明
|
||||
|
||||
- `POST /v1/chat/completions` 创建聊天补全
|
||||
- `GET /v1/models` 列出可用模型
|
||||
|
||||
## 其他
|
||||
|
||||
### 直接使用 uvicorn 运行
|
||||
|
||||
```shell
|
||||
uv sync
|
||||
source .venv/bin/activate
|
||||
|
||||
uvicorn --host 0.0.0.0 --port 8000 --reload --log-level debug src.app:app
|
||||
```
|
||||
|
||||
### 使用 docker 部署
|
||||
|
||||
|
||||
## 免责声明
|
||||
|
||||
- 本项目仅供学习研究使用,请遵循 Trae 的使用条款
|
||||
|
||||
## 许可证
|
||||
|
||||
[MIT License](https://github.com/A-23187/trae-api/blob/main/LICENSE)
|
62
auth.js
Normal file
62
auth.js
Normal file
@@ -0,0 +1,62 @@
|
||||
// ==UserScript==
|
||||
// @name 获取并保存 Trae 登录凭证
|
||||
// @namespace a23187.cn
|
||||
// @version 0.1.0
|
||||
// @description 获取并保存 Trae 登录凭证
|
||||
// @author A23187
|
||||
// @match https://www.trae.ai/authorization?*
|
||||
// @match https://www.trae.com.cn/authorization?*
|
||||
// @icon https://www.google.com/s2/favicons?sz=64&domain=trae.ai
|
||||
// @grant GM_setClipboard
|
||||
// @license MIT
|
||||
// ==/UserScript==
|
||||
|
||||
(function () {
|
||||
'use strict';
|
||||
async function getRefreshToken(clientId) {
|
||||
const resp = await fetch('https://www.trae.ai/cloudide/api/v3/trae/oauth/GetRefreshToken', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({ clientID: clientId }),
|
||||
}).then((resp) => resp.json());
|
||||
return resp.Result.RefreshToken;
|
||||
}
|
||||
async function exchangeToken(clientId, refreshToken) {
|
||||
const resp = await fetch('https://api-sg-central.trae.ai/cloudide/api/v3/trae/oauth/ExchangeToken', {
|
||||
method: 'POST',
|
||||
headers: { 'Content-Type': 'application/json' },
|
||||
body: JSON.stringify({
|
||||
ClientID: clientId, RefreshToken: refreshToken, ClientSecret: '-', UserID: '',
|
||||
}),
|
||||
}).then((resp) => resp.json());
|
||||
return resp.Result.Token;
|
||||
}
|
||||
const id = setInterval(() => {
|
||||
const mainTitleDiv = document.getElementsByClassName('main-title')[0];
|
||||
if (mainTitleDiv === undefined || mainTitleDiv?.innerText !== 'Login Successful') {
|
||||
return;
|
||||
}
|
||||
const saveTokenBtn = document.createElement('button');
|
||||
mainTitleDiv.parentElement.appendChild(saveTokenBtn);
|
||||
saveTokenBtn.innerText = 'Save token to clipboard';
|
||||
saveTokenBtn.onclick = async () => {
|
||||
const params = new URLSearchParams(document.location.search);
|
||||
const clientId = params.get('client_id');
|
||||
const refreshToken = await getRefreshToken(clientId);
|
||||
const token = await exchangeToken(clientId, refreshToken);
|
||||
GM_setClipboard(`
|
||||
TRAE_APP_ID = "6eefa01c-1036-4c7e-9ca5-d891f63bfcd8"
|
||||
TRAE_DEVICE_BRAND = "${params.get('x_device_brand')}"
|
||||
TRAE_DEVICE_CPU = "Intel"
|
||||
TRAE_DEVICE_ID = "${params.get('x_device_id')}"
|
||||
TRAE_DEVICE_TYPE = "${params.get('x_device_type')}"
|
||||
TRAE_IDE_TOKEN = "${token}"
|
||||
TRAE_IDE_VERSION = ""
|
||||
TRAE_IDE_VERSION_CODE = ""
|
||||
TRAE_IDE_VERSION_TYPE = ""
|
||||
TRAE_MACHINE_ID = "${params.get('x_machine_id')}"
|
||||
TRAE_OS_VERSION = "${params.get('x_os_version')}"`, 'text', () => alert('已复制'));
|
||||
};
|
||||
clearInterval(id);
|
||||
}, 1000);
|
||||
})();
|
16
pyproject.toml
Normal file
16
pyproject.toml
Normal file
@@ -0,0 +1,16 @@
|
||||
[project]
|
||||
name = "trae-api"
|
||||
version = "0.1.0"
|
||||
description = "Make trae's builtin models openai api compatible"
|
||||
readme = "README.md"
|
||||
requires-python = ">=3.13.2"
|
||||
dependencies = [
|
||||
"fastapi>=0.115.12",
|
||||
"httpx>=0.28.1",
|
||||
"httpx-sse>=0.4.0",
|
||||
"python-dotenv>=1.1.0",
|
||||
"uvicorn>=0.34.0",
|
||||
]
|
||||
|
||||
[tool.black]
|
||||
line-length = 120
|
4
server.py
Normal file
4
server.py
Normal file
@@ -0,0 +1,4 @@
|
||||
import uvicorn
|
||||
|
||||
if __name__ == "__main__":
|
||||
uvicorn.run("src.app:app", host="0.0.0.0", port=8000)
|
0
src/__init__.py
Normal file
0
src/__init__.py
Normal file
151
src/app.py
Normal file
151
src/app.py
Normal file
@@ -0,0 +1,151 @@
|
||||
import json
|
||||
import time
|
||||
import uuid
|
||||
from datetime import datetime
|
||||
|
||||
import httpx_sse
|
||||
from fastapi import FastAPI, Header
|
||||
from fastapi.responses import StreamingResponse
|
||||
from httpx import AsyncClient
|
||||
|
||||
from .env import (
|
||||
TRAE_APP_ID,
|
||||
TRAE_DEVICE_BRAND,
|
||||
TRAE_DEVICE_CPU,
|
||||
TRAE_DEVICE_ID,
|
||||
TRAE_DEVICE_TYPE,
|
||||
TRAE_IDE_TOKEN,
|
||||
TRAE_IDE_VERSION,
|
||||
TRAE_IDE_VERSION_CODE,
|
||||
TRAE_IDE_VERSION_TYPE,
|
||||
TRAE_MACHINE_ID,
|
||||
TRAE_OS_VERSION,
|
||||
)
|
||||
from .types import (
|
||||
ChatCompletionChunk,
|
||||
ChatCompletionChunkChoice,
|
||||
ChatCompletionRequest,
|
||||
Model,
|
||||
)
|
||||
|
||||
app = FastAPI(
|
||||
title="Trae2OpenAI Proxy",
|
||||
description="A api proxy to make trae's builtin models openai compatible",
|
||||
version="0.1.0",
|
||||
)
|
||||
|
||||
|
||||
@app.get("/v1/models")
|
||||
async def list_models(ide_token: str = Header(TRAE_IDE_TOKEN, alias="Authorization")) -> list[Model]:
|
||||
ide_token = ide_token.removeprefix("Bearer ")
|
||||
async with AsyncClient() as client:
|
||||
response = await client.get(
|
||||
"https://trae-api-sg.mchost.guru/api/ide/v1/model_list",
|
||||
params={"type": "llm_raw_chat"},
|
||||
headers={
|
||||
"x-app-id": TRAE_APP_ID,
|
||||
"x-device-brand": TRAE_DEVICE_BRAND,
|
||||
"x-device-cpu": TRAE_DEVICE_CPU,
|
||||
"x-device-id": TRAE_DEVICE_ID,
|
||||
"x-device-type": TRAE_DEVICE_TYPE,
|
||||
"x-ide-token": ide_token,
|
||||
"x-ide-version": TRAE_IDE_VERSION,
|
||||
"x-ide-version-code": TRAE_IDE_VERSION_CODE,
|
||||
"x-ide-version-type": TRAE_IDE_VERSION_TYPE,
|
||||
"x-machine-id": TRAE_MACHINE_ID,
|
||||
"x-os-version": TRAE_OS_VERSION,
|
||||
},
|
||||
)
|
||||
return [Model(created=0, id=model["name"]) for model in response.json()["model_configs"]]
|
||||
|
||||
|
||||
@app.post("/v1/chat/completions")
|
||||
async def create_chat_completions(
|
||||
request: ChatCompletionRequest, ide_token: str = Header(TRAE_IDE_TOKEN, alias="Authorization")
|
||||
) -> StreamingResponse:
|
||||
ide_token = ide_token.removeprefix("Bearer ")
|
||||
current_turn = sum(1 for msg in request.messages if msg.role == "user")
|
||||
last_assistant_message = next(filter(lambda msg: msg.role == "assistant", reversed(request.messages)), None)
|
||||
|
||||
async def stream_response():
|
||||
async with AsyncClient() as client:
|
||||
async with httpx_sse.aconnect_sse(
|
||||
client,
|
||||
"POST",
|
||||
"https://trae-api-sg.mchost.guru/api/ide/v1/chat",
|
||||
headers={
|
||||
"x-app-id": TRAE_APP_ID,
|
||||
"x-device-brand": TRAE_DEVICE_BRAND,
|
||||
"x-device-cpu": TRAE_DEVICE_CPU,
|
||||
"x-device-id": TRAE_DEVICE_ID,
|
||||
"x-device-type": TRAE_DEVICE_TYPE,
|
||||
"x-ide-token": ide_token,
|
||||
"x-ide-version": TRAE_IDE_VERSION,
|
||||
"x-ide-version-code": TRAE_IDE_VERSION_CODE,
|
||||
"x-ide-version-type": TRAE_IDE_VERSION_TYPE,
|
||||
"x-machine-id": TRAE_MACHINE_ID,
|
||||
"x-os-version": TRAE_OS_VERSION,
|
||||
},
|
||||
json={
|
||||
"chat_history": [msg.model_dump() for msg in request.messages[:-1]],
|
||||
"context_resolvers": [],
|
||||
"conversation_id": str(uuid.uuid4()),
|
||||
"current_turn": current_turn,
|
||||
"generate_suggested_questions": False,
|
||||
"intent_name": "general_qa_intent",
|
||||
"is_preset": True,
|
||||
"last_llm_response_info": (
|
||||
{"turn": current_turn - 1, "is_error": False, "response": last_assistant_message.content}
|
||||
if last_assistant_message
|
||||
else {}
|
||||
),
|
||||
"model_name": request.model,
|
||||
"multi_media": [],
|
||||
"provider": "",
|
||||
"session_id": str(uuid.uuid4()),
|
||||
"user_input": request.messages[-1].content,
|
||||
"valid_turns": list(range(current_turn)),
|
||||
"variables": json.dumps(
|
||||
{"locale": "zh-cn", "current_time": datetime.now().strftime("%Y%m%d %H:%M:%S %A")}
|
||||
),
|
||||
},
|
||||
) as response:
|
||||
chunk = ChatCompletionChunk(
|
||||
choices=[],
|
||||
created=int(time.time()),
|
||||
id="",
|
||||
model=request.model,
|
||||
)
|
||||
async for sse in response.aiter_sse():
|
||||
sse_data = sse.json()
|
||||
if sse.event == "metadata":
|
||||
chunk.id = str(sse_data["prompt_completion_id"])
|
||||
elif sse.event == "output":
|
||||
content = sse_data["response"]
|
||||
reasoning_content = sse_data["reasoning_content"]
|
||||
chunk.choices = [
|
||||
ChatCompletionChunkChoice(
|
||||
delta={"role": "assistant", "content": content, "reasoning_content": reasoning_content}
|
||||
)
|
||||
]
|
||||
yield f"data: {chunk.model_dump_json()}\n\n"
|
||||
elif sse.event == "token_usage":
|
||||
chunk.choices = []
|
||||
chunk.usage = {
|
||||
"completion_tokens": sse_data["completion_tokens"],
|
||||
"prompt_tokens": sse_data["prompt_tokens"],
|
||||
"total_tokens": sse_data["total_tokens"],
|
||||
}
|
||||
yield f"data: {chunk.model_dump_json()}\n\n"
|
||||
elif sse.event == "done":
|
||||
chunk.choices = [ChatCompletionChunkChoice(delta={}, finish_reason="stop")]
|
||||
yield f"data: {chunk.model_dump_json()}\n\ndata: [DONE]\n\n"
|
||||
elif sse.event == "error":
|
||||
chunk.choices = [
|
||||
ChatCompletionChunkChoice(
|
||||
delta={"role": "assistant", "content": sse.data}, finish_reason="error"
|
||||
)
|
||||
]
|
||||
yield f"data: {chunk.model_dump_json()}\n\ndata: [DONE]\n\n"
|
||||
|
||||
return StreamingResponse(stream_response(), media_type="text/event-stream")
|
17
src/env.py
Normal file
17
src/env.py
Normal file
@@ -0,0 +1,17 @@
|
||||
import os
|
||||
|
||||
from dotenv import load_dotenv
|
||||
|
||||
load_dotenv()
|
||||
|
||||
TRAE_APP_ID = str(os.getenv("TRAE_APP_ID"))
|
||||
TRAE_DEVICE_BRAND = str(os.getenv("TRAE_DEVICE_BRAND"))
|
||||
TRAE_DEVICE_CPU = str(os.getenv("TRAE_DEVICE_CPU"))
|
||||
TRAE_DEVICE_ID = str(os.getenv("TRAE_DEVICE_ID"))
|
||||
TRAE_DEVICE_TYPE = str(os.getenv("TRAE_DEVICE_TYPE"))
|
||||
TRAE_IDE_TOKEN = str(os.getenv("TRAE_IDE_TOKEN"))
|
||||
TRAE_IDE_VERSION = str(os.getenv("TRAE_IDE_VERSION"))
|
||||
TRAE_IDE_VERSION_CODE = str(os.getenv("TRAE_IDE_VERSION_CODE"))
|
||||
TRAE_IDE_VERSION_TYPE = str(os.getenv("TRAE_IDE_VERSION_TYPE"))
|
||||
TRAE_MACHINE_ID = str(os.getenv("TRAE_MACHINE_ID"))
|
||||
TRAE_OS_VERSION = str(os.getenv("TRAE_OS_VERSION"))
|
52
src/types.py
Normal file
52
src/types.py
Normal file
@@ -0,0 +1,52 @@
|
||||
from typing import Any, Literal
|
||||
|
||||
from pydantic import BaseModel
|
||||
|
||||
|
||||
class ChatMessage(BaseModel):
|
||||
content: str | list[dict[str, Any]]
|
||||
name: str | None = None
|
||||
role: Literal["system", "user", "assistant", "tool", "function"]
|
||||
|
||||
|
||||
class ChatCompletionRequest(BaseModel):
|
||||
model: str
|
||||
messages: list[ChatMessage]
|
||||
max_completion_tokens: int | None = None
|
||||
modalities: list[str] | None = None
|
||||
response_format: dict[str, Any] | None = None
|
||||
seed: int | None = None
|
||||
stop: str | list[str] | None = None
|
||||
stream: bool | None = False
|
||||
stream_options: dict[str, Any] | None = None
|
||||
temperature: float | None = 1
|
||||
tool_choice: Literal["none", "auto", "required"] | dict[str, Any] | None = None
|
||||
tools: list[dict[str, Any]] | None = None
|
||||
top_k: int | None = 20
|
||||
top_p: float | None = 1
|
||||
web_search_options: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class ChatCompletionChunkChoice(BaseModel):
|
||||
delta: dict[str, Any]
|
||||
finish_reason: str | None = None
|
||||
index: int = 0
|
||||
logprobs: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class ChatCompletionChunk(BaseModel):
|
||||
choices: list[ChatCompletionChunkChoice]
|
||||
created: int
|
||||
id: str
|
||||
model: str
|
||||
object: str = "chat.completion.chunk"
|
||||
service_tier: str | None = None
|
||||
system_fingerprint: str = ""
|
||||
usage: dict[str, Any] | None = None
|
||||
|
||||
|
||||
class Model(BaseModel):
|
||||
created: int
|
||||
id: str
|
||||
object: str = "model"
|
||||
owned_by: str = "trae"
|
252
uv.lock
generated
Normal file
252
uv.lock
generated
Normal file
@@ -0,0 +1,252 @@
|
||||
version = 1
|
||||
revision = 1
|
||||
requires-python = ">=3.13.2"
|
||||
|
||||
[[package]]
|
||||
name = "annotated-types"
|
||||
version = "0.7.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/ee/67/531ea369ba64dcff5ec9c3402f9f51bf748cec26dde048a2f973a4eea7f5/annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89", size = 16081 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/78/b6/6307fbef88d9b5ee7421e68d78a9f162e0da4900bc5f5793f6d3d0e34fb8/annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53", size = 13643 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.9.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
{ name = "sniffio" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/7d/4c1bd541d4dffa1b52bd83fb8527089e097a106fc90b467a7313b105f840/anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028", size = 190949 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/a1/ee/48ca1a7c89ffec8b6a0c5d02b89c305671d5ffd8d3c94acf8b8c408575bb/anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c", size = 100916 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2025.1.31"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/1c/ab/c9f1e32b7b1bf505bf26f0ef697775960db7932abeb7b516de930ba2705f/certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651", size = 167577 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/38/fc/bce832fd4fd99766c04d1ee0eead6b0ec6486fb100ae5e74c1d91292b982/certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe", size = 166393 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "click"
|
||||
version = "8.1.8"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "colorama"
|
||||
version = "0.4.6"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "fastapi"
|
||||
version = "0.115.12"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "pydantic" },
|
||||
{ name = "starlette" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/55/ae499352d82338331ca1e28c7f4a63bfd09479b16395dce38cf50a39e2c2/fastapi-0.115.12.tar.gz", hash = "sha256:1e2c2a2646905f9e83d32f04a3f86aff4a286669c6c950ca95b5fd68c2602681", size = 295236 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/50/b3/b51f09c2ba432a576fe63758bddc81f78f0c6309d9e5c10d194313bf021e/fastapi-0.115.12-py3-none-any.whl", hash = "sha256:e94613d6c05e27be7ffebdd6ea5f388112e5e430c8f7d6494a9d1d88d43e814d", size = 95164 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "h11"
|
||||
version = "0.14.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f5/38/3af3d3633a34a3316095b39c8e8fb4853a28a536e55d347bd8d8e9a14b03/h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d", size = 100418 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/95/04/ff642e65ad6b90db43e668d70ffb6736436c7ce41fcc549f4e9472234127/h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761", size = 58259 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpcore"
|
||||
version = "1.0.7"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "certifi" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/6a/41/d7d0a89eb493922c37d343b607bc1b5da7f5be7e383740b4753ad8943e90/httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c", size = 85196 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/87/f5/72347bc88306acb359581ac4d52f23c0ef445b57157adedb9aee0cd689d2/httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd", size = 78551 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx"
|
||||
version = "0.28.1"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
{ name = "certifi" },
|
||||
{ name = "httpcore" },
|
||||
{ name = "idna" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b1/df/48c586a5fe32a0f01324ee087459e112ebb7224f646c0b5023f5e79e9956/httpx-0.28.1.tar.gz", hash = "sha256:75e98c5f16b0f35b567856f597f06ff2270a374470a5c2392242528e3e3e42fc", size = 141406 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/2a/39/e50c7c3a983047577ee07d2a9e53faf5a69493943ec3f6a384bdc792deb2/httpx-0.28.1-py3-none-any.whl", hash = "sha256:d909fcccc110f8c7faf814ca82a9a4d816bc5a6dbfea25d6591d6985b8ba59ad", size = 73517 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "httpx-sse"
|
||||
version = "0.4.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4c/60/8f4281fa9bbf3c8034fd54c0e7412e66edbab6bc74c4996bd616f8d0406e/httpx-sse-0.4.0.tar.gz", hash = "sha256:1e81a3a3070ce322add1d3529ed42eb5f70817f45ed6ec915ab753f961139721", size = 12624 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/e1/9b/a181f281f65d776426002f330c31849b86b31fc9d848db62e16f03ff739f/httpx_sse-0.4.0-py3-none-any.whl", hash = "sha256:f329af6eae57eaa2bdfd962b42524764af68075ea87370a2de920af5341e318f", size = 7819 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "idna"
|
||||
version = "3.10"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/f1/70/7703c29685631f5a7590aa73f1f1d3fa9a380e654b86af429e0934a32f7d/idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9", size = 190490 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/c6/c88e154df9c4e1a2a66ccf0005a88dfb2650c1dffb6f5ce603dfbd452ce3/idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3", size = 70442 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic"
|
||||
version = "2.11.2"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "annotated-types" },
|
||||
{ name = "pydantic-core" },
|
||||
{ name = "typing-extensions" },
|
||||
{ name = "typing-inspection" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/b0/41/832125a41fe098b58d1fdd04ae819b4dc6b34d6b09ed78304fd93d4bc051/pydantic-2.11.2.tar.gz", hash = "sha256:2138628e050bd7a1e70b91d4bf4a91167f4ad76fdb83209b107c8d84b854917e", size = 784742 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/bf/c2/0f3baea344d0b15e35cb3e04ad5b953fa05106b76efbf4c782a3f47f22f5/pydantic-2.11.2-py3-none-any.whl", hash = "sha256:7f17d25846bcdf89b670a86cdfe7b29a9f1c9ca23dee154221c9aa81845cfca7", size = 443295 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pydantic-core"
|
||||
version = "2.33.1"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/17/19/ed6a078a5287aea7922de6841ef4c06157931622c89c2a47940837b5eecd/pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df", size = 434395 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/7a/24/eed3466a4308d79155f1cdd5c7432c80ddcc4530ba8623b79d5ced021641/pydantic_core-2.33.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:70af6a21237b53d1fe7b9325b20e65cbf2f0a848cf77bed492b029139701e66a", size = 2033551 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ab/14/df54b1a0bc9b6ded9b758b73139d2c11b4e8eb43e8ab9c5847c0a2913ada/pydantic_core-2.33.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:282b3fe1bbbe5ae35224a0dbd05aed9ccabccd241e8e6b60370484234b456266", size = 1852785 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/fa/96/e275f15ff3d34bb04b0125d9bc8848bf69f25d784d92a63676112451bfb9/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4b315e596282bbb5822d0c7ee9d255595bd7506d1cb20c2911a4da0b970187d3", size = 1897758 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/b7/d8/96bc536e975b69e3a924b507d2a19aedbf50b24e08c80fb00e35f9baaed8/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:1dfae24cf9921875ca0ca6a8ecb4bb2f13c855794ed0d468d6abbec6e6dcd44a", size = 1986109 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/90/72/ab58e43ce7e900b88cb571ed057b2fcd0e95b708a2e0bed475b10130393e/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6dd8ecfde08d8bfadaea669e83c63939af76f4cf5538a72597016edfa3fad516", size = 2129159 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/dc/3f/52d85781406886c6870ac995ec0ba7ccc028b530b0798c9080531b409fdb/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2f593494876eae852dc98c43c6f260f45abdbfeec9e4324e31a481d948214764", size = 2680222 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/f4/56/6e2ef42f363a0eec0fd92f74a91e0ac48cd2e49b695aac1509ad81eee86a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:948b73114f47fd7016088e5186d13faf5e1b2fe83f5e320e371f035557fd264d", size = 2006980 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/4c/c0/604536c4379cc78359f9ee0aa319f4aedf6b652ec2854953f5a14fc38c5a/pydantic_core-2.33.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e11f3864eb516af21b01e25fac915a82e9ddad3bb0fb9e95a246067398b435a4", size = 2120840 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/1f/46/9eb764814f508f0edfb291a0f75d10854d78113fa13900ce13729aaec3ae/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:549150be302428b56fdad0c23c2741dcdb5572413776826c965619a25d9c6bde", size = 2072518 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/42/e3/fb6b2a732b82d1666fa6bf53e3627867ea3131c5f39f98ce92141e3e3dc1/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:495bc156026efafd9ef2d82372bd38afce78ddd82bf28ef5276c469e57c0c83e", size = 2248025 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/5c/9d/fbe8fe9d1aa4dac88723f10a921bc7418bd3378a567cb5e21193a3c48b43/pydantic_core-2.33.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ec79de2a8680b1a67a07490bddf9636d5c2fab609ba8c57597e855fa5fa4dacd", size = 2254991 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/aa/99/07e2237b8a66438d9b26482332cda99a9acccb58d284af7bc7c946a42fd3/pydantic_core-2.33.1-cp313-cp313-win32.whl", hash = "sha256:ee12a7be1742f81b8a65b36c6921022301d466b82d80315d215c4c691724986f", size = 1915262 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/8a/f4/e457a7849beeed1e5defbcf5051c6f7b3c91a0624dd31543a64fc9adcf52/pydantic_core-2.33.1-cp313-cp313-win_amd64.whl", hash = "sha256:ede9b407e39949d2afc46385ce6bd6e11588660c26f80576c11c958e6647bc40", size = 1956626 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/20/d0/e8d567a7cff7b04e017ae164d98011f1e1894269fe8e90ea187a3cbfb562/pydantic_core-2.33.1-cp313-cp313-win_arm64.whl", hash = "sha256:aa687a23d4b7871a00e03ca96a09cad0f28f443690d300500603bd0adba4b523", size = 1909590 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/ef/fd/24ea4302d7a527d672c5be06e17df16aabfb4e9fdc6e0b345c21580f3d2a/pydantic_core-2.33.1-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:401d7b76e1000d0dd5538e6381d28febdcacb097c8d340dde7d7fc6e13e9f95d", size = 1812963 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/5f/95/4fbc2ecdeb5c1c53f1175a32d870250194eb2fdf6291b795ab08c8646d5d/pydantic_core-2.33.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7aeb055a42d734c0255c9e489ac67e75397d59c6fbe60d155851e9782f276a9c", size = 1986896 },
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/71/ae/fe31e7f4a62431222d8f65a3bd02e3fa7e6026d154a00818e6d30520ea77/pydantic_core-2.33.1-cp313-cp313t-win_amd64.whl", hash = "sha256:338ea9b73e6e109f15ab439e62cb3b78aa752c7fd9536794112e14bee02c8d18", size = 1931810 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "python-dotenv"
|
||||
version = "1.1.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/88/2c/7bb1416c5620485aa793f2de31d3df393d3686aa8a8506d11e10e13c5baf/python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5", size = 39920 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/1e/18/98a99ad95133c6a6e2005fe89faedf294a748bd5dc803008059409ac9b1e/python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d", size = 20256 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "sniffio"
|
||||
version = "1.3.1"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/a2/87/a6771e1546d97e7e041b6ae58d80074f81b7d5121207425c964ddf5cfdbd/sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc", size = 20372 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/e9/44/75a9c9421471a6c4805dbf2356f7c181a29c1879239abab1ea2cc8f38b40/sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2", size = 10235 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "starlette"
|
||||
version = "0.46.1"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "anyio" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/04/1b/52b27f2e13ceedc79a908e29eac426a63465a1a01248e5f24aa36a62aeb3/starlette-0.46.1.tar.gz", hash = "sha256:3c88d58ee4bd1bb807c0d1acb381838afc7752f9ddaec81bbe4383611d833230", size = 2580102 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/a0/4b/528ccf7a982216885a1ff4908e886b8fb5f19862d1962f56a3fce2435a70/starlette-0.46.1-py3-none-any.whl", hash = "sha256:77c74ed9d2720138b25875133f3a2dae6d854af2ec37dceb56aef370c1d8a227", size = 71995 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "trae-api"
|
||||
version = "0.1.0"
|
||||
source = { virtual = "." }
|
||||
dependencies = [
|
||||
{ name = "fastapi" },
|
||||
{ name = "httpx" },
|
||||
{ name = "httpx-sse" },
|
||||
{ name = "python-dotenv" },
|
||||
{ name = "uvicorn" },
|
||||
]
|
||||
|
||||
[package.metadata]
|
||||
requires-dist = [
|
||||
{ name = "fastapi", specifier = ">=0.115.12" },
|
||||
{ name = "httpx", specifier = ">=0.28.1" },
|
||||
{ name = "httpx-sse", specifier = ">=0.4.0" },
|
||||
{ name = "python-dotenv", specifier = ">=1.1.0" },
|
||||
{ name = "uvicorn", specifier = ">=0.34.0" },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-extensions"
|
||||
version = "4.13.1"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/76/ad/cd3e3465232ec2416ae9b983f27b9e94dc8171d56ac99b345319a9475967/typing_extensions-4.13.1.tar.gz", hash = "sha256:98795af00fb9640edec5b8e31fc647597b4691f099ad75f469a2616be1a76dff", size = 106633 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/df/c5/e7a0b0f5ed69f94c8ab7379c599e6036886bffcde609969a5325f47f1332/typing_extensions-4.13.1-py3-none-any.whl", hash = "sha256:4b6cf02909eb5495cfbc3f6e8fd49217e6cc7944e145cdda8caa3734777f9e69", size = 45739 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "typing-inspection"
|
||||
version = "0.4.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/82/5c/e6082df02e215b846b4b8c0b887a64d7d08ffaba30605502639d44c06b82/typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122", size = 76222 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/31/08/aa4fdfb71f7de5176385bd9e90852eaf6b5d622735020ad600f2bab54385/typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f", size = 14125 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "uvicorn"
|
||||
version = "0.34.0"
|
||||
source = { registry = "https://pypi.tuna.tsinghua.edu.cn/simple" }
|
||||
dependencies = [
|
||||
{ name = "click" },
|
||||
{ name = "h11" },
|
||||
]
|
||||
sdist = { url = "https://pypi.tuna.tsinghua.edu.cn/packages/4b/4d/938bd85e5bf2edeec766267a5015ad969730bb91e31b44021dfe8b22df6c/uvicorn-0.34.0.tar.gz", hash = "sha256:404051050cd7e905de2c9a7e61790943440b3416f49cb409f965d9dcd0fa73e9", size = 76568 }
|
||||
wheels = [
|
||||
{ url = "https://pypi.tuna.tsinghua.edu.cn/packages/61/14/33a3a1352cfa71812a3a21e8c9bfb83f60b0011f5e36f2b1399d51928209/uvicorn-0.34.0-py3-none-any.whl", hash = "sha256:023dc038422502fa28a09c7a30bf2b6991512da7dcdb8fd35fe57cfc154126f4", size = 62315 },
|
||||
]
|
Reference in New Issue
Block a user