Làm cách nào tôi có thể sử dụng dịch vụ web WSDL (SOAP) trong Python?


124

Tôi muốn sử dụng dịch vụ web dựa trên WSDL SOAP bằng Python. Tôi đã xem xét mã lặn vào Python nhưng mô-đun SOAPpy không hoạt động theo Python 2.5.

Tôi đã thử sử dụng suds hoạt động một phần, nhưng phá vỡ với một số loại nhất định (suds.TypeNotFound: Loại không tìm thấy: 'item').

Tôi cũng đã xem xét Client nhưng điều này dường như không hỗ trợ WSDL.

Và tôi đã xem xét ZSI nhưng nó có vẻ rất phức tạp. Có ai có bất kỳ mã mẫu cho nó?

WSDL là https://ws.pingdom.com/soap/PingdomAPI.wsdl và hoạt động tốt với máy khách PHP 5 SOAP.


3
Bạn sẽ xem xét thay đổi câu trả lời được chấp nhận của bạn? Câu trả lời hiện được chấp nhận là -1 và có câu trả lời khác với +19. Tôi biết đây là từ năm 2008; Tôi chỉ đề nghị.
Đánh dấu E. Haase

SUDS đã không hoạt động vì nó không thể phân tích WSDL đúng cách nhưng sẽ là một lựa chọn tốt. Vì vậy, tôi đã thay đổi câu trả lời cho một hướng dẫn từ Dive Into Python có một số lựa chọn thay thế. Là một lưu ý phụ, Pingdom hiện có API API APIdomdom.com/service/api-documentation-rest với các thư viện khách tại blog.pingdom.com/2011/04/11/pingdom-rest-api-wrappers
davidmytton

Câu trả lời:


49

Tôi muốn khuyên bạn nên xem SUDS

"Suds là một máy khách python nhẹ SOAP để sử dụng Dịch vụ web."


Biệt phái. Suds có ý nghĩa ngay lập tức với tôi, không có thế hệ lớp, nó tải WSDL trực tiếp và tạo một đối tượng bạn có thể sử dụng ngay lập tức từ nó.
EnigmaCurry

19
Suds có một vấn đề đệ quy vô hạn khi mở WSDL với nhập khẩu đệ quy. Đây được coi là một lỗi chặn bởi Suds và sự cố đã được tạo ra cách đây hơn 3 năm, nhưng nó vẫn chưa được khắc phục. fedorahosted.org/suds/ticket/239 Nó khiến tôi tự hỏi liệu Suds có phù hợp để sử dụng vào năm 2012 không?
Nút840

2
bọt dường như đã chết. SUDS sống lâu - đây dường như là Fork hoạt động.
nerdoc

3
Đây là câu trả lời hàng đầu, nhưng nếu bất cứ ai đang tìm kiếm một câu trả lời hoạt động ngày hôm nay, hãy xem xét Zeep , như các câu trả lời mới hơn cũng đề xuất.
Tobias Feil

25

Có một thư viện tương đối mới rất hứa hẹn và mặc dù vẫn còn tài liệu kém, có vẻ rất sạch sẽ và pythonic: python zeep .

Xem thêm câu trả lời này cho một ví dụ.


2
+1 cho điều này. Tôi đã thử zeep ngày hôm nay và nó rất dễ sử dụng. Đã có thể sử dụng và gọi dịch vụ Xà phòng 1.1 / 1.2 với 3 dòng mã.
Jagu

20

Gần đây tôi đã vấp phải vấn đề tương tự. Đây là tóm tắt của giải pháp của tôi:

Các khối mã cấu thành cơ bản cần thiết

Sau đây là các khối mã cơ bản bắt buộc của ứng dụng khách của bạn

  1. Phần yêu cầu phiên: yêu cầu một phiên với nhà cung cấp
  2. Phần xác thực phiên: cung cấp thông tin đăng nhập cho nhà cung cấp
  3. Phần Client: tạo Client
  4. Phần Tiêu đề bảo mật: thêm Tiêu đề WS-Security vào Máy khách
  5. Phần tiêu thụ: tiêu thụ các hoạt động có sẵn (hoặc phương pháp) khi cần thiết

Những mô-đun nào bạn cần?

Nhiều người đề xuất sử dụng các mô-đun Python như urllib2; tuy nhiên, không có mô-đun nào hoạt động - ít nhất là cho dự án cụ thể này.

Vì vậy, đây là danh sách các mô-đun bạn cần để có được. Trước hết, bạn cần tải xuống và cài đặt phiên bản mới nhất của suds từ liên kết sau:

pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2

Ngoài ra, bạn cần tải xuống và cài đặt các yêu cầu và mô-đun suds numquests từ các liên kết sau tương ứng (từ chối trách nhiệm: Tôi mới đăng bài ở đây, vì vậy hiện tại tôi không thể đăng nhiều hơn một liên kết).

pypi.python.org/pypi/requests

pypi.python.org/pypi/suds_Vquests/0.1

Một khi bạn tải xuống và cài đặt thành công các mô-đun này, bạn sẽ thấy ổn.

Mật mã

Thực hiện theo các bước được nêu trước đó, mã trông như sau: Nhập khẩu:

import logging
from suds.client import Client
from suds.wsse import *
from datetime import timedelta,date,datetime,tzinfo
import requests
from requests.auth import HTTPBasicAuth
import suds_requests

Yêu cầu phiên và xác thực:

username=input('Username:')
password=input('password:')
session = requests.session()
session.auth=(username, password)

Tạo khách hàng:

client = Client(WSDL_URL, faults=False, cachingpolicy=1, location=WSDL_URL, transport=suds_requests.RequestsTransport(session))

Thêm tiêu đề WS-Security:

...
addSecurityHeader(client,username,password)
....

def addSecurityHeader(client,username,password):
    security=Security()
    userNameToken=UsernameToken(username,password)
    timeStampToken=Timestamp(validity=600)
    security.tokens.append(userNameToken)
    security.tokens.append(timeStampToken)
    client.set_options(wsse=security)

Xin lưu ý rằng phương thức này tạo tiêu đề bảo mật được mô tả trong hình 1. Vì vậy, việc triển khai của bạn có thể thay đổi tùy thuộc vào định dạng tiêu đề bảo mật chính xác được cung cấp bởi chủ sở hữu dịch vụ bạn đang tiêu thụ.

Sử dụng phương pháp liên quan (hoặc hoạt động):

result=client.service.methodName(Inputs)

Ghi nhật ký :

Một trong những thực tiễn tốt nhất trong việc triển khai như thế này là đăng nhập để xem cách truyền thông được thực hiện. Trong trường hợp có một số vấn đề, nó làm cho việc gỡ lỗi dễ dàng. Các mã sau đây không đăng nhập cơ bản. Tuy nhiên, bạn có thể đăng nhập nhiều khía cạnh của giao tiếp ngoài những khía cạnh được mô tả trong mã.

logging.basicConfig(level=logging.INFO) 
logging.getLogger('suds.client').setLevel(logging.DEBUG) 
logging.getLogger('suds.transport').setLevel(logging.DEBUG)

Kết quả:

Đây là kết quả trong trường hợp của tôi. Lưu ý rằng máy chủ trả về HTTP 200. Đây là mã thành công tiêu chuẩn cho phản hồi yêu cầu HTTP.

(200, (collectionNodeLmp){
   timestamp = 2014-12-03 00:00:00-05:00
   nodeLmp[] = 
      (nodeLmp){
         pnodeId = 35010357
         name = "YADKIN"
         mccValue = -0.19
         mlcValue = -0.13
         price = 36.46
         type = "500 KV"
         timestamp = 2014-12-03 01:00:00-05:00
         errorCodeId = 0
      },
      (nodeLmp){
         pnodeId = 33138769
         name = "ZION 1"
         mccValue = -0.18
         mlcValue = -1.86
         price = 34.75
         type = "Aggregate"
         timestamp = 2014-12-03 01:00:00-05:00
         errorCodeId = 0
      },
 })

1
Có thể đáng để nói rằng suds_requestsẽ thất bại trong khi cài đặt, vì vậy nếu bạn đang sử dụng suds-jurkofork, bạn có thể cài đặt suds_requestđược điều chỉnh để hoạt động với phiên bản suds của Jurko:pip install git+https://github.com/chrcoe/suds_requests.git@feature/python3_suds_jurko
errata

7

Ngay bây giờ (tính đến năm 2008), tất cả các thư viện SOAP có sẵn cho Python hút. Tôi khuyên bạn nên tránh SOAP nếu có thể. Lần cuối cùng chúng tôi buộc phải sử dụng dịch vụ web SOAP từ Python, chúng tôi đã viết một trình bao bọc trong C # xử lý SOAP ở một bên và nói COM bên kia.


15
Nghe có vẻ như là một cách cực kỳ phức tạp để sử dụng một giao thức đơn giản dựa trên xml và http.
ddaa

1
Vào thời điểm đó, năm 2008, đây là phương pháp ít nhất cho nhu cầu của chúng ta. Tôi dường như nhớ rằng dịch vụ web cụ thể đó cực kỳ kén chọn điều gì đó mà tất cả các thư viện python đã bị sai.
Matthew Scouten

1
2019, python zeep, suds, vẫn có nhiều vấn đề không tương thích phân tích cú pháp. Việc duy trì kém các tài liệu wsdl sẽ khiến các mô-đun đó ném ngoại lệ như pháo không ngừng.
xe mô tô


6

Tôi định kỳ tìm kiếm một câu trả lời thỏa đáng cho điều này, nhưng không có may mắn cho đến nay. Tôi sử dụng xà phòng + yêu cầu + lao động thủ công.

Tôi đã từ bỏ và sử dụng Java lần cuối cùng tôi cần để làm điều này và chỉ đơn giản là đã từ bỏ một vài lần lần cuối cùng tôi muốn làm điều này, nhưng nó không cần thiết.

Đã sử dụng thành công thư viện yêu cầu vào năm ngoái với API RESTful của Project Place, tôi nhận thấy rằng có lẽ tôi chỉ có thể cuộn các yêu cầu SOAP mà tôi muốn gửi theo cách tương tự.

Lần lượt ra đó không phải là quá khó khăn, nhưng nó tốn nhiều thời gian và dễ bị lỗi, đặc biệt là nếu các trường được nhất quán tên là (một trong những Tôi hiện đang làm việc ngày hôm nay có 'jobId', JobId' và 'JobID'. Tôi sử dụng soapUI để tải WSDL để giúp trích xuất các điểm cuối dễ dàng hơn v.v. và thực hiện một số thử nghiệm thủ công. Cho đến nay tôi đã may mắn không bị ảnh hưởng bởi các thay đổi đối với bất kỳ WSDL nào tôi đang sử dụng.


3

Điều đó không đúng SOAPpy không hoạt động với Python 2.5 - nó hoạt động, mặc dù nó rất đơn giản và thực sự, thực sự cơ bản. Nếu bạn muốn nói chuyện với bất kỳ dịch vụ web phức tạp hơn, ZSI là người bạn duy nhất của bạn.

Bản demo thực sự hữu ích mà tôi tìm thấy là tại http://www.ebi.ac.uk/Tools/webservice/tutorials/python - điều này thực sự giúp tôi hiểu cách ZSI hoạt động.


1
cài đặt python setup.py cung cấp lỗi với bản phát hành mới nhất. Bản sao dev mới nhất có thể hoạt động nhưng đó là một nỗi đau để làm.
davidmytton


1

SOAPpy hiện đã lỗi thời, AFAIK, được thay thế bằng ZSL. Đó là một điểm cần thiết, bởi vì tôi không thể làm cho một trong hai hoạt động, biên dịch ít hơn nhiều, trên Python 2.5 hoặc Python 2.6


1
#!/usr/bin/python
# -*- coding: utf-8 -*-
# consume_wsdl_soap_ws_pss.py
import logging.config
from pysimplesoap.client import SoapClient

logging.config.dictConfig({
    'version': 1,
    'formatters': {
        'verbose': {
            'format': '%(name)s: %(message)s'
        }
    },
    'handlers': {
        'console': {
            'level': 'DEBUG',
            'class': 'logging.StreamHandler',
            'formatter': 'verbose',
        },
    },
    'loggers': {
        'pysimplesoap.helpers': {
            'level': 'DEBUG',
            'propagate': True,
            'handlers': ['console'],
        },
    }
})

WSDL_URL = 'http://www.webservicex.net/stockquote.asmx?WSDL'
client = SoapClient(wsdl=WSDL_URL, ns="web", trace=True)
client['AuthHeaderElement'] = {'username': 'someone', 'password': 'nottelling'}

#Discover operations
list_of_services = [service for service in client.services]
print(list_of_services)

#Discover params
method = client.services['StockQuote']

response = client.GetQuote(symbol='GOOG')
print('GetQuote: {}'.format(response['GetQuoteResult']))

lib được liệt kê ở đây: code.google.com/archive/p/pysimplesoap
Xuống dòng

đầu ra mẫu: ... DEBUG: pysimplesoap.helpers: ComplexContent / simpleType / Element string = string [u'StockQuote '] GetQuote: <StockQuotes> <Stock> <Symbol> GOOG </ Symbol> <Last> 816.13 </ Last> <Ngày> 23/03/2017 </ Ngày> <Thời gian> 11:41 sáng </ Thời gian> <Thay đổi> -13,46 </ Thay đổi> <Mở> 820,01 </ Mở> <Cao> 822,57 </ Cao> <Thấp> 812,26 </ Thấp> <Âm lượng> 1973140 </ Âm lượng> <MktCap> 564,29B </ MktCap> <BeforeClose> 829.59 </ BeforeC Đóng> <PercentageChange> -1,62% </ PercentageChange> <AnnRange> 663.28 <Kiếm được> 27,88 </ Thu nhập> <PE> 29,28 </ PE> <Tên> Bảng chữ cái Inc. </ Tên> </ Stock> </ StockQuotes>
Xuống suối

không thành công trên Python3 trong pysimplesoap / client.py: 757 - đối tượng 'dict' không có thuộc tính 'iteritems'
ierdna

rõ ràng phiên bản đi kèm với PIP bị hỏng. phải cài đặt thủ công từ GIT - nó sửa mọi thứ
ierdna

Điểm hay: xem liên kết này: stackoverflow.com/questions/13998492/iteritems-in-python "dict.iteritems đã bị xóa vì dict.items hiện tại điều dict.iteritems đã làm trong python 2 ..."
Xuống Stream
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.