使用Python调用Workday Put_Worker_Document接口上传文件失败求助
解决Workday Put_Worker_Document API文件上传问题
一、修复基于Zeep的脚本
错误原因
报错TypeError: {urn:com.workday/bsvc}Document_Category__All_ObjectIDType() got an unexpected keyword argument 'ID',核心问题是你传递的Reference结构不符合Zeep生成的Workday类型签名:
- Workday的
ObjectIDType要求直接传递ID值和type参数,而非嵌套字典 File字段为base64Binary类型,无需手动编码,Zeep会自动处理二进制内容
修复后的代码
import base64 from zeep import Client, Settings from zeep.wsse.username import UsernameToken from zeep.helpers import serialize_object # Workday配置 wsdl = 'https://wd2-impl-services1.workday.com/ccx/service/<my tenant>/Staffing/v42.0?wsdl' endpoint = 'https://wd2-impl-services1.workday.com/ccx/service/<my tenant>/Staffing/v42.0' username = '<my user name>' password = '<my password>' # 初始化Zeep客户端 settings = Settings(strict=False, xml_huge_tree=True) client = Client(wsdl=wsdl, wsse=UsernameToken(username, password), settings=settings) # 获取Workday类型定义 WorkerObjectID = client.get_type('bsvc:WorkerObjectIDType') DocumentCategoryObjectID = client.get_type('bsvc:Document_Category__All_ObjectIDType') # 读取文件二进制内容(无需手动base64编码) file_path = r'd:/path/to/file.pdf' with open(file_path, 'rb') as file: file_content = file.read() # 构造请求参数 worker_reference = WorkerObjectID('<worker id>', type='WID') document_category_reference = DocumentCategoryObjectID('<category id>', type='WID') document_data = { 'Filename': 'file.pdf', 'Comment': 'Uploaded via API Test 1', 'File': file_content, 'Document_Category_Reference': {'ID': [document_category_reference]}, 'Worker_Reference': {'ID': [worker_reference]}, 'Content_Type': 'application/pdf' } # 调用API response = client.service.Put_Worker_Document(Worker_Document_Data=document_data) print(serialize_object(response))
二、修复原生XML脚本
错误原因
500服务器错误通常由XML格式错误或参数无效导致,你的代码存在以下问题:
- 新建文档时包含空的
<bsvc:ID>字段,该字段仅在更新文档时需要 - 占位符
<category id>和<employee id>未替换为实际有效WID - 错误使用HTTP Basic Auth,Workday SOAP API默认使用WSSE认证
修复后的代码
import base64 from zeep import Client, Settings, Transport from zeep.wsse.username import UsernameToken from requests import Session from lxml import etree # Workday配置 wsdl = 'https://wd2-impl-services1.workday.com/ccx/service/<my tenant>/Staffing/v42.0?wsdl' endpoint = 'https://wd2-impl-services1.workday.com/ccx/service/<my tenant>/Staffing/v42.0' username = '<my username>' password = '<my password>' # 使用WSSE认证初始化客户端 session = Session() transport = Transport(session=session) settings = Settings(strict=False, xml_huge_tree=True) client = Client(wsdl=wsdl, wsse=UsernameToken(username, password), transport=transport, settings=settings) # 读取文件并手动base64编码 file_path = r'd:/path/to/file.pdf' with open(file_path, 'rb') as file: file_content = base64.b64encode(file.read()).decode('utf-8') # 构造正确的XML请求(移除空ID字段,替换占位符) raw_xml = f""" <soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bsvc="urn:com.workday/bsvc"> <soapenv:Header/> <soapenv:Body> <bsvc:Put_Worker_Document_Request> <bsvc:Worker_Document_Data> <bsvc:Filename>file.pdf</bsvc:Filename> <bsvc:Comment>Uploaded via API Test 1</bsvc:Comment> <bsvc:File>{file_content}</bsvc:File> <bsvc:Document_Category_Reference> <bsvc:ID bsvc:type="WID">实际文档分类WID</bsvc:ID> </bsvc:Document_Category_Reference> <bsvc:Worker_Reference> <bsvc:ID bsvc:type="WID">实际员工WID</bsvc:ID> </bsvc:Worker_Reference> <bsvc:Content_Type>application/pdf</bsvc:Content_Type> </bsvc:Worker_Document_Data> </bsvc:Put_Worker_Document_Request> </soapenv:Body> </soapenv:Envelope> """ # 发送请求并打印完整响应 parsed_xml = etree.fromstring(raw_xml) headers = { 'Content-Type': 'text/xml; charset=utf-8', 'SOAPAction': 'urn:com.workday/bsvc#Put_Worker_Document' } response = client.transport.post_xml(address=endpoint, envelope=parsed_xml, headers=headers) print(etree.tostring(response._response.content, pretty_print=True).decode('utf-8'))
三、调试建议
- 启用Zeep日志:添加以下代码查看生成的XML请求,确认是否符合Workday规范:
import logging logging.basicConfig(level=logging.DEBUG) - 验证WID有效性:通过Workday UI或
Get_Worker等API获取正确的员工和文档分类WID - 检查权限:确认账号拥有
Put_Worker_Document操作权限及对应文档分类的访问权限 - Postman预测试:先在Postman中构造正确的XML请求验证通过后,再移植到Python脚本
- 查看Workday日志:联系管理员获取服务器端详细错误日志,500错误通常包含具体原因
内容的提问来源于stack exchange,提问作者BlindWiz
相关产品推荐
相关产品推荐

