使用Python调用Synology NAS API上传文件请求卡顿问题排查
Synology NAS 文件上传API请求卡顿问题排查与替代方案
问题背景
已通过SYNO.API.Auth和SYNO.FileStation.List完成登录与文件站信息查询,但调用SYNO.FileStation.Upload API时POST请求无限卡顿,代码如下:
file_path = 'path to xlsx file' # API endpoint for file upload upload_url = f'{url}/webapi/entry.cgi' # The file to be uploaded files = {'file': (open(file_path, 'rb'))} # Parameters for the file upload request upload_params = { 'api': 'SYNO.FileStation.Upload', 'version': '2', 'method': 'upload', 'path': '/home/Drive', 'create_parents': 'true', '_sid': sid, } try: # Sending the file upload request upload_response = requests.post(upload_url, params=upload_params, files=files) upload_data = upload_response.json() except Exception as e: print(f'Error uploading file: {e}')
可能遗漏的配置项
- 文件参数格式不完整:
requests的files字典中,file字段需传递完整三元组(文件名、文件对象、MIME类型)。xlsx文件的MIME类型为application/vnd.openxmlformats-officedocument.spreadsheetml.sheet,仅传文件对象可能导致NAS无法识别请求,进而卡住处理。 - 参数类型错误:
create_parents需传入布尔值True而非字符串'true',部分Synology API对参数类型敏感,字符串类型可能引发异常处理逻辑卡顿。 - 路径有效性问题:确认
path是否正确,若为用户Home目录下的Drive,路径应为/home/<用户名>/Drive;若为共享文件夹,直接使用/Drive即可。路径错误会导致NAS在尝试创建父目录时陷入无效处理。 - 缺少超时设置:
requests.post未设置timeout参数,默认无超时限制,若NAS端处理异常会无限等待,需添加timeout=30(或其他合理值)强制终止超时请求。 - 大文件未分块:若xlsx文件较大,需启用分块上传,添加
offset、total_size等参数,否则单请求上传大文件会因网络或NAS处理能力不足导致卡顿。
修正后的上传代码示例
import os import requests file_path = 'path to xlsx file' file_name = os.path.basename(file_path) upload_url = f'{url}/webapi/entry.cgi' # 完整的文件参数配置 files = { 'file': ( file_name, open(file_path, 'rb'), 'application/vnd.openxmlformats-officedocument.spreadsheetml.sheet' ) } upload_params = { 'api': 'SYNO.FileStation.Upload', 'version': '2', 'method': 'upload', 'path': '/home/<你的用户名>/Drive', # 修正为正确路径 'create_parents': True, '_sid': sid, } try: # 添加超时限制,避免无限等待 upload_response = requests.post( upload_url, params=upload_params, files=files, timeout=30 ) upload_response.raise_for_status() # 触发HTTP错误异常 upload_data = upload_response.json() if upload_data.get('success'): print('文件上传成功') else: print(f'上传失败:{upload_data.get("error", {}).get("message", "未知错误")}') except Exception as e: print(f'上传出错:{e}') finally: # 确保文件句柄关闭 files['file'][1].close()
替代上传方案
- WebDAV协议上传:利用Synology支持的WebDAV接口,通过
PUT请求直接上传,无需处理复杂的API参数:
import requests # 替换为你的WebDAV地址(通常为https://<NAS_IP>:5006/<共享文件夹名>/目标文件名.xlsx) webdav_upload_url = f'https://<NAS_IP>:5006/Drive/{os.path.basename(file_path)}' headers = {'Cookie': f'sid={sid}'} with open(file_path, 'rb') as f: response = requests.put(webdav_upload_url, data=f, headers=headers, timeout=30) if response.status_code == 201: print('WebDAV上传成功') else: print(f'WebDAV上传失败:{response.status_code}')
- 第三方Synology Python库:使用社区维护的
synology-api库,简化API调用流程:
from synology_api import filestation # 初始化文件站客户端 fs = filestation.FileStation( '<NAS_IP>', '<端口>', '<用户名>', '<密码>', secure=True, cert_verify=False # 若NAS证书未认证则关闭验证 ) # 上传文件到指定路径 upload_result = fs.upload_file('/Drive', file_path) print(upload_result)
- curl命令测试:先用curl验证API可用性,排除代码逻辑问题:
curl -X POST "http://<NAS_IP>:5000/webapi/entry.cgi?api=SYNO.FileStation.Upload&version=2&method=upload&path=/home/Drive&create_parents=true&_sid=<你的SID>" \ -F "file=@/path/to/your/file.xlsx;type=application/vnd.openxmlformats-officedocument.spreadsheetml.sheet"
内容的提问来源于stack exchange,提问作者NicLovin
相关产品推荐
相关产品推荐

