如何用Python生成SOAPUI风格的Adjust_Asset_Cost请求?
解决Zeep生成Workday Adjust_Asset_Cost SOAP请求的"服务未找到"问题
问题背景
需要用Python生成和SOAPUI一致的Adjust_Asset_Cost操作SOAP请求样本,用于后续字符串处理。对应WSDL地址:https://wd2-impl-services1.workday.com/ccx/service/workdayproserv_dpt2/Resource_Management/v41.0?wsdl,无需用户凭证/令牌。但使用Zeep库时触发"服务未找到"错误,已确认该操作存在。
原Zeep代码:
from zeep import Client from zeep.wsse.username import UsernameToken # Define the WSDL URL and operation name wsdl_url = "https://wd2-impl-services1.workday.com/ccx/service/workdayproserv_dpt2/Resource_Management/v41.0?wsdl" operation_name = "Adjust_Asset_Cost" # Create a Zeep client using the WSDL URL client = Client(wsdl=wsdl_url) # Print the sample request for the specified operation operation = client.bind(operation_name, "adjustAssetCost") sample_request = client.create_message(operation_name, _soapheaders=[UsernameToken("", "")]) print(sample_request)
SOAPUI生成的目标请求样本:
<soapenv:Envelope xmlns:soapenv="http://schemas.xmlsoap.org/soap/envelope/" xmlns:bsvc="urn:com.workday/bsvc"> <soapenv:Header> <bsvc:Workday_Common_Header> <!--Optional:--> <bsvc:Include_Reference_Descriptors_In_Response>?</bsvc:Include_Reference_Descriptors_In_Response> </bsvc:Workday_Common_Header> </soapenv:Header> <soapenv:Body> <bsvc:Adjust_Asset_Cost_Request bsvc:version="?"> <bsvc:Business_Asset_Reference bsvc:Descriptor="?"> <!--Zero or more repetitions:--> <bsvc:ID bsvc:type="?">?</bsvc:ID> </bsvc:Business_Asset_Reference> <!--Optional:--> <bsvc:Business_Process_Parameters> <!--Optional:--> <bsvc:Auto_Complete>?</bsvc:Auto_Complete> <!--Optional:--> <bsvc:Comment_Data> <!--Optional:--> <bsvc:Comment>?</bsvc:Comment> <!--Optional:--> <bsvc:Worker_Reference bsvc:Descriptor="?"> <!--Zero or more repetitions:--> <bsvc:ID bsvc:type="?">?</bsvc:ID> </bsvc:Worker_Reference> </bsvc:Comment_Data> </bsvc:Business_Process_Parameters> <bsvc:Business_Asset_Cost_Adjustment_Data> <!--Optional:--> <bsvc:Post_Acquisition_Adjustment>?</bsvc:Post_Acquisition_Adjustment> <!--Optional:--> <bsvc:Transaction_Effective_Date>?</bsvc:Transaction_Effective_Date> <!--Optional:--> <bsvc:Currency_Reference bsvc:Descriptor="?"> <!--Zero or more repetitions:--> <bsvc:ID bsvc:type="?">?</bsvc:ID> </bsvc:Currency_Reference> <!--Optional:--> <bsvc:Adjustment_Amount>?</bsvc:Adjustment_Amount> <!--Optional:--> <bsvc:Adjustment_Quantity>?</bsvc:Adjustment_Quantity> <!--Optional:--> <bsvc:Adjustment_Residual_Value>?</bsvc:Adjustment_Residual_Value> <!--Optional:--> <bsvc:Accounting_Date>?</bsvc:Accounting_Date> <!--Zero or more repetitions:--> <bsvc:Restricted_to_Books_Reference bsvc:Descriptor="?"> <!--Zero or more repetitions:--> <bsvc:ID bsvc:type="?">?</bsvc:ID> </bsvc:Restricted_to_Books_Reference> <!--Optional:--> <bsvc:Adjustment_Reason_Reference bsvc:Descriptor="?"> <!--Zero or more repetitions:--> <bsvc:ID bsvc:type="?">?</bsvc:ID> </bsvc:Adjustment_Reason_Reference> <!--Optional:--> <bsvc:Supplier_Invoice_Line_Reference_ID>?</bsvc:Supplier_Invoice_Line_Reference_ID> </bsvc:Business_Asset_Cost_Adjustment_Data> </bsvc:Adjust_Asset_Cost_Request> </soapenv:Body> </soapenv:Envelope>
错误原因
client.bind方法参数错误:Zeep的bind需要先指定服务名称和端口名称,而非直接传操作名create_message第一个参数应为绑定后的operation对象,不是操作名字符串- 错误使用
UsernameToken作为SOAP头:Workday该接口需要的是Workday_Common_Header,且无需凭证
修正后的代码
from zeep import Client, xsd from zeep.wsdl.utils import etree_to_string wsdl_url = "https://wd2-impl-services1.workday.com/ccx/service/workdayproserv_dpt2/Resource_Management/v41.0?wsdl" operation_name = "Adjust_Asset_Cost" # 初始化Zeep客户端 client = Client(wsdl=wsdl_url) # 绑定正确的服务和端口:对应WSDL中的Resource_Management_Service和Resource_Management_Port service = client.bind("Resource_Management_Service", "Resource_Management_Port") operation = getattr(service, operation_name) # 构造Workday通用头(匹配SOAPUI中的结构) common_header = client.get_type("ns0:Workday_Common_Header")( Include_Reference_Descriptors_In_Response="?" ) # 构造请求参数框架(匹配SOAPUI的占位符结构) request_params = { "Business_Asset_Reference": client.get_type("ns0:Business_AssetObjectIDType")( ID=[client.get_type("ns0:Workday_Common_IDType")(type="?", _value_1="?")] ), "Business_Process_Parameters": client.get_type("ns0:Business_Process_ParametersType")( Auto_Complete="?", Comment_Data=client.get_type("ns0:Comment_DataType")( Comment="?", Worker_Reference=client.get_type("ns0:WorkerObjectIDType")( ID=[client.get_type("ns0:Workday_Common_IDType")(type="?", _value_1="?")] ) ) ), "Business_Asset_Cost_Adjustment_Data": client.get_type("ns0:Business_Asset_Cost_Adjustment_DataType")( Post_Acquisition_Adjustment="?", Transaction_Effective_Date="?", Currency_Reference=client.get_type("ns0:CurrencyObjectIDType")( ID=[client.get_type("ns0:Workday_Common_IDType")(type="?", _value_1="?")] ), Adjustment_Amount="?", Adjustment_Quantity="?", Adjustment_Residual_Value="?", Accounting_Date="?", Restricted_to_Books_Reference=[client.get_type("ns0:Accounting_BookObjectIDType")( ID=[client.get_type("ns0:Workday_Common_IDType")(type="?", _value_1="?")] )], Adjustment_Reason_Reference=client.get_type("ns0:Adjustment_ReasonObjectIDType")( ID=[client.get_type("ns0:Workday_Common_IDType")(type="?", _value_1="?")] ), Supplier_Invoice_Line_Reference_ID="?" ) } # 生成SOAP请求消息 sample_request = client.create_message(operation, _soapheaders=[common_header], **request_params) # 转换为字符串方便后续处理 request_str = etree_to_string(sample_request) print(request_str)
说明
- 运行修正后的代码会生成与SOAPUI结构、占位符完全一致的SOAP请求XML
- 可根据需求将占位符
?替换为实际业务数据 - 若不需要某些可选字段,可将对应参数替换为
xsd.Skip(),生成的XML会自动忽略该字段
内容的提问来源于stack exchange,提问作者Code_Journey_4_Fun
相关产品推荐
相关产品推荐

