你能帮我解决这个 SUDS/SOAP 问题吗?
所以我试图访问这个api https://www.clarityaccounting.com/api-docs/ 使用 SUDS。这是应该工作的代码:
from suds.client import Client
client = Client('https://www.clarityaccounting.com/api/v1?wsdl')
token = client.service.doLogin('demo', 'demo', 'www.kashoo.com', 'en_US', 300000)
但我收到此错误:
WebFault: Server raised fault: 'No such operation: (HTTP GET PATH_INFO: /api/v1)'
他们的支持人员说请求应该如下所示:
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:api="http://api.service.books/">
<SOAP-ENV:Body>
<api:doLogin>
<username>demo</username>
<password>demo</password>
<siteName>www.kashoo.com</siteName>
<locale>en_US</locale>
<duration>300000</duration>
</api:doLogin>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
但 SUDS 看起来像这样:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:ns0="http://api.service.books/"
xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:doLogin>
<username>demo</username>
<password>demo</password>
<siteName>www.kashoo.com</siteName>
<locale>en_US</locale>
<duration>300000</duration>
</ns0:doLogin>
</ns1:Body>
</SOAP-ENV:Envelope>
我是一个真正的 SOAP 和 SUDS 新手,但我听说 SUDS 是最好的从这里使用的 SOAP 库: Python 存在哪些 SOAP 客户端库,它们的文档在哪里?
所以我的问题是简单地说,有哪些不同的关键部分导致请求失败,以及如何配置 SUDS 来发送格式正确的请求?
So I'm trying to access this api https://www.clarityaccounting.com/api-docs/ using SUDS. Here is the code that should work:
from suds.client import Client
client = Client('https://www.clarityaccounting.com/api/v1?wsdl')
token = client.service.doLogin('demo', 'demo', 'www.kashoo.com', 'en_US', 300000)
But I get this error:
WebFault: Server raised fault: 'No such operation: (HTTP GET PATH_INFO: /api/v1)'
Their support guy says that the request should look like this:
<SOAP-ENV:Envelope
SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:SOAP-ENC="http://schemas.xmlsoap.org/soap/encoding/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:xsd="http://www.w3.org/2001/XMLSchema"
xmlns:api="http://api.service.books/">
<SOAP-ENV:Body>
<api:doLogin>
<username>demo</username>
<password>demo</password>
<siteName>www.kashoo.com</siteName>
<locale>en_US</locale>
<duration>300000</duration>
</api:doLogin>
</SOAP-ENV:Body>
</SOAP-ENV:Envelope>
But SUDS' looks like this:
<?xml version="1.0" encoding="UTF-8"?>
<SOAP-ENV:Envelope
xmlns:ns0="http://api.service.books/"
xmlns:ns1="http://schemas.xmlsoap.org/soap/envelope/"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/">
<SOAP-ENV:Header/>
<ns1:Body>
<ns0:doLogin>
<username>demo</username>
<password>demo</password>
<siteName>www.kashoo.com</siteName>
<locale>en_US</locale>
<duration>300000</duration>
</ns0:doLogin>
</ns1:Body>
</SOAP-ENV:Envelope>
I'm a real SOAP and SUDS newbie but I heard that SUDS is the best SOAP library to use from here: What SOAP client libraries exist for Python, and where is the documentation for them?
So my question is simply what are the crucial parts that are different and that are making the request fail and how can I configure SUDS to send the properly formatted request?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
乍一看,您遇到的问题似乎出在 SSL 上。您正在访问 https URL,并且 suds.client 的传输处理程序默认使用 http。
问题
如果您查看 WSDL 的底部,它会将默认位置指定为
http://www.clarityaccounting.com/api/v1
,这是一个 http URL,但 WSDL 是 SSL。如果您对该 URL 执行 http GET,您会收到收到的错误消息:
解决方案
要解决此问题,您需要在调用
Client
构造函数时覆盖默认位置,以使其与 https:Victory! 保持一致
,以供将来调试之用的专业提示:打开完整日志记录调试。 SUDS 使用标准
logging
库,因此它为您提供了很多控制权。所以我把它全部调高到DEBUG
:这帮助我缩小了范围,因为它清楚地表明它是通过http发送的:
然后响应也这么说:
At first glance looks like the problem you're having is with SSL. You are accessing an https URL, and the Transport handler for suds.client talks http by default.
The problem
If you look at the bottom of the WSDL it is specifying the default location as
http://www.clarityaccounting.com/api/v1
, which is an http URL, but the WSDL is SSL.If you do an http GET on that URL, you get the error message you received:
The Solution
To fix this you need to override the default location when you call the
Client
constructor to make it stick with https:Victory!
Pro tip for future debugging purposes: Turn on full logging debugging. SUDS uses the standard
logging
library, so it gives you a lot of control. So I cranked it all up toDEBUG
:This is what helped me narrow it down, because it was clearly saying it was sending over http:
And then the response said so as well:
使用suds-jurko https://pypi.python.org/pypi/suds-jurko这是一个维护的泡沫叉子。
您可以传入 __inject 选项,您可以在其中为其提供要发送的原始 xml。
我觉得我应该记录人们可以在这里检查泡沫产生的生肥皂的所有方法。
构建客户端时使用 nosend 标志。请注意,当该标志设置为 True 时,suds 将仅生成肥皂,但不会发送它。
client =Client(url, nosend=True)
res = client.service.example()
print res.envelope
#打印原始肥皂使用日志记录。这里我们只记录 suds.transport.http,因此它只会输出发送/接收的内容。
导入日志记录
导入系统
handler =logging.StreamHandler(sys.stderr)
logger =logging.getLogger('suds.transport.http')
logger.setLevel(logging.DEBUG), handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
使用 MessagePlugin
从 suds.plugin 导入 MessagePlugin
类MyPlugin(MessagePlugin):
def marshalled(self, context):
#导入pdb; pdb.set_trace()
打印 context.envelope.str()
client = Client(url, plugins=[MyPlugin()])
MessagePlugin 不仅使您能够检查生成的肥皂但您也可以在发送前修改它,请参阅-> https://jortel.fedorapeople.org/suds/doc/suds .plugin.MessagePlugin-class.html
Using suds-jurko https://pypi.python.org/pypi/suds-jurko which is a maintained fork of suds.
You can pass in an __inject option where you can give it the raw xml you want to send.
I feel like I should document all the ways that one can inspect the Raw soap that suds generates here.
Using a nosend flag when constructing the client. Please note that with the flag set to True, suds will just generate the soap but not send it.
client =Client(url, nosend=True)
res = client.service.example()
print res.envelope
#prints the raw soapUsing logging. Here we are only logging suds.transport.http, so it will only output whatever is sent/received.
import logging
import sys
handler = logging.StreamHandler(sys.stderr)
logger = logging.getLogger('suds.transport.http')
logger.setLevel(logging.DEBUG), handler.setLevel(logging.DEBUG)
logger.addHandler(handler)
Using the MessagePlugin
from suds.plugin import MessagePlugin
class MyPlugin(MessagePlugin):
def marshalled(self, context):
#import pdb; pdb.set_trace()
print context.envelope.str()
client = Client(url, plugins=[MyPlugin()])
Not only does the MessagePlugin give you the ability to inspect the soap generated but you can also modify it before sending, see-> https://jortel.fedorapeople.org/suds/doc/suds.plugin.MessagePlugin-class.html
这不应该是与通过 HTTPS 连接到服务相关的问题。我正在使用泡沫来做同样的事情。我尝试了几种处理您的 WSDL 文件的方法(我自己不是专家),但遇到了相同的错误。不过,作为使用 suds 的练习,您应该使用 factory 方法,例如
发送到 create 函数的任何内容都是 WSDL 文件中定义的类型之一。如果您在 shell 中创建该类型,则可以运行“打印登录”来查看其附加属性。
希望这至少能告诉您问题所在(使用 HTTPS)。另外,我注意到 WSDL 文件中未设置soapAction 标头,不确定suds 或服务如何在没有该标头的情况下处理请求。
It shouldn't be a problem related to connecting to a service over HTTPS. I'm using suds to do the same thing. I've tried a few approaches to your WSDL file (not an expert myself) and encountered the same error. What you should do as practice with suds though is use the factory method, e.g.
Where anything sent to the create function is one of the types defined in the WSDL file. If you create that type in the shell you can run 'print login' to see its additional properties.
Hope this at least tells you where the problem isn't (with HTTPS). Also, I noticed that the soapAction headers aren't set in the WSDL file, not sure how suds or the service handles requests without that.