2010-03-05 26 views
15

Vì vậy, tôi đang cố truy cập vào api https://www.clarityaccounting.com/api-docs/ này bằng SUDS. Dưới đây là đoạn code mà nên làm việc:Bạn có thể giúp tôi giải quyết vấn đề SUDS/SOAP này không?

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) 

Nhưng tôi nhận được lỗi này:

WebFault: Server raised fault: 'No such operation: (HTTP GET PATH_INFO: /api/v1)' 

chàng hỗ trợ của họ nói rằng đề nghị nên xem xét như thế này:

<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> 

Nhưng bọt' trông giống như sau:

<?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> 

Tôi thực sự là SOAP và SUDS newbie nhưng tôi nghe nói rằng SUDS là thư viện SOAP tốt nhất để sử dụng tại đây: What SOAP client libraries exist for Python, and where is the documentation for them?

Vì vậy, câu hỏi của tôi chỉ đơn giản là những phần quan trọng khác nhau và đang đưa ra yêu cầu thất bại và làm cách nào tôi có thể định cấu hình SUDS để gửi yêu cầu được định dạng đúng?

Trả lời

35

Thoạt nhìn, có vẻ như vấn đề bạn gặp phải là với SSL. Bạn đang truy cập URL https và trình xử lý Giao thông vận tải cho suds.client đàm phán http theo mặc định.

Vấn đề
Nếu bạn nhìn vào phía dưới của WSDL nó được quy định cụ thể vị trí mặc định như http://www.clarityaccounting.com/api/v1, mà là một URL http, nhưng WSDL là SSL.

<wsdl:service name="v1"> 
    <wsdl:port binding="tns:v1SoapBinding" name="BooksApiV1Port"> 
     <soap:address location="http://www.clarityaccounting.com/api/v1"/> 
    </wsdl:port> 
</wsdl:service> 

Nếu bạn làm một http GET trên URL đó, bạn nhận được thông báo lỗi mà bạn nhận được:

<soap:Envelope xmlns:soap="http://schemas.xmlsoap.org/soap/envelope/"> 
    <soap:Body> 
     <soap:Fault> 
      <faultcode>soap:Server</faultcode> 
      <faultstring>No such operation: (HTTP GET PATH_INFO: /api/v1)</faultstring> 
     </soap:Fault> 
    </soap:Body> 
</soap:Envelope> 

Giải pháp
Để khắc phục điều này, bạn cần phải ghi đè vị trí mặc định khi bạn hãy gọi cho nhà xây dựng Client để làm cho nó gắn với https:

>>> url 
'https://www.clarityaccounting.com/api/v1?wsdl' 
>>> client = Client(url, location='https://www.clarityaccounting.com/api/v1') 
>>> token = client.service.doLogin('demo', 'demo', 'www.kashoo.com', 'en_US', 300000) 
>>> token 
(authToken){ 
    authenticationCode = "ObaicdMJZY6UM8xZ2wzGjicT0jQ=" 
    expiryDate = 2010-03-05 12:31:41.000698 
    locale = "en_US" 
    myUserId = 4163 
    site = "www.kashoo.com" 
} 

Chiến thắng!

Mẹo chuyên nghiệp cho các mục đích gỡ lỗi trong tương lai: Bật gỡ lỗi ghi nhật ký đầy đủ. SUDS sử dụng thư viện chuẩn logging, vì vậy, nó cung cấp cho bạn rất nhiều quyền kiểm soát. Vì vậy, tôi cranked nó tất cả lên đến DEBUG:

import logging 
logging.basicConfig(level=logging.INFO) 
logging.getLogger('suds.client').setLevel(logging.DEBUG) 
logging.getLogger('suds.transport').setLevel(logging.DEBUG) 
logging.getLogger('suds.xsd.schema').setLevel(logging.DEBUG) 
logging.getLogger('suds.wsdl').setLevel(logging.DEBUG) 

Đây là những gì giúp tôi thu hẹp nó xuống, bởi vì nó đã được rõ ràng rằng nó đã được gửi qua http:

DEBUG:suds.transport.http:sending: 
URL:http://www.clarityaccounting.com/api/v1 
(xml output omitted) 

