dataify-sdk 0.1.0__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.
- dataify_sdk-0.1.0/.gitignore +32 -0
- dataify_sdk-0.1.0/LICENSE +21 -0
- dataify_sdk-0.1.0/PKG-INFO +154 -0
- dataify_sdk-0.1.0/README.md +121 -0
- dataify_sdk-0.1.0/docs/examples/basic_usage.py +97 -0
- dataify_sdk-0.1.0/pyproject.toml +66 -0
- dataify_sdk-0.1.0/scripts/codegen.py +121 -0
- dataify_sdk-0.1.0/src/dataify_mcp/__init__.py +37 -0
- dataify_sdk-0.1.0/src/dataify_mcp/_codegen/__init__.py +14 -0
- dataify_sdk-0.1.0/src/dataify_mcp/_codegen/_generate.py +353 -0
- dataify_sdk-0.1.0/src/dataify_mcp/_codegen/_introspect.py +112 -0
- dataify_sdk-0.1.0/src/dataify_mcp/_codegen/_templates/__init__.py +0 -0
- dataify_sdk-0.1.0/src/dataify_mcp/_version.py +3 -0
- dataify_sdk-0.1.0/src/dataify_mcp/client/__init__.py +7 -0
- dataify_sdk-0.1.0/src/dataify_mcp/client/_base.py +223 -0
- dataify_sdk-0.1.0/src/dataify_mcp/client/_http.py +205 -0
- dataify_sdk-0.1.0/src/dataify_mcp/client/_protocol.py +204 -0
- dataify_sdk-0.1.0/src/dataify_mcp/client/_sse.py +319 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/__init__.py +90 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/amazon.py +137 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/bing.py +141 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/facebook.py +63 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/glassdoor.py +41 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/google_scraper.py +121 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/google_serp.py +320 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/indeed.py +41 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/instagram.py +52 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/linkedin.py +41 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/other_scrapers.py +137 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/other_search.py +90 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/reddit.py +41 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/task_status.py +188 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/tiktok.py +81 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/twitter.py +41 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/user.py +79 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/web_unlocker.py +53 -0
- dataify_sdk-0.1.0/src/dataify_mcp/tools/youtube.py +163 -0
- dataify_sdk-0.1.0/src/dataify_mcp/types/__init__.py +39 -0
- dataify_sdk-0.1.0/src/dataify_mcp/types/_enums.py +220 -0
- dataify_sdk-0.1.0/src/dataify_mcp/types/_errors.py +73 -0
- dataify_sdk-0.1.0/src/dataify_mcp/types/_mcp.py +89 -0
- dataify_sdk-0.1.0/tests/__init__.py +0 -0
- dataify_sdk-0.1.0/tests/conftest.py +123 -0
- dataify_sdk-0.1.0/tests/test_client/__init__.py +0 -0
- dataify_sdk-0.1.0/tests/test_client/test_http_client.py +136 -0
- dataify_sdk-0.1.0/tests/test_tools/__init__.py +0 -0
- dataify_sdk-0.1.0/tests/test_tools/test_codegen.py +174 -0
- dataify_sdk-0.1.0/tests/test_tools/test_tool_modules.py +203 -0
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
# Python
|
|
2
|
+
__pycache__/
|
|
3
|
+
*.py[cod]
|
|
4
|
+
*.egg-info/
|
|
5
|
+
dist/
|
|
6
|
+
build/
|
|
7
|
+
*.egg
|
|
8
|
+
|
|
9
|
+
# Virtual environments
|
|
10
|
+
.venv/
|
|
11
|
+
venv/
|
|
12
|
+
|
|
13
|
+
# IDE
|
|
14
|
+
.idea/
|
|
15
|
+
.vscode/
|
|
16
|
+
*.swp
|
|
17
|
+
*.swo
|
|
18
|
+
|
|
19
|
+
# Testing
|
|
20
|
+
.pytest_cache/
|
|
21
|
+
.coverage
|
|
22
|
+
htmlcov/
|
|
23
|
+
|
|
24
|
+
# Mypy
|
|
25
|
+
.mypy_cache/
|
|
26
|
+
|
|
27
|
+
# OS
|
|
28
|
+
.DS_Store
|
|
29
|
+
Thumbs.db
|
|
30
|
+
|
|
31
|
+
# Code generation artifacts
|
|
32
|
+
tool_manifest.json
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 dataify-server
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: dataify-sdk
|
|
3
|
+
Version: 0.1.0
|
|
4
|
+
Summary: Python SDK for the Dataify MCP API — access web unlocker, search engines, and platform scrapers.
|
|
5
|
+
Project-URL: Homepage, https://dashboard.dataify.com
|
|
6
|
+
Project-URL: Repository, https://github.com/dataify/dataify-mcp-sdk
|
|
7
|
+
Author-email: Dataify <support@dataify.com>
|
|
8
|
+
License: MIT
|
|
9
|
+
License-File: LICENSE
|
|
10
|
+
Keywords: dataify,google-search,mcp,scraper,serp,web-unlocker
|
|
11
|
+
Classifier: Development Status :: 4 - Beta
|
|
12
|
+
Classifier: Intended Audience :: Developers
|
|
13
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
14
|
+
Classifier: Programming Language :: Python :: 3
|
|
15
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
16
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
17
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.13
|
|
19
|
+
Classifier: Topic :: Internet :: WWW/HTTP
|
|
20
|
+
Classifier: Topic :: Software Development :: Libraries :: Python Modules
|
|
21
|
+
Requires-Python: >=3.10
|
|
22
|
+
Requires-Dist: httpx>=0.28.0
|
|
23
|
+
Requires-Dist: pydantic>=2.0.0
|
|
24
|
+
Requires-Dist: typing-extensions>=4.0.0
|
|
25
|
+
Provides-Extra: dev
|
|
26
|
+
Requires-Dist: jinja2>=3.0.0; extra == 'dev'
|
|
27
|
+
Requires-Dist: mypy>=1.0.0; extra == 'dev'
|
|
28
|
+
Requires-Dist: pytest-asyncio>=0.24.0; extra == 'dev'
|
|
29
|
+
Requires-Dist: pytest-httpx>=0.30.0; extra == 'dev'
|
|
30
|
+
Requires-Dist: pytest>=8.0.0; extra == 'dev'
|
|
31
|
+
Requires-Dist: ruff>=0.6.0; extra == 'dev'
|
|
32
|
+
Description-Content-Type: text/markdown
|
|
33
|
+
|
|
34
|
+
# Dataify MCP Python SDK
|
|
35
|
+
|
|
36
|
+
Python 客户端库,用于通过 [MCP (Model Context Protocol)](https://spec.modelcontextprotocol.io/) 访问 [Dataify](https://dashboard.dataify.com) 数据采集平台。
|
|
37
|
+
|
|
38
|
+
## 功能
|
|
39
|
+
|
|
40
|
+
- 🌐 **网页解锁器** — 绕过 CAPTCHA、JS 渲染,返回 HTML 或 PNG 截图
|
|
41
|
+
- 🔍 **搜索引擎** — Google(17 种搜索类型)、Bing(6 种)、Yandex、DuckDuckGo
|
|
42
|
+
- 🛒 **平台抓取器** — Amazon、YouTube、TikTok、Facebook、Instagram、Reddit、Twitter/X、LinkedIn、Glassdoor、Indeed 等 35+ 平台
|
|
43
|
+
- ⚡ **异步优先** — 基于 `httpx` 的现代异步 API
|
|
44
|
+
- 🛡️ **类型安全** — 完整的类型注解,支持 `mypy --strict`
|
|
45
|
+
- 🔌 **双传输模式** — 支持 Streamable HTTP 和 SSE
|
|
46
|
+
|
|
47
|
+
## 安装
|
|
48
|
+
|
|
49
|
+
```bash
|
|
50
|
+
pip install dataify-mcp
|
|
51
|
+
```
|
|
52
|
+
|
|
53
|
+
要求 Python >= 3.10。
|
|
54
|
+
|
|
55
|
+
## 快速开始
|
|
56
|
+
|
|
57
|
+
```python
|
|
58
|
+
import asyncio
|
|
59
|
+
from dataify_mcp import DataifyClient
|
|
60
|
+
|
|
61
|
+
async def main():
|
|
62
|
+
async with DataifyClient(
|
|
63
|
+
base_url="http://localhost:7780",
|
|
64
|
+
token="your-api-token",
|
|
65
|
+
) as client:
|
|
66
|
+
# 列出可用工具
|
|
67
|
+
tools = await client.list_tools()
|
|
68
|
+
print(f"可用工具: {len(tools)} 个")
|
|
69
|
+
|
|
70
|
+
# 调用 Google 搜索
|
|
71
|
+
result = await client.call_tool("google_search", {
|
|
72
|
+
"q": "今天天气",
|
|
73
|
+
"gl": "cn",
|
|
74
|
+
"hl": "zh-cn",
|
|
75
|
+
})
|
|
76
|
+
print(result)
|
|
77
|
+
|
|
78
|
+
asyncio.run(main())
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 连接方式
|
|
82
|
+
|
|
83
|
+
### Streamable HTTP(默认)
|
|
84
|
+
|
|
85
|
+
```python
|
|
86
|
+
client = DataifyClient(
|
|
87
|
+
base_url="http://localhost:7780",
|
|
88
|
+
token="your-token",
|
|
89
|
+
transport="http", # 默认值
|
|
90
|
+
)
|
|
91
|
+
```
|
|
92
|
+
|
|
93
|
+
### SSE(Server-Sent Events)
|
|
94
|
+
|
|
95
|
+
```python
|
|
96
|
+
client = DataifyClient(
|
|
97
|
+
base_url="http://localhost:7780",
|
|
98
|
+
token="your-token",
|
|
99
|
+
transport="sse",
|
|
100
|
+
)
|
|
101
|
+
```
|
|
102
|
+
|
|
103
|
+
### 工具权限过滤
|
|
104
|
+
|
|
105
|
+
```python
|
|
106
|
+
# 只使用指定的工具类别
|
|
107
|
+
client = DataifyClient(
|
|
108
|
+
base_url="http://localhost:7780",
|
|
109
|
+
token="your-token",
|
|
110
|
+
tool_codes="serp,google", # 多个用逗号分隔
|
|
111
|
+
)
|
|
112
|
+
```
|
|
113
|
+
|
|
114
|
+
## 错误处理
|
|
115
|
+
|
|
116
|
+
```python
|
|
117
|
+
from dataify_mcp import (
|
|
118
|
+
DataifyClient,
|
|
119
|
+
AuthenticationError,
|
|
120
|
+
ToolError,
|
|
121
|
+
ConnectionError,
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
try:
|
|
125
|
+
async with DataifyClient("http://localhost:7780", "token") as client:
|
|
126
|
+
result = await client.call_tool("google_search", {"q": "test"})
|
|
127
|
+
except AuthenticationError:
|
|
128
|
+
print("Token 无效,请检查 https://dashboard.dataify.com")
|
|
129
|
+
except ToolError as e:
|
|
130
|
+
print(f"工具执行失败: {e}")
|
|
131
|
+
except ConnectionError:
|
|
132
|
+
print("无法连接服务器")
|
|
133
|
+
```
|
|
134
|
+
|
|
135
|
+
## 开发
|
|
136
|
+
|
|
137
|
+
```bash
|
|
138
|
+
# 安装开发依赖
|
|
139
|
+
pip install -e ".[dev]"
|
|
140
|
+
|
|
141
|
+
# 代码检查
|
|
142
|
+
ruff check src/dataify_mcp/
|
|
143
|
+
mypy src/dataify_mcp/
|
|
144
|
+
|
|
145
|
+
# 运行测试
|
|
146
|
+
pytest
|
|
147
|
+
|
|
148
|
+
# 生成工具封装代码
|
|
149
|
+
python scripts/codegen.py --server http://localhost:7780 --token YOUR_TOKEN
|
|
150
|
+
```
|
|
151
|
+
|
|
152
|
+
## 许可
|
|
153
|
+
|
|
154
|
+
MIT License
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
# Dataify MCP Python SDK
|
|
2
|
+
|
|
3
|
+
Python 客户端库,用于通过 [MCP (Model Context Protocol)](https://spec.modelcontextprotocol.io/) 访问 [Dataify](https://dashboard.dataify.com) 数据采集平台。
|
|
4
|
+
|
|
5
|
+
## 功能
|
|
6
|
+
|
|
7
|
+
- 🌐 **网页解锁器** — 绕过 CAPTCHA、JS 渲染,返回 HTML 或 PNG 截图
|
|
8
|
+
- 🔍 **搜索引擎** — Google(17 种搜索类型)、Bing(6 种)、Yandex、DuckDuckGo
|
|
9
|
+
- 🛒 **平台抓取器** — Amazon、YouTube、TikTok、Facebook、Instagram、Reddit、Twitter/X、LinkedIn、Glassdoor、Indeed 等 35+ 平台
|
|
10
|
+
- ⚡ **异步优先** — 基于 `httpx` 的现代异步 API
|
|
11
|
+
- 🛡️ **类型安全** — 完整的类型注解,支持 `mypy --strict`
|
|
12
|
+
- 🔌 **双传输模式** — 支持 Streamable HTTP 和 SSE
|
|
13
|
+
|
|
14
|
+
## 安装
|
|
15
|
+
|
|
16
|
+
```bash
|
|
17
|
+
pip install dataify-mcp
|
|
18
|
+
```
|
|
19
|
+
|
|
20
|
+
要求 Python >= 3.10。
|
|
21
|
+
|
|
22
|
+
## 快速开始
|
|
23
|
+
|
|
24
|
+
```python
|
|
25
|
+
import asyncio
|
|
26
|
+
from dataify_mcp import DataifyClient
|
|
27
|
+
|
|
28
|
+
async def main():
|
|
29
|
+
async with DataifyClient(
|
|
30
|
+
base_url="http://localhost:7780",
|
|
31
|
+
token="your-api-token",
|
|
32
|
+
) as client:
|
|
33
|
+
# 列出可用工具
|
|
34
|
+
tools = await client.list_tools()
|
|
35
|
+
print(f"可用工具: {len(tools)} 个")
|
|
36
|
+
|
|
37
|
+
# 调用 Google 搜索
|
|
38
|
+
result = await client.call_tool("google_search", {
|
|
39
|
+
"q": "今天天气",
|
|
40
|
+
"gl": "cn",
|
|
41
|
+
"hl": "zh-cn",
|
|
42
|
+
})
|
|
43
|
+
print(result)
|
|
44
|
+
|
|
45
|
+
asyncio.run(main())
|
|
46
|
+
```
|
|
47
|
+
|
|
48
|
+
## 连接方式
|
|
49
|
+
|
|
50
|
+
### Streamable HTTP(默认)
|
|
51
|
+
|
|
52
|
+
```python
|
|
53
|
+
client = DataifyClient(
|
|
54
|
+
base_url="http://localhost:7780",
|
|
55
|
+
token="your-token",
|
|
56
|
+
transport="http", # 默认值
|
|
57
|
+
)
|
|
58
|
+
```
|
|
59
|
+
|
|
60
|
+
### SSE(Server-Sent Events)
|
|
61
|
+
|
|
62
|
+
```python
|
|
63
|
+
client = DataifyClient(
|
|
64
|
+
base_url="http://localhost:7780",
|
|
65
|
+
token="your-token",
|
|
66
|
+
transport="sse",
|
|
67
|
+
)
|
|
68
|
+
```
|
|
69
|
+
|
|
70
|
+
### 工具权限过滤
|
|
71
|
+
|
|
72
|
+
```python
|
|
73
|
+
# 只使用指定的工具类别
|
|
74
|
+
client = DataifyClient(
|
|
75
|
+
base_url="http://localhost:7780",
|
|
76
|
+
token="your-token",
|
|
77
|
+
tool_codes="serp,google", # 多个用逗号分隔
|
|
78
|
+
)
|
|
79
|
+
```
|
|
80
|
+
|
|
81
|
+
## 错误处理
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
from dataify_mcp import (
|
|
85
|
+
DataifyClient,
|
|
86
|
+
AuthenticationError,
|
|
87
|
+
ToolError,
|
|
88
|
+
ConnectionError,
|
|
89
|
+
)
|
|
90
|
+
|
|
91
|
+
try:
|
|
92
|
+
async with DataifyClient("http://localhost:7780", "token") as client:
|
|
93
|
+
result = await client.call_tool("google_search", {"q": "test"})
|
|
94
|
+
except AuthenticationError:
|
|
95
|
+
print("Token 无效,请检查 https://dashboard.dataify.com")
|
|
96
|
+
except ToolError as e:
|
|
97
|
+
print(f"工具执行失败: {e}")
|
|
98
|
+
except ConnectionError:
|
|
99
|
+
print("无法连接服务器")
|
|
100
|
+
```
|
|
101
|
+
|
|
102
|
+
## 开发
|
|
103
|
+
|
|
104
|
+
```bash
|
|
105
|
+
# 安装开发依赖
|
|
106
|
+
pip install -e ".[dev]"
|
|
107
|
+
|
|
108
|
+
# 代码检查
|
|
109
|
+
ruff check src/dataify_mcp/
|
|
110
|
+
mypy src/dataify_mcp/
|
|
111
|
+
|
|
112
|
+
# 运行测试
|
|
113
|
+
pytest
|
|
114
|
+
|
|
115
|
+
# 生成工具封装代码
|
|
116
|
+
python scripts/codegen.py --server http://localhost:7780 --token YOUR_TOKEN
|
|
117
|
+
```
|
|
118
|
+
|
|
119
|
+
## 许可
|
|
120
|
+
|
|
121
|
+
MIT License
|
|
@@ -0,0 +1,97 @@
|
|
|
1
|
+
"""Basic usage examples for the Dataify MCP SDK."""
|
|
2
|
+
|
|
3
|
+
import asyncio
|
|
4
|
+
from dataify_mcp import DataifyClient, AuthenticationError, ToolError, ConnectionError
|
|
5
|
+
|
|
6
|
+
# 配置
|
|
7
|
+
BASE_URL = "http://localhost:7780"
|
|
8
|
+
TOKEN = "your-api-token"
|
|
9
|
+
|
|
10
|
+
|
|
11
|
+
async def example_list_tools():
|
|
12
|
+
"""列出所有可用工具。"""
|
|
13
|
+
async with DataifyClient(BASE_URL, TOKEN) as client:
|
|
14
|
+
tools = await client.list_tools()
|
|
15
|
+
for tool in tools:
|
|
16
|
+
print(f" {tool.name}: {tool.description[:80]}...")
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
async def example_google_search():
|
|
20
|
+
"""执行 Google 搜索。"""
|
|
21
|
+
async with DataifyClient(BASE_URL, TOKEN) as client:
|
|
22
|
+
result = await client.call_tool("google_search", {
|
|
23
|
+
"q": "Python 异步编程",
|
|
24
|
+
"gl": "cn",
|
|
25
|
+
"hl": "zh-cn",
|
|
26
|
+
"num": "10",
|
|
27
|
+
})
|
|
28
|
+
print(result)
|
|
29
|
+
|
|
30
|
+
|
|
31
|
+
async def example_web_unlocker():
|
|
32
|
+
"""解锁网页。"""
|
|
33
|
+
async with DataifyClient(BASE_URL, TOKEN) as client:
|
|
34
|
+
result = await client.call_tool("request_web_unlocker", {
|
|
35
|
+
"url": "https://example.com",
|
|
36
|
+
"type": "html",
|
|
37
|
+
"js_render": "True",
|
|
38
|
+
})
|
|
39
|
+
print(result)
|
|
40
|
+
|
|
41
|
+
|
|
42
|
+
async def example_user_info():
|
|
43
|
+
"""查询用户信息。"""
|
|
44
|
+
async with DataifyClient(BASE_URL, TOKEN) as client:
|
|
45
|
+
result = await client.call_tool("query_user_info", {})
|
|
46
|
+
print(result)
|
|
47
|
+
|
|
48
|
+
|
|
49
|
+
async def example_error_handling():
|
|
50
|
+
"""错误处理示例。"""
|
|
51
|
+
try:
|
|
52
|
+
async with DataifyClient(BASE_URL, "invalid-token") as client:
|
|
53
|
+
await client.call_tool("google_search", {"q": "test"})
|
|
54
|
+
except AuthenticationError:
|
|
55
|
+
print("Token 无效,请检查 https://dashboard.dataify.com")
|
|
56
|
+
except ToolError as e:
|
|
57
|
+
print(f"工具执行失败: {e}")
|
|
58
|
+
except ConnectionError:
|
|
59
|
+
print("无法连接服务器")
|
|
60
|
+
|
|
61
|
+
|
|
62
|
+
async def example_with_tool_filter():
|
|
63
|
+
"""使用工具过滤。"""
|
|
64
|
+
async with DataifyClient(
|
|
65
|
+
BASE_URL, TOKEN,
|
|
66
|
+
tool_codes="serp,google", # 只使用 SERP 相关工具
|
|
67
|
+
) as client:
|
|
68
|
+
tools = await client.list_tools()
|
|
69
|
+
print(f"过滤后的工具数: {len(tools)}")
|
|
70
|
+
|
|
71
|
+
|
|
72
|
+
async def example_sse_transport():
|
|
73
|
+
"""使用 SSE 传输。"""
|
|
74
|
+
async with DataifyClient(
|
|
75
|
+
BASE_URL, TOKEN,
|
|
76
|
+
transport="sse",
|
|
77
|
+
) as client:
|
|
78
|
+
result = await client.call_tool("google_search", {"q": "test"})
|
|
79
|
+
print(result)
|
|
80
|
+
|
|
81
|
+
|
|
82
|
+
async def main():
|
|
83
|
+
"""运行所有示例。"""
|
|
84
|
+
print("=" * 60)
|
|
85
|
+
print("Dataify MCP SDK — 使用示例")
|
|
86
|
+
print("=" * 60)
|
|
87
|
+
|
|
88
|
+
try:
|
|
89
|
+
await example_list_tools()
|
|
90
|
+
except ConnectionError:
|
|
91
|
+
print("(跳过 — 服务器未运行)")
|
|
92
|
+
|
|
93
|
+
print("\n提示: 修改 TOKEN 并启动服务器后运行完整示例。")
|
|
94
|
+
|
|
95
|
+
|
|
96
|
+
if __name__ == "__main__":
|
|
97
|
+
asyncio.run(main())
|
|
@@ -0,0 +1,66 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["hatchling"]
|
|
3
|
+
build-backend = "hatchling.build"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "dataify-sdk"
|
|
7
|
+
version = "0.1.0"
|
|
8
|
+
description = "Python SDK for the Dataify MCP API — access web unlocker, search engines, and platform scrapers."
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
license = {text = "MIT"}
|
|
11
|
+
requires-python = ">=3.10"
|
|
12
|
+
authors = [{name = "Dataify", email = "support@dataify.com"}]
|
|
13
|
+
keywords = ["mcp", "dataify", "serp", "scraper", "google-search", "web-unlocker"]
|
|
14
|
+
classifiers = [
|
|
15
|
+
"Development Status :: 4 - Beta",
|
|
16
|
+
"Intended Audience :: Developers",
|
|
17
|
+
"License :: OSI Approved :: MIT License",
|
|
18
|
+
"Programming Language :: Python :: 3",
|
|
19
|
+
"Programming Language :: Python :: 3.10",
|
|
20
|
+
"Programming Language :: Python :: 3.11",
|
|
21
|
+
"Programming Language :: Python :: 3.12",
|
|
22
|
+
"Programming Language :: Python :: 3.13",
|
|
23
|
+
"Topic :: Internet :: WWW/HTTP",
|
|
24
|
+
"Topic :: Software Development :: Libraries :: Python Modules",
|
|
25
|
+
]
|
|
26
|
+
dependencies = [
|
|
27
|
+
"httpx>=0.28.0",
|
|
28
|
+
"pydantic>=2.0.0",
|
|
29
|
+
"typing-extensions>=4.0.0",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
[project.optional-dependencies]
|
|
33
|
+
dev = [
|
|
34
|
+
"pytest>=8.0.0",
|
|
35
|
+
"pytest-asyncio>=0.24.0",
|
|
36
|
+
"pytest-httpx>=0.30.0",
|
|
37
|
+
"mypy>=1.0.0",
|
|
38
|
+
"ruff>=0.6.0",
|
|
39
|
+
"jinja2>=3.0.0",
|
|
40
|
+
]
|
|
41
|
+
|
|
42
|
+
[project.urls]
|
|
43
|
+
Homepage = "https://dashboard.dataify.com"
|
|
44
|
+
Repository = "https://github.com/dataify/dataify-mcp-sdk"
|
|
45
|
+
|
|
46
|
+
[tool.hatch.build.targets.wheel]
|
|
47
|
+
packages = ["src/dataify_mcp"]
|
|
48
|
+
exclude = ["src/dataify_mcp/_codegen"]
|
|
49
|
+
|
|
50
|
+
[tool.ruff]
|
|
51
|
+
line-length = 100
|
|
52
|
+
target-version = "py310"
|
|
53
|
+
|
|
54
|
+
[tool.ruff.lint]
|
|
55
|
+
select = ["E", "F", "I", "N", "W", "UP"]
|
|
56
|
+
|
|
57
|
+
[tool.mypy]
|
|
58
|
+
strict = true
|
|
59
|
+
python_version = "3.10"
|
|
60
|
+
|
|
61
|
+
[tool.pytest.ini_options]
|
|
62
|
+
asyncio_mode = "auto"
|
|
63
|
+
testpaths = ["tests"]
|
|
64
|
+
filterwarnings = [
|
|
65
|
+
"ignore:Field name.*shadows an attribute in parent.*BaseModel:UserWarning",
|
|
66
|
+
]
|
|
@@ -0,0 +1,121 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Code generation CLI for the Dataify MCP SDK.
|
|
3
|
+
|
|
4
|
+
Usage::
|
|
5
|
+
|
|
6
|
+
# Fetch tools from a running server and generate wrappers
|
|
7
|
+
python scripts/codegen.py --server http://localhost:7780 --token YOUR_TOKEN
|
|
8
|
+
|
|
9
|
+
# Generate from a previously saved manifest
|
|
10
|
+
python scripts/codegen.py --manifest tool_manifest.json
|
|
11
|
+
|
|
12
|
+
# Save the manifest without generating
|
|
13
|
+
python scripts/codegen.py --server http://localhost:7780 --token YOUR_TOKEN --save-only
|
|
14
|
+
"""
|
|
15
|
+
|
|
16
|
+
from __future__ import annotations
|
|
17
|
+
|
|
18
|
+
import argparse
|
|
19
|
+
import asyncio
|
|
20
|
+
import sys
|
|
21
|
+
from pathlib import Path
|
|
22
|
+
|
|
23
|
+
# Allow running directly from the scripts directory
|
|
24
|
+
_scripts_dir = Path(__file__).resolve().parent
|
|
25
|
+
_sdk_root = _scripts_dir.parent
|
|
26
|
+
sys.path.insert(0, str(_sdk_root / "src"))
|
|
27
|
+
|
|
28
|
+
from dataify_mcp._codegen._generate import generate_tool_modules
|
|
29
|
+
from dataify_mcp._codegen._introspect import (
|
|
30
|
+
fetch_tool_manifest,
|
|
31
|
+
load_tool_manifest,
|
|
32
|
+
save_tool_manifest,
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
|
|
36
|
+
def main() -> None:
|
|
37
|
+
parser = argparse.ArgumentParser(
|
|
38
|
+
description="Generate typed tool wrappers for Dataify MCP SDK",
|
|
39
|
+
)
|
|
40
|
+
parser.add_argument(
|
|
41
|
+
"--server",
|
|
42
|
+
help="Dataify MCP server URL (e.g. http://localhost:7780)",
|
|
43
|
+
)
|
|
44
|
+
parser.add_argument(
|
|
45
|
+
"--token",
|
|
46
|
+
help="API token for the MCP server",
|
|
47
|
+
)
|
|
48
|
+
parser.add_argument(
|
|
49
|
+
"--tools",
|
|
50
|
+
help="Optional tool code filter (comma-separated)",
|
|
51
|
+
)
|
|
52
|
+
parser.add_argument(
|
|
53
|
+
"--manifest",
|
|
54
|
+
help="Path to a previously saved tool_manifest.json",
|
|
55
|
+
)
|
|
56
|
+
parser.add_argument(
|
|
57
|
+
"--output",
|
|
58
|
+
default=str(_sdk_root / "src" / "dataify_mcp" / "tools"),
|
|
59
|
+
help="Output directory for generated modules",
|
|
60
|
+
)
|
|
61
|
+
parser.add_argument(
|
|
62
|
+
"--save-manifest",
|
|
63
|
+
default=str(_sdk_root / "tool_manifest.json"),
|
|
64
|
+
help="Path to save the tool manifest JSON",
|
|
65
|
+
)
|
|
66
|
+
parser.add_argument(
|
|
67
|
+
"--save-only",
|
|
68
|
+
action="store_true",
|
|
69
|
+
help="Only save the manifest, do not generate code",
|
|
70
|
+
)
|
|
71
|
+
parser.add_argument(
|
|
72
|
+
"--timeout",
|
|
73
|
+
type=float,
|
|
74
|
+
default=30.0,
|
|
75
|
+
help="HTTP request timeout in seconds",
|
|
76
|
+
)
|
|
77
|
+
|
|
78
|
+
args = parser.parse_args()
|
|
79
|
+
|
|
80
|
+
if args.server and args.token:
|
|
81
|
+
print(f"Fetching tool manifest from {args.server} ...")
|
|
82
|
+
tools = asyncio.run(
|
|
83
|
+
fetch_tool_manifest(
|
|
84
|
+
args.server,
|
|
85
|
+
args.token,
|
|
86
|
+
tool_codes=args.tools,
|
|
87
|
+
timeout=args.timeout,
|
|
88
|
+
)
|
|
89
|
+
)
|
|
90
|
+
print(f" → {len(tools)} tools discovered")
|
|
91
|
+
|
|
92
|
+
save_tool_manifest(tools, args.save_manifest)
|
|
93
|
+
print(f" → saved to {args.save_manifest}")
|
|
94
|
+
|
|
95
|
+
if args.save_only:
|
|
96
|
+
return
|
|
97
|
+
|
|
98
|
+
elif args.manifest:
|
|
99
|
+
print(f"Loading tool manifest from {args.manifest} ...")
|
|
100
|
+
tools = load_tool_manifest(args.manifest)
|
|
101
|
+
print(f" → {len(tools)} tools loaded")
|
|
102
|
+
|
|
103
|
+
else:
|
|
104
|
+
parser.error("Either --server + --token, or --manifest is required")
|
|
105
|
+
|
|
106
|
+
print(f"Generating tool wrappers in {args.output} ...")
|
|
107
|
+
written = generate_tool_modules(tools, args.output)
|
|
108
|
+
for module, tool_names in sorted(written.items()):
|
|
109
|
+
print(f" {module}.py: {len(tool_names)} tools")
|
|
110
|
+
print(f" → {sum(len(v) for v in written.values())} tools across {len(written)} modules")
|
|
111
|
+
|
|
112
|
+
print("Done.")
|
|
113
|
+
print()
|
|
114
|
+
print("Next steps:")
|
|
115
|
+
print(" 1. Review generated code for correctness")
|
|
116
|
+
print(" 2. Run: ruff check src/dataify_mcp/tools/")
|
|
117
|
+
print(" 3. Run: python -c 'from dataify_mcp.tools import *' # verify imports")
|
|
118
|
+
|
|
119
|
+
|
|
120
|
+
if __name__ == "__main__":
|
|
121
|
+
main()
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
"""Dataify MCP SDK — Python client for the Dataify MCP API.
|
|
2
|
+
|
|
3
|
+
Provides access to web unlocker, search engines (Google, Bing, Yandex, DuckDuckGo),
|
|
4
|
+
and platform scrapers (Amazon, YouTube, TikTok, Facebook, Instagram, etc.) through
|
|
5
|
+
the Model Context Protocol.
|
|
6
|
+
"""
|
|
7
|
+
|
|
8
|
+
from dataify_mcp._version import __version__
|
|
9
|
+
from dataify_mcp.client._base import DataifyClient
|
|
10
|
+
from dataify_mcp.client._http import HTTPTransport
|
|
11
|
+
from dataify_mcp.client._sse import SSETransport
|
|
12
|
+
from dataify_mcp.types._errors import (
|
|
13
|
+
AuthenticationError,
|
|
14
|
+
ConnectionError,
|
|
15
|
+
DataifyError,
|
|
16
|
+
ProtocolError,
|
|
17
|
+
ServerError,
|
|
18
|
+
TimeoutError,
|
|
19
|
+
ToolAccessError,
|
|
20
|
+
ToolError,
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
__all__ = [
|
|
24
|
+
"__version__",
|
|
25
|
+
"DataifyClient",
|
|
26
|
+
"HTTPTransport",
|
|
27
|
+
"SSETransport",
|
|
28
|
+
# Errors
|
|
29
|
+
"DataifyError",
|
|
30
|
+
"AuthenticationError",
|
|
31
|
+
"ToolAccessError",
|
|
32
|
+
"ConnectionError",
|
|
33
|
+
"ProtocolError",
|
|
34
|
+
"ToolError",
|
|
35
|
+
"TimeoutError",
|
|
36
|
+
"ServerError",
|
|
37
|
+
]
|
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
"""Code generation tooling for Dataify MCP SDK.
|
|
2
|
+
|
|
3
|
+
This package connects to a running Dataify MCP server, introspects its
|
|
4
|
+
``tools/list`` endpoint, and generates typed Pydantic models and convenience
|
|
5
|
+
methods for every tool. The generated code is written into
|
|
6
|
+
``src/dataify_mcp/tools/``.
|
|
7
|
+
|
|
8
|
+
**This package is NOT shipped in the wheel** (excluded in pyproject.toml).
|
|
9
|
+
"""
|
|
10
|
+
|
|
11
|
+
from dataify_mcp._codegen._introspect import fetch_tool_manifest, load_tool_manifest
|
|
12
|
+
from dataify_mcp._codegen._generate import generate_tool_modules
|
|
13
|
+
|
|
14
|
+
__all__ = ["fetch_tool_manifest", "load_tool_manifest", "generate_tool_modules"]
|