使用 Synology DSM API (最常用)
这是最主流和灵活的方式,它通过 HTTP 请求与 NAS 的 Web 服务进行交互,几乎可以控制 DSM 的所有功能,如文件管理、下载任务、系统信息、用户管理等。
准备工作:在 DSM 中启用 API
在编写 Python 脚本之前,你必须在 NAS 上进行一些设置:
-
开启 SSH 功能:
- 进入 控制面板 > 终端机和 SNMP。
- 勾选 启用 SSH 功能,这方便你后续调试和直接运行脚本。
-
创建专用 API 用户:
- 进入 控制面板 > 用户和用户组。
- 创建一个新用户(
api_user),并为其分配一个强密码。 - 编辑该用户的权限,确保它有足够的权限来执行你需要的操作(如果需要管理文件,就需要赋予相应的文件夹读写权限)。
-
获取你的 NAS 信息:
- DSM 版本:进入 控制面板 > 关于。
- NAS 的 IP 地址或域名:
168.1.100或my.synology.me。 - HTTPS 端口:默认
5001,可以在 控制面板 > 外部访问 > DSM 设置 中找到。
核心概念:API 认证
Synology API 使用一种叫做 Session 的机制来保持认证状态,流程如下:
- 获取
sid(Session ID):首先向auth.cgi发送一个 POST 请求,包含你的用户名和密码,如果成功,服务器会返回一个sid。 - 使用
sid访问其他 API:后续所有的 API 请求都需要在 URL 或 Header 中带上这个sid,服务器以此来识别你的身份。 - 注销
sid:当操作完成时,最好向auth.cgi发送一个请求来注销你的会话,释放资源。
Python 实现:安装 requests 库
我们使用非常流行的 requests 库来处理 HTTP 请求。
pip install requests
完整代码示例:列出共享文件夹中的文件
这个例子将演示如何获取 sid,然后使用 FileStation API 来列出指定共享文件夹下的内容。
import requests
import json
from urllib.parse import urljoin
# --- 配置信息 ---
# 替换为你的 NAS 实际信息
SYNOLOGY_HOST = "192.168.1.100" # 你的 NAS IP 或域名
SYNOLOGY_PORT = 5001 # DSM HTTPS 端口
USERNAME = "api_user" # 你创建的 API 用户名
PASSWORD = "your_password" # API 用户的密码
API_NAME = "FileStation" # 要调用的 API 名称
API_INFO = "list" # 要调用的 API 方法
FOLDER_PATH = "/home" # 你想列出内容的文件夹路径
# --- 1. 获取 Session ID (sid) ---
def get_sid():
"""获取 Synology DSM 的 Session ID"""
auth_url = f"https://{SYNOLOGY_HOST}:{SYNOLOGY_PORT}/webapi/auth.cgi"
params = {
'api': 'SYNO.API.Auth',
'version': '3',
'method': 'login',
'account': USERNAME,
'passwd': PASSWORD,
'session': 'FileStation', # 指定会话名称,方便管理
'format': 'sid' # 只返回 sid
}
try:
response = requests.post(auth_url, params=params, verify=False) # verify=False 用于忽略自签名证书警告
response.raise_for_status() # 如果请求失败则抛出异常
sid = response.json()['data']['sid']
print("成功获取 Session ID (sid)!")
return sid
except requests.exceptions.RequestException as e:
print(f"获取 sid 失败: {e}")
return None
except KeyError:
print("获取 sid 失败: 响应数据格式不正确,请检查用户名和密码。")
return None
# --- 2. 使用 sid 调用 FileStation API 列出文件 ---
def list_files(sid):
"""使用 sid 调用 FileStation API 列出指定文件夹的内容"""
api_url = f"https://{SYNOLOGY_HOST}:{SYNOLOGY_PORT}/webapi/entry.cgi"
params = {
'api': API_NAME,
'version': '2', # FileStation API 的版本
'method': API_INFO,
'path': FOLDER_PATH,
'additional': 'real_path,owner,size,modification_time', # 获取更多信息
'_sid': sid # 关键:在请求中带上 sid
}
try:
response = requests.get(api_url, params=params, verify=False)
response.raise_for_status()
data = response.json()
if data['success']:
print(f"\n--- 文件夹 '{FOLDER_PATH}' 的内容 ---")
files = data['data']['files']
for item in files:
# 判断是文件还是文件夹
item_type = "📁" if item['isdir'] else "📄"
print(f"{item_type} {item['name']} (大小: {item['size']}, 修改时间: {item['mtime']})")
else:
print(f"API 调用失败: {data['error']}")
except requests.exceptions.RequestException as e:
print(f"调用 API 失败: {e}")
except KeyError:
print("解析 API 响应失败,请检查 API 名称和方法是否正确。")
# --- 3. 注销 sid ---
def logout(sid):
"""注销会话,释放资源"""
logout_url = f"https://{SYNOLOGY_HOST}:{SYNOLOGY_PORT}/webapi/auth.cgi"
params = {
'api': 'SYNO.API.Auth',
'version': '3',
'method': 'logout',
'_sid': sid
}
try:
requests.post(logout_url, params=params, verify=False)
print("\n成功注销 Session ID (sid)。")
except requests.exceptions.RequestException as e:
print(f"注销 sid 失败: {e}")
# --- 主程序 ---
if __name__ == "__main__":
# 注意: verify=False 会产生 InsecureRequestWarning,可以忽略或在生产环境中配置正确的证书
import urllib3
urllib3.disable_warnings(urllib3.exceptions.InsecureRequestWarning)
session_id = get_sid()
if session_id:
list_files(session_id)
logout(session_id)
其他常用 API
你可以通过修改 API_NAME 和 API_INFO 来调用不同的功能。
- Download Station (下载管理):
API_NAME:DownloadStationAPI_INFO:list(列出任务),info(获取任务详情),create(创建下载任务)
- System Info (系统信息):
API_NAME:SYNO.API.InfoAPI_INFO:get(获取 API 列表和版本信息)
- Virtual Machine Manager (虚拟机管理):
API_NAME:VMManagerAPI_INFO:list(列出虚拟机)
使用 Synology Package Center SDK (高级)
如果你要开发的是官方的套件应用,而不是外部脚本,那么你应该使用 Synology Package Center SDK,这个 SDK 提供了更底层、更强大的接口,可以直接与 DSM 的核心系统集成,创建有完整 UI 界面的应用。
特点:
- 用于开发官方套件:创建可以在套件中心安装和管理的应用。
- 语言: 主要是 C/C++,但也提供 Python 的绑定。
- 复杂度高:需要理解 DSM 的应用开发框架,包括 UI 定义、权限管理、后台服务等。
- 文档: 需要申请 Synology 开发者账号来获取 SDK 和相关文档。
适用场景:
- 你想开发一个功能复杂的、可以发布给所有群晖用户使用的官方应用。
- 你的应用需要深度集成系统功能,并且需要有图形用户界面。
对于绝大多数只想用 Python 自动化 NAS 任务的普通用户来说,方式一 (DSM API) 是首选。
总结与最佳实践
| 特性 | 方式一 (DSM API) | 方式二 (Package SDK) |
|---|---|---|
| 用途 | 自动化脚本、第三方工具、集成开发 | 官方套件应用开发 |
| 技术栈 | Python + requests 库 |
C/C++, Python (绑定), Web 技术 |
| 认证 | Session ID (sid) |
套件专用 API Key 和权限 |
| 部署 | 在任何有 Python 的机器上运行 | 作为套件安装到 DSM |
| 学习曲线 | 较低 | 较高 |
| 推荐度 | ⭐⭐⭐⭐⭐ (对于脚本开发者) | ⭐⭐⭐ (对于官方应用开发者) |
最佳实践建议
-
安全第一:
- 不要在代码中硬编码你的用户名和密码,使用环境变量或配置文件来存储它们。
- 为脚本创建一个权限最低的专用用户。
- 强烈建议使用 HTTPS 并考虑配置 NAS 的自签名证书。
-
错误处理:
- 网络请求可能会失败,API 调用也可能因为权限不足或参数错误而失败,务必使用
try...except块来处理这些异常,让你的脚本更健壮。
- 网络请求可能会失败,API 调用也可能因为权限不足或参数错误而失败,务必使用
-
会话管理:
- 确保在脚本结束时调用
logout函数来注销sid,这是一个好习惯,可以避免会话资源被长时间占用。
- 确保在脚本结束时调用
-
探索 API:
- 你可以直接在浏览器中访问
https://<your_nas_ip>:<port>/webapi/entry.cgi?api=SYNO.API.Info&method=get&version=1来获取所有可用的 API 列表和它们的版本号,这是发现新功能的好方法。
- 你可以直接在浏览器中访问
希望这份详细的指南能帮助你顺利地在 Python 中使用 Synology NAS!