Và sau đó phản ứng nói như vậy là well:

DEBUG:suds.client:http failed: 
+1

Rất vui được giúp đỡ! Đó là một vấn đề thú vị để tìm ra vào một buổi chiều thứ Sáu. – jathanism

+3

+1 Chạm đẹp để giúp gỡ lỗi – Draemon

+0

Cảm ơn bạn! Tôi chỉ gặp sự cố tương tự với một dịch vụ web khác, nhưng cùng một vấn đề https/http. Tôi không thể tìm cách thiết lập ứng dụng khách sử dụng https mặc dù WSDL đã sử dụng http. –

1

Nó không phải là vấn đề liên quan đến kết nối với dịch vụ qua HTTPS. Tôi đang sử dụng suds để làm điều tương tự. Tôi đã thử một vài cách tiếp cận tệp WSDL của bạn (không phải là một chuyên gia bản thân) và gặp phải lỗi tương tự. Những gì bạn nên làm khi thực hành với các bọt mặc dù đang sử dụng phương pháp nhà máy, ví dụ:

login = client.factory.create('doLogin') 
login.username = 'username' 
etc... 

Trường hợp bất kỳ thứ gì được gửi đến hàm tạo là một trong các loại được xác định trong tệp WSDL. Nếu bạn tạo kiểu đó trong shell, bạn có thể chạy 'print login' để xem các thuộc tính bổ sung của nó.

Hy vọng điều này ít nhất sẽ cho bạn biết vấn đề ở đâu (với HTTPS). Ngoài ra, tôi nhận thấy rằng các tiêu đề soapAction không được đặt trong tệp WSDL, không chắc chắn cách thức các dịch vụ xử lý các yêu cầu không có điều đó.

+0

Như bạn có thể thấy trong câu trả lời đã sửa đổi của tôi, vấn đề không phải là kết nối qua https, nhưng với sự không thống nhất trong WSDL đang được phục vụ trên https, trong khi đó chỉ các cuộc gọi SOAP đến http. Tôi đoán là cách họ có dịch vụ được cấu hình để chuyển hướng các URL đến từ http đến https là nguồn gốc của vấn đề. Tất cả những gì chúng tôi thực sự làm là làm việc xung quanh nó. – jathanism

+0

Gỡ lỗi cho chiến thắng zee! – bennylope

1

Sử dụng suds-jurko https://pypi.python.org/pypi/suds-jurko là một nĩa duy trì của bọt. Bạn có thể chuyển vào tùy chọn __inject nơi bạn có thể cung cấp cho nó xml thô bạn muốn gửi.

from suds.client import Client 

username, password, sitename, locale, duration = 'demo', 'demo', 'www.kashoo.com', 'en_US', 300000 

raw_xml = """<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>{0}</username> 
     <password>{1}</password> 
     <siteName>{2}</siteName> 
     <locale>{3}</locale> 
     <duration>{4}</duration> 
    </api:doLogin> 
    </SOAP-ENV:Body> 
</SOAP-ENV:Envelope>""".format(username, password, sitename, locale, duration) 

client = Client(url, location) 
result = client.service.doLogin(__inject={'msg':raw_xml}) 

Tôi cảm thấy mình nên ghi lại tất cả các cách mà người ta có thể kiểm tra xà phòng thô tạo ra ở đây.

  1. Sử dụng cờ mũi đất khi xây dựng ứng dụng khách. Xin lưu ý rằng với cờ được đặt thành True, suds sẽ chỉ tạo ra xà phòng nhưng không gửi nó.

    client =Client(url, nosend=True)
    res = client.service.example()
    print res.envelope #prints xà phòng thô

  2. Sử dụng khai thác gỗ. Ở đây chúng ta chỉ đăng nhập suds.transport.http, vì vậy nó sẽ chỉ xuất ra bất cứ thứ gì được gửi/nhận.

    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)

  3. Sử dụng 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()])

Không chỉ MessagePlugin cung cấp cho bạn khả năng kiểm tra việc xà phòng được tạo ra nhưng bạn cũng có thể sửa đổi nó trước khi gửi, see->https://jortel.fedorapeople.org/suds/doc/suds.plugin.MessagePlugin-class.html

Các vấn đề liên quan