modelscope-api 0.0.1__tar.gz → 0.0.2__tar.gz
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- modelscope_api-0.0.2/PKG-INFO +189 -0
- modelscope_api-0.0.2/README.md +162 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/pyproject.toml +19 -4
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/config.py +7 -0
- modelscope_api-0.0.2/src/modelscope_api/models/_sub_client.py +143 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/collection/collection.py +2 -2
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/collection/collection_client.py +2 -2
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/collection/collection_item.py +1 -1
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/collection/collection_item_client.py +2 -2
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/magicube/magicube_client.py +2 -2
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/modelscope_client.py +86 -17
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/studio/environment_variable_client.py +2 -2
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/studio/studio.py +8 -1
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/studio/studio_client.py +18 -2
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/user/user_client.py +2 -2
- modelscope_api-0.0.2/src/modelscope_api.egg-info/PKG-INFO +189 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api.egg-info/SOURCES.txt +1 -2
- modelscope_api-0.0.1/PKG-INFO +0 -20
- modelscope_api-0.0.1/README.md +0 -0
- modelscope_api-0.0.1/src/modelscope_api/models/_sub_client.py +0 -71
- modelscope_api-0.0.1/src/modelscope_api.egg-info/PKG-INFO +0 -20
- modelscope_api-0.0.1/test/test_client.py +0 -20
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/LICENSE +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/setup.cfg +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/base.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/collection/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/collection/collection.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/collection/collection_item.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/magicube/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/magicube/magicube_blance.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/studio/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/studio/base_image.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/studio/environment_variable.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/studio/hardware.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/studio/logs.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/studio/sdk.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/studio/studio.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/user/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/data_models/user/user.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/exceptions.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/collection/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/magicube/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/studio/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/user/__init__.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/utils/regex.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/utils/typing.py +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api.egg-info/dependency_links.txt +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api.egg-info/requires.txt +0 -0
- {modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api.egg-info/top_level.txt +0 -0
|
@@ -0,0 +1,189 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: modelscope-api
|
|
3
|
+
Version: 0.0.2
|
|
4
|
+
Summary: A Python async SDK that wraps the ModelScope API into a clean, type-safe interface.
|
|
5
|
+
Author-email: Jerry <wujr24@m.fudan.edu.cn>
|
|
6
|
+
License: MIT
|
|
7
|
+
Project-URL: Homepage, https://github.com/Jerry-Wu-GitHub/modelscope-api
|
|
8
|
+
Project-URL: Repository, https://github.com/Jerry-Wu-GitHub/modelscope-api.git
|
|
9
|
+
Classifier: Development Status :: 3 - Alpha
|
|
10
|
+
Classifier: Intended Audience :: Developers
|
|
11
|
+
Classifier: Intended Audience :: Science/Research
|
|
12
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
13
|
+
Classifier: Operating System :: OS Independent
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
18
|
+
Requires-Python: >=3.11
|
|
19
|
+
Description-Content-Type: text/markdown
|
|
20
|
+
License-File: LICENSE
|
|
21
|
+
Requires-Dist: fake-useragent
|
|
22
|
+
Requires-Dist: httpx
|
|
23
|
+
Requires-Dist: python-dotenv
|
|
24
|
+
Requires-Dist: typing-extensions
|
|
25
|
+
Requires-Dist: yarl
|
|
26
|
+
Dynamic: license-file
|
|
27
|
+
|
|
28
|
+
# ModelScope API Python SDK
|
|
29
|
+
|
|
30
|
+
[](https://badge.fury.io/py/modelscope-api)
|
|
31
|
+
[](LICENSE)
|
|
32
|
+
[](https://www.python.org/downloads/)
|
|
33
|
+
|
|
34
|
+
一个**异步**、**类型安全**的 Python SDK,用于调用 [ModelScope 开放 API](https://modelscope.cn/docs/openapi)。
|
|
35
|
+
|
|
36
|
+
它提供了直观的对象化接口,覆盖了合集、创空间、魔粒、用户等核心模块,让您能以 Pythonic 的方式与 ModelScope 平台交互。
|
|
37
|
+
|
|
38
|
+
## ✨ 特性
|
|
39
|
+
|
|
40
|
+
- 🚀 **全异步** – 基于 `httpx.AsyncClient`,支持高并发请求。
|
|
41
|
+
- 🧩 **模块化设计** – 按业务领域拆分:`User`、`Magicube`、`Studio`、`Collection` 等。
|
|
42
|
+
- 📦 **类型安全** – 使用 Pydantic 数据模型,提供 IDE 自动补全和校验。
|
|
43
|
+
- 🔐 **自动认证** – 通过环境变量或构造参数传入 API Token,自动注入请求头。
|
|
44
|
+
- 🛠️ **开箱即用** – 支持 `.env` 配置,内置随机 UA 伪装,简化开发。
|
|
45
|
+
|
|
46
|
+
## 📦 安装
|
|
47
|
+
|
|
48
|
+
```bash
|
|
49
|
+
pip install modelscope-api
|
|
50
|
+
```
|
|
51
|
+
|
|
52
|
+
或直接从源码安装:
|
|
53
|
+
|
|
54
|
+
```bash
|
|
55
|
+
git clone https://github.com/Jerry-Wu-GitHub/modelscope-api.git
|
|
56
|
+
cd modelscope-api
|
|
57
|
+
pip install -e .
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
## 🚀 快速开始
|
|
61
|
+
|
|
62
|
+
### 1. 获取 API Token
|
|
63
|
+
|
|
64
|
+
访问 [ModelScope 个人设置](https://www.modelscope.cn/my/settings/token) 生成您的 `MODELSCOPE_API_TOKEN`。
|
|
65
|
+
|
|
66
|
+
### 2. 配置环境变量(推荐)
|
|
67
|
+
|
|
68
|
+
在项目根目录创建 `.env` 文件:
|
|
69
|
+
|
|
70
|
+
```env
|
|
71
|
+
MODELSCOPE_API_TOKEN=your_token_here
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
也可以直接在代码中传入:
|
|
75
|
+
|
|
76
|
+
```python
|
|
77
|
+
from modelscope_api import ModelScopeClient
|
|
78
|
+
|
|
79
|
+
client = ModelScopeClient(api_key="your_token_here")
|
|
80
|
+
```
|
|
81
|
+
|
|
82
|
+
### 3. 基础用法
|
|
83
|
+
|
|
84
|
+
```python
|
|
85
|
+
import asyncio
|
|
86
|
+
from modelscope_api import ModelScopeClient
|
|
87
|
+
|
|
88
|
+
async def main():
|
|
89
|
+
async with ModelScopeClient() as client:
|
|
90
|
+
# 获取当前用户信息
|
|
91
|
+
user_info = await client.user.get_current_user_info()
|
|
92
|
+
print(f"当前用户: {user_info.username}")
|
|
93
|
+
|
|
94
|
+
# 查询魔粒余额
|
|
95
|
+
balance = await client.magicube.query_magicube_balance()
|
|
96
|
+
print(f"可用魔粒: {balance.available_balance}")
|
|
97
|
+
|
|
98
|
+
# 搜索创空间
|
|
99
|
+
studios = await client.studio.search_studio_infos(search="chatbot", owner="iic")
|
|
100
|
+
for studio in studios:
|
|
101
|
+
print(f"- {studio.display_name} ({studio.id})")
|
|
102
|
+
|
|
103
|
+
if __name__ == "__main__":
|
|
104
|
+
asyncio.run(main())
|
|
105
|
+
```
|
|
106
|
+
|
|
107
|
+
## 📖 API 概览
|
|
108
|
+
|
|
109
|
+
SDK 的所有功能通过 `ModelScopeClient` 聚合,您可以通过其属性访问各子客户端:
|
|
110
|
+
|
|
111
|
+
| 子客户端 | 说明 | 主要方法 |
|
|
112
|
+
| ------------------- | ------------ | ------------------------------------------------------------ |
|
|
113
|
+
| `client.user` | 用户信息 | `get_current_user_info()` |
|
|
114
|
+
| `client.magicube` | 魔粒(积分) | `query_magicube_balance()` |
|
|
115
|
+
| `client.studio` | 创空间管理 | `search_studio_infos()`, `create_studio()`, `get_studio()` |
|
|
116
|
+
| `client.collection` | 合集管理 | `search_collection_infos()`, `create_collection()`, `get_collection()` |
|
|
117
|
+
|
|
118
|
+
每个子客户端返回的数据均为 Pydantic 模型,可直接访问属性。
|
|
119
|
+
|
|
120
|
+
### 详细示例:操作创空间
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
async def studio_example(client):
|
|
124
|
+
# 创建创空间
|
|
125
|
+
studio = await client.studio.create_studio(
|
|
126
|
+
repo_name="my-awesome-space",
|
|
127
|
+
display_name="我的炫酷空间",
|
|
128
|
+
visibility="public",
|
|
129
|
+
sdk_type="gradio",
|
|
130
|
+
hardware="platform/2v-cpu-16g-mem"
|
|
131
|
+
)
|
|
132
|
+
print(f"创建成功: {studio.id}")
|
|
133
|
+
|
|
134
|
+
# 部署
|
|
135
|
+
runtime = await studio.deploy(timeout=30)
|
|
136
|
+
print(f"部署状态: {runtime.status}")
|
|
137
|
+
|
|
138
|
+
# 查看日志
|
|
139
|
+
logs = await studio.get_logs("run", page_size=50)
|
|
140
|
+
for line in logs.logs:
|
|
141
|
+
print(line)
|
|
142
|
+
|
|
143
|
+
# 添加环境变量
|
|
144
|
+
await studio.variables.add("MY_KEY", "my_value")
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### 详细示例:操作合集
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
async def collection_example(client):
|
|
151
|
+
# 创建合集
|
|
152
|
+
collection = await client.collection.create_collection(
|
|
153
|
+
title="我的收藏",
|
|
154
|
+
visibility="private"
|
|
155
|
+
)
|
|
156
|
+
|
|
157
|
+
# 添加条目(模型)
|
|
158
|
+
failed = await collection.items.add_items([
|
|
159
|
+
{
|
|
160
|
+
"item_type": "model",
|
|
161
|
+
"item_object_id": "Qwen/Qwen3.8-27B",
|
|
162
|
+
"position": 1
|
|
163
|
+
}
|
|
164
|
+
])
|
|
165
|
+
if failed:
|
|
166
|
+
print("添加失败:", failed)
|
|
167
|
+
|
|
168
|
+
# 获取条目列表
|
|
169
|
+
items = await collection.items.get_items()
|
|
170
|
+
for item in items:
|
|
171
|
+
print(f"- {item.item_object_id}")
|
|
172
|
+
|
|
173
|
+
# 删除合集
|
|
174
|
+
await collection.delete()
|
|
175
|
+
```
|
|
176
|
+
|
|
177
|
+
## 🧪 运行测试
|
|
178
|
+
|
|
179
|
+
项目包含完整的测试用例,位于 `tests/` 目录。运行前请确保已设置有效的 `MODELSCOPE_API_TOKEN`。
|
|
180
|
+
|
|
181
|
+
> [!CAUTION]
|
|
182
|
+
>
|
|
183
|
+
> 测试用例里包含“删除创空间”,这是一个危险的操作,请确保您没有会受影响的创空间。
|
|
184
|
+
>
|
|
185
|
+
> 要实现该操作,需要使用“管理员权限”的 API Token。
|
|
186
|
+
|
|
187
|
+
## 📄 许可证
|
|
188
|
+
|
|
189
|
+
本项目使用 [MIT](LICENSE) 许可证。
|
|
@@ -0,0 +1,162 @@
|
|
|
1
|
+
# ModelScope API Python SDK
|
|
2
|
+
|
|
3
|
+
[](https://badge.fury.io/py/modelscope-api)
|
|
4
|
+
[](LICENSE)
|
|
5
|
+
[](https://www.python.org/downloads/)
|
|
6
|
+
|
|
7
|
+
一个**异步**、**类型安全**的 Python SDK,用于调用 [ModelScope 开放 API](https://modelscope.cn/docs/openapi)。
|
|
8
|
+
|
|
9
|
+
它提供了直观的对象化接口,覆盖了合集、创空间、魔粒、用户等核心模块,让您能以 Pythonic 的方式与 ModelScope 平台交互。
|
|
10
|
+
|
|
11
|
+
## ✨ 特性
|
|
12
|
+
|
|
13
|
+
- 🚀 **全异步** – 基于 `httpx.AsyncClient`,支持高并发请求。
|
|
14
|
+
- 🧩 **模块化设计** – 按业务领域拆分:`User`、`Magicube`、`Studio`、`Collection` 等。
|
|
15
|
+
- 📦 **类型安全** – 使用 Pydantic 数据模型,提供 IDE 自动补全和校验。
|
|
16
|
+
- 🔐 **自动认证** – 通过环境变量或构造参数传入 API Token,自动注入请求头。
|
|
17
|
+
- 🛠️ **开箱即用** – 支持 `.env` 配置,内置随机 UA 伪装,简化开发。
|
|
18
|
+
|
|
19
|
+
## 📦 安装
|
|
20
|
+
|
|
21
|
+
```bash
|
|
22
|
+
pip install modelscope-api
|
|
23
|
+
```
|
|
24
|
+
|
|
25
|
+
或直接从源码安装:
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
git clone https://github.com/Jerry-Wu-GitHub/modelscope-api.git
|
|
29
|
+
cd modelscope-api
|
|
30
|
+
pip install -e .
|
|
31
|
+
```
|
|
32
|
+
|
|
33
|
+
## 🚀 快速开始
|
|
34
|
+
|
|
35
|
+
### 1. 获取 API Token
|
|
36
|
+
|
|
37
|
+
访问 [ModelScope 个人设置](https://www.modelscope.cn/my/settings/token) 生成您的 `MODELSCOPE_API_TOKEN`。
|
|
38
|
+
|
|
39
|
+
### 2. 配置环境变量(推荐)
|
|
40
|
+
|
|
41
|
+
在项目根目录创建 `.env` 文件:
|
|
42
|
+
|
|
43
|
+
```env
|
|
44
|
+
MODELSCOPE_API_TOKEN=your_token_here
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
也可以直接在代码中传入:
|
|
48
|
+
|
|
49
|
+
```python
|
|
50
|
+
from modelscope_api import ModelScopeClient
|
|
51
|
+
|
|
52
|
+
client = ModelScopeClient(api_key="your_token_here")
|
|
53
|
+
```
|
|
54
|
+
|
|
55
|
+
### 3. 基础用法
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import asyncio
|
|
59
|
+
from modelscope_api import ModelScopeClient
|
|
60
|
+
|
|
61
|
+
async def main():
|
|
62
|
+
async with ModelScopeClient() as client:
|
|
63
|
+
# 获取当前用户信息
|
|
64
|
+
user_info = await client.user.get_current_user_info()
|
|
65
|
+
print(f"当前用户: {user_info.username}")
|
|
66
|
+
|
|
67
|
+
# 查询魔粒余额
|
|
68
|
+
balance = await client.magicube.query_magicube_balance()
|
|
69
|
+
print(f"可用魔粒: {balance.available_balance}")
|
|
70
|
+
|
|
71
|
+
# 搜索创空间
|
|
72
|
+
studios = await client.studio.search_studio_infos(search="chatbot", owner="iic")
|
|
73
|
+
for studio in studios:
|
|
74
|
+
print(f"- {studio.display_name} ({studio.id})")
|
|
75
|
+
|
|
76
|
+
if __name__ == "__main__":
|
|
77
|
+
asyncio.run(main())
|
|
78
|
+
```
|
|
79
|
+
|
|
80
|
+
## 📖 API 概览
|
|
81
|
+
|
|
82
|
+
SDK 的所有功能通过 `ModelScopeClient` 聚合,您可以通过其属性访问各子客户端:
|
|
83
|
+
|
|
84
|
+
| 子客户端 | 说明 | 主要方法 |
|
|
85
|
+
| ------------------- | ------------ | ------------------------------------------------------------ |
|
|
86
|
+
| `client.user` | 用户信息 | `get_current_user_info()` |
|
|
87
|
+
| `client.magicube` | 魔粒(积分) | `query_magicube_balance()` |
|
|
88
|
+
| `client.studio` | 创空间管理 | `search_studio_infos()`, `create_studio()`, `get_studio()` |
|
|
89
|
+
| `client.collection` | 合集管理 | `search_collection_infos()`, `create_collection()`, `get_collection()` |
|
|
90
|
+
|
|
91
|
+
每个子客户端返回的数据均为 Pydantic 模型,可直接访问属性。
|
|
92
|
+
|
|
93
|
+
### 详细示例:操作创空间
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
async def studio_example(client):
|
|
97
|
+
# 创建创空间
|
|
98
|
+
studio = await client.studio.create_studio(
|
|
99
|
+
repo_name="my-awesome-space",
|
|
100
|
+
display_name="我的炫酷空间",
|
|
101
|
+
visibility="public",
|
|
102
|
+
sdk_type="gradio",
|
|
103
|
+
hardware="platform/2v-cpu-16g-mem"
|
|
104
|
+
)
|
|
105
|
+
print(f"创建成功: {studio.id}")
|
|
106
|
+
|
|
107
|
+
# 部署
|
|
108
|
+
runtime = await studio.deploy(timeout=30)
|
|
109
|
+
print(f"部署状态: {runtime.status}")
|
|
110
|
+
|
|
111
|
+
# 查看日志
|
|
112
|
+
logs = await studio.get_logs("run", page_size=50)
|
|
113
|
+
for line in logs.logs:
|
|
114
|
+
print(line)
|
|
115
|
+
|
|
116
|
+
# 添加环境变量
|
|
117
|
+
await studio.variables.add("MY_KEY", "my_value")
|
|
118
|
+
```
|
|
119
|
+
|
|
120
|
+
### 详细示例:操作合集
|
|
121
|
+
|
|
122
|
+
```python
|
|
123
|
+
async def collection_example(client):
|
|
124
|
+
# 创建合集
|
|
125
|
+
collection = await client.collection.create_collection(
|
|
126
|
+
title="我的收藏",
|
|
127
|
+
visibility="private"
|
|
128
|
+
)
|
|
129
|
+
|
|
130
|
+
# 添加条目(模型)
|
|
131
|
+
failed = await collection.items.add_items([
|
|
132
|
+
{
|
|
133
|
+
"item_type": "model",
|
|
134
|
+
"item_object_id": "Qwen/Qwen3.8-27B",
|
|
135
|
+
"position": 1
|
|
136
|
+
}
|
|
137
|
+
])
|
|
138
|
+
if failed:
|
|
139
|
+
print("添加失败:", failed)
|
|
140
|
+
|
|
141
|
+
# 获取条目列表
|
|
142
|
+
items = await collection.items.get_items()
|
|
143
|
+
for item in items:
|
|
144
|
+
print(f"- {item.item_object_id}")
|
|
145
|
+
|
|
146
|
+
# 删除合集
|
|
147
|
+
await collection.delete()
|
|
148
|
+
```
|
|
149
|
+
|
|
150
|
+
## 🧪 运行测试
|
|
151
|
+
|
|
152
|
+
项目包含完整的测试用例,位于 `tests/` 目录。运行前请确保已设置有效的 `MODELSCOPE_API_TOKEN`。
|
|
153
|
+
|
|
154
|
+
> [!CAUTION]
|
|
155
|
+
>
|
|
156
|
+
> 测试用例里包含“删除创空间”,这是一个危险的操作,请确保您没有会受影响的创空间。
|
|
157
|
+
>
|
|
158
|
+
> 要实现该操作,需要使用“管理员权限”的 API Token。
|
|
159
|
+
|
|
160
|
+
## 📄 许可证
|
|
161
|
+
|
|
162
|
+
本项目使用 [MIT](LICENSE) 许可证。
|
|
@@ -4,15 +4,30 @@ build-backend = "setuptools.build_meta"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "modelscope-api" # 包名,保持与项目仓库名一致
|
|
7
|
-
version = "0.0.
|
|
7
|
+
version = "0.0.2" # 当前版本
|
|
8
8
|
description = "A Python async SDK that wraps the ModelScope API into a clean, type-safe interface." # 简短描述
|
|
9
9
|
readme = "README.md" # 自述文件,PyPI 会将其渲染为项目首页
|
|
10
10
|
authors = [{name = "Jerry", email = "wujr24@m.fudan.edu.cn"}] # 作者信息
|
|
11
11
|
license = {text = "MIT"} # 指定许可证,与 LICENSE 文件一致
|
|
12
12
|
classifiers = [ # 帮助用户在 PyPI 上找到你的项目
|
|
13
|
-
|
|
14
|
-
"
|
|
13
|
+
# 开发状态
|
|
14
|
+
"Development Status :: 3 - Alpha",
|
|
15
|
+
|
|
16
|
+
# 目标受众
|
|
17
|
+
"Intended Audience :: Developers",
|
|
18
|
+
"Intended Audience :: Science/Research",
|
|
19
|
+
|
|
20
|
+
# 许可证
|
|
21
|
+
"License :: OSI Approved :: MIT License",
|
|
22
|
+
|
|
23
|
+
# 操作系统
|
|
15
24
|
"Operating System :: OS Independent",
|
|
25
|
+
|
|
26
|
+
# 编程语言 & Python 版本
|
|
27
|
+
"Programming Language :: Python :: 3",
|
|
28
|
+
"Programming Language :: Python :: 3.11",
|
|
29
|
+
"Programming Language :: Python :: 3.12",
|
|
30
|
+
"Programming Language :: Python :: 3.13",
|
|
16
31
|
]
|
|
17
32
|
requires-python = ">=3.11"
|
|
18
33
|
dependencies = [ # 项目的运行时依赖,从 requirements.txt 移植
|
|
@@ -20,7 +35,7 @@ dependencies = [ # 项目的运行时依赖,从 requirements.tx
|
|
|
20
35
|
"httpx",
|
|
21
36
|
"python-dotenv",
|
|
22
37
|
"typing-extensions",
|
|
23
|
-
"yarl"
|
|
38
|
+
"yarl",
|
|
24
39
|
]
|
|
25
40
|
|
|
26
41
|
[project.urls] # 可选,但推荐,指向你的项目主页或仓库
|
|
@@ -15,6 +15,13 @@ load_dotenv()
|
|
|
15
15
|
# 用于 ModelScope 用户进行身份验证的令牌
|
|
16
16
|
MODELSCOPE_API_TOKEN: Optional[str] = os.getenv("MODELSCOPE_API_TOKEN")
|
|
17
17
|
|
|
18
|
+
# API 基础地址
|
|
19
|
+
MODELSCOPE_API_VERSION: str = "v1"
|
|
20
|
+
MODELSCOPE_API_BASE_URL: URL = URL(os.getenv(
|
|
21
|
+
"MODELSCOPE_API_BASE_URL",
|
|
22
|
+
"https://www.modelscope.cn/api"
|
|
23
|
+
))
|
|
24
|
+
|
|
18
25
|
# OpenAPI 基础地址
|
|
19
26
|
MODELSCOPE_OPENAPI_VERSION: str = "v1"
|
|
20
27
|
MODELSCOPE_OPENAPI_BASE_URL: URL = URL(os.getenv(
|
|
@@ -0,0 +1,143 @@
|
|
|
1
|
+
"""
|
|
2
|
+
集成封装子路由的 API。
|
|
3
|
+
"""
|
|
4
|
+
|
|
5
|
+
from __future__ import annotations
|
|
6
|
+
|
|
7
|
+
from typing import List, Optional, Union, TYPE_CHECKING
|
|
8
|
+
|
|
9
|
+
from yarl import URL
|
|
10
|
+
|
|
11
|
+
if TYPE_CHECKING:
|
|
12
|
+
from .modelscope_client import ModelScopeClient, JsonObject
|
|
13
|
+
|
|
14
|
+
|
|
15
|
+
class SubClient:
|
|
16
|
+
"""
|
|
17
|
+
集成封装子路由的 API。
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
def __init__(
|
|
21
|
+
self,
|
|
22
|
+
super_client: Union[ModelScopeClient, SubClient],
|
|
23
|
+
*,
|
|
24
|
+
api_prefix: Optional[str] = None,
|
|
25
|
+
openapi_prefix: Optional[str] = None,
|
|
26
|
+
):
|
|
27
|
+
"""
|
|
28
|
+
Args:
|
|
29
|
+
super_client: 上一级路由的 HTTP 客户端。
|
|
30
|
+
api_prefix: 要接在父级 api_url 后的前缀。
|
|
31
|
+
openapi_prefix: 要接在父级 openapi_prefix 后的前缀。
|
|
32
|
+
"""
|
|
33
|
+
self.super_client = super_client
|
|
34
|
+
self.api_prefix: Optional[str] = api_prefix
|
|
35
|
+
self.openapi_prefix: Optional[str] = openapi_prefix
|
|
36
|
+
|
|
37
|
+
|
|
38
|
+
# ==== API ====
|
|
39
|
+
|
|
40
|
+
@property
|
|
41
|
+
def api_url(self) -> URL:
|
|
42
|
+
"""
|
|
43
|
+
The URL of API sub interface.
|
|
44
|
+
|
|
45
|
+
Returns like:
|
|
46
|
+
"https://www.modelscope.cn/api/v1/studio"
|
|
47
|
+
"""
|
|
48
|
+
if self.api_prefix is None:
|
|
49
|
+
return self.super_client.api_url
|
|
50
|
+
return self.super_client.api_url / self.api_prefix
|
|
51
|
+
|
|
52
|
+
|
|
53
|
+
def get_api_url(self, subpath: Optional[str] = None) -> URL:
|
|
54
|
+
"""
|
|
55
|
+
拼接完整的 API 路由。
|
|
56
|
+
"""
|
|
57
|
+
if subpath is None:
|
|
58
|
+
return self.api_url
|
|
59
|
+
return self.api_url / subpath
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async def request_api_data(
|
|
63
|
+
self,
|
|
64
|
+
subpath: Optional[str] = None,
|
|
65
|
+
*,
|
|
66
|
+
data_field="data",
|
|
67
|
+
**kwargs
|
|
68
|
+
) -> Optional[JsonObject | List[JsonObject]]:
|
|
69
|
+
"""
|
|
70
|
+
向 ModelScope API 发送请求,并返回响应体中的字段 `data_field` (默认为 "data")的值。
|
|
71
|
+
如果响应体中没有 `data_field` 字段,则返回整个响应体。
|
|
72
|
+
|
|
73
|
+
Args:
|
|
74
|
+
subpath: 在 `self.api_url` 之后要拼接的子路径。
|
|
75
|
+
不能以 `/` 开头。
|
|
76
|
+
|
|
77
|
+
Raises:
|
|
78
|
+
ParseException: 如果解析失败。
|
|
79
|
+
ModelScopeException: 如果请求失败。
|
|
80
|
+
"""
|
|
81
|
+
if subpath is None:
|
|
82
|
+
subpath = self.api_prefix
|
|
83
|
+
else:
|
|
84
|
+
subpath = f"{self.api_prefix}/{subpath}"
|
|
85
|
+
return await self.super_client.request_api_data(
|
|
86
|
+
subpath=subpath,
|
|
87
|
+
data_field=data_field,
|
|
88
|
+
**kwargs
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
|
|
92
|
+
# ==== OpenAPI ====
|
|
93
|
+
|
|
94
|
+
@property
|
|
95
|
+
def openapi_url(self) -> URL:
|
|
96
|
+
"""
|
|
97
|
+
The URL of OpenAPI sub interface.
|
|
98
|
+
|
|
99
|
+
Returns like:
|
|
100
|
+
"https://modelscope.cn/openapi/v1/studios"
|
|
101
|
+
"""
|
|
102
|
+
if self.openapi_prefix is None:
|
|
103
|
+
return self.super_client.openapi_url
|
|
104
|
+
return self.super_client.openapi_url / self.openapi_prefix
|
|
105
|
+
|
|
106
|
+
|
|
107
|
+
def get_openapi_url(self, subpath: Optional[str] = None) -> URL:
|
|
108
|
+
"""
|
|
109
|
+
拼接完整的 OpenAPI 路由。
|
|
110
|
+
"""
|
|
111
|
+
if subpath is None:
|
|
112
|
+
return self.openapi_url
|
|
113
|
+
return self.openapi_url / subpath
|
|
114
|
+
|
|
115
|
+
|
|
116
|
+
async def request_openapi_data(
|
|
117
|
+
self,
|
|
118
|
+
subpath: Optional[str] = None,
|
|
119
|
+
*,
|
|
120
|
+
data_field="data",
|
|
121
|
+
**kwargs
|
|
122
|
+
) -> Optional[JsonObject | List[JsonObject]]:
|
|
123
|
+
"""
|
|
124
|
+
向 ModelScope OpenAPI 发送请求,并返回响应体中的字段 `data_field` (默认为 "data")的值。
|
|
125
|
+
如果响应体中没有 `data_field` 字段,则返回整个响应体。
|
|
126
|
+
|
|
127
|
+
Args:
|
|
128
|
+
subpath: 在 `self.openapi_url` 之后要拼接的子路径。
|
|
129
|
+
不能以 `/` 开头。
|
|
130
|
+
|
|
131
|
+
Raises:
|
|
132
|
+
ParseException: 如果解析失败。
|
|
133
|
+
ModelScopeException: 如果请求失败。
|
|
134
|
+
"""
|
|
135
|
+
if subpath is None:
|
|
136
|
+
subpath = self.openapi_prefix
|
|
137
|
+
else:
|
|
138
|
+
subpath = f"{self.openapi_prefix}/{subpath}"
|
|
139
|
+
return await self.super_client.request_openapi_data(
|
|
140
|
+
subpath=subpath,
|
|
141
|
+
data_field=data_field,
|
|
142
|
+
**kwargs
|
|
143
|
+
)
|
{modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/collection/collection.py
RENAMED
|
@@ -27,7 +27,7 @@ class Collection(SubClient):
|
|
|
27
27
|
assert COLLECTION_SLUG_PATTERN.fullmatch(self.slug), f"Invalid collection slug: {self.slug}"
|
|
28
28
|
super().__init__(
|
|
29
29
|
super_client=collection_client,
|
|
30
|
-
|
|
30
|
+
openapi_prefix=self.slug
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
# 聚合子路由
|
|
@@ -111,7 +111,7 @@ class Collection(SubClient):
|
|
|
111
111
|
})
|
|
112
112
|
data = await self.request_openapi_data(**kwargs)
|
|
113
113
|
self._slug = data["slug"]
|
|
114
|
-
self.
|
|
114
|
+
self.openapi_prefix = self._slug
|
|
115
115
|
return await self.get_info()
|
|
116
116
|
|
|
117
117
|
|
|
@@ -24,11 +24,11 @@ class CollectionClient(SubClient):
|
|
|
24
24
|
self,
|
|
25
25
|
modelscope_client: ModelScopeClient,
|
|
26
26
|
*,
|
|
27
|
-
|
|
27
|
+
openapi_prefix: str = "collections"
|
|
28
28
|
):
|
|
29
29
|
super().__init__(
|
|
30
30
|
super_client=modelscope_client,
|
|
31
|
-
|
|
31
|
+
openapi_prefix=openapi_prefix
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
|
|
@@ -24,11 +24,11 @@ class CollectionItemClient(SubClient):
|
|
|
24
24
|
self,
|
|
25
25
|
collection: Collection,
|
|
26
26
|
*,
|
|
27
|
-
|
|
27
|
+
openapi_prefix: str = "items"
|
|
28
28
|
):
|
|
29
29
|
super().__init__(
|
|
30
30
|
super_client=collection,
|
|
31
|
-
|
|
31
|
+
openapi_prefix=openapi_prefix
|
|
32
32
|
)
|
|
33
33
|
|
|
34
34
|
|
{modelscope_api-0.0.1 → modelscope_api-0.0.2}/src/modelscope_api/models/magicube/magicube_client.py
RENAMED
|
@@ -23,11 +23,11 @@ class MagicubeClient(SubClient):
|
|
|
23
23
|
self,
|
|
24
24
|
modelscope_client: ModelScopeClient,
|
|
25
25
|
*,
|
|
26
|
-
|
|
26
|
+
openapi_prefix: str = "magicubes"
|
|
27
27
|
):
|
|
28
28
|
super().__init__(
|
|
29
29
|
super_client=modelscope_client,
|
|
30
|
-
|
|
30
|
+
openapi_prefix=openapi_prefix
|
|
31
31
|
)
|
|
32
32
|
|
|
33
33
|
|