ฉันจะใช้บริการเว็บ WSDL (SOAP) ใน Python ได้อย่างไร


124

ฉันต้องการใช้บริการเว็บที่ใช้ WSDL SOAP ใน Python ฉันได้ดูโค้ดDive Into Python แล้วแต่โมดูล SOAPpy ไม่ทำงานภายใต้ Python 2.5

ฉันได้ลองใช้sudsซึ่งใช้งานได้บางส่วน แต่แตกกับบางประเภท (suds.TypeNotFound: Type not found: 'item')

ฉันได้ดูClient แล้วแต่ดูเหมือนว่าจะไม่รองรับ WSDL

และฉันได้ดูZSIแต่มันดูซับซ้อนมาก ใครมีโค้ดตัวอย่างไหม

WSDL คือhttps://ws.pingdom.com/soap/PingdomAPI.wsdlและทำงานได้ดีกับไคลเอนต์ SOAP PHP 5


3
คุณจะพิจารณาเปลี่ยนคำตอบที่คุณยอมรับหรือไม่ คำตอบที่ยอมรับในปัจจุบันคือ -1 และมีอีกคำตอบที่มี +19 ฉันรู้ว่านี่มาจากปี 2008 ฉันแค่แนะนำ
Mark E. Haase

SUDS ไม่ทำงานเนื่องจากไม่สามารถแยกวิเคราะห์ WSDL ได้อย่างถูกต้อง แต่จะเป็นทางเลือกที่ดี ดังนั้นฉันจึงเปลี่ยนคำตอบเป็นบทช่วยสอนจาก Dive Into Python ซึ่งมีทางเลือกอื่น โปรดทราบว่าขณะนี้ Pingdom มี REST API pingdom.com/services/api-documentation-restพร้อมไลบรารีไคลเอ็นต์ที่blog.pingdom.com/2011/04/11/pingdom-rest-api-wrappers
davidmytton

คำตอบ:


49

ฉันอยากจะแนะนำให้คุณดูSUDS

"Suds เป็นไคลเอนต์ SOAP python ที่มีน้ำหนักเบาสำหรับการใช้บริการเว็บ"


หนุน Suds ทำให้ฉันรู้สึกได้ทันทีไม่มีการสร้างคลาสมันโหลด WSDL สดและสร้างวัตถุที่คุณสามารถใช้จากมันได้ทันที
EnigmaCurry

19
Suds มีปัญหาการเรียกซ้ำไม่สิ้นสุดเมื่อเปิด WSDL ด้วยการนำเข้าแบบเรียกซ้ำ นี่ถือเป็นข้อบกพร่องในการบล็อกของ Suds และปัญหานี้สร้างขึ้นเมื่อ 3 ปีที่แล้ว แต่ยังไม่ได้รับการแก้ไข fedorahosted.org/suds/ticket/239 ทำให้ฉันสงสัยว่า Suds เหมาะสำหรับใช้ในปี 2012 หรือไม่?
ปุ่ม 840

2
สบู่ดูเหมือนตาย SUDS ที่มีอายุการใช้งานยาวนาน- ดูเหมือนว่าจะเป็น Fork ที่ใช้งานอยู่
nerdoc

3
นี่คือคำตอบอันดับต้น ๆ แต่หากใครที่กำลังมองหาคำตอบที่ใช้ได้ผลในวันนี้ลองพิจารณาZeepตามคำตอบที่ใหม่กว่าแนะนำด้วย
Tobias Feil

25

มีห้องสมุดที่ค่อนข้างใหม่ซึ่งมีแนวโน้มมากและแม้ว่าจะยังมีการจัดทำเอกสารไม่ดี แต่ดูเหมือนว่าจะสะอาดและไพ ธ อนมาก: python zeep

ดูคำตอบนี้สำหรับตัวอย่าง


2
+1 สำหรับสิ่งนี้ วันนี้ฉันลอง Zeep แล้วและมันใช้งานง่ายอย่างน่าประหลาดใจ สามารถบริโภคและเรียกใช้บริการ Soap 1.1 / 1.2 ด้วยรหัส 3 บรรทัด
Jagu

20

ฉันเพิ่งสะดุดกับปัญหาเดียวกันนี้ นี่คือบทสรุปของวิธีแก้ปัญหาของฉัน:

จำเป็นต้องมีบล็อกรหัสองค์ประกอบพื้นฐาน

ต่อไปนี้เป็นบล็อกรหัสพื้นฐานที่จำเป็นสำหรับแอปพลิเคชันไคลเอนต์ของคุณ

  1. ส่วนคำขอเซสชัน: ขอเซสชันกับผู้ให้บริการ
  2. ส่วนการรับรองความถูกต้องเซสชัน: ให้ข้อมูลรับรองแก่ผู้ให้บริการ
  3. ส่วนไคลเอ็นต์: สร้างไคลเอนต์
  4. ส่วน Security Header: เพิ่ม WS-Security Header ให้กับ Client
  5. ส่วนการบริโภค: ใช้การดำเนินการที่มีอยู่ (หรือวิธีการ) ตามความจำเป็น

คุณต้องการโมดูลอะไร?

หลายคนแนะนำให้ใช้โมดูล Python เช่น urllib2; อย่างไรก็ตามไม่มีโมดูลใดทำงานได้อย่างน้อยสำหรับโครงการนี้

ดังนั้นนี่คือรายการโมดูลที่คุณต้องได้รับ ก่อนอื่นคุณต้องดาวน์โหลดและติดตั้ง suds เวอร์ชันล่าสุดจากลิงค์ต่อไปนี้:

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

นอกจากนี้คุณต้องดาวน์โหลดและติดตั้งคำขอและโมดูล suds_requests จากลิงก์ต่อไปนี้ตามลำดับ (ข้อจำกัดความรับผิดชอบ: ฉันเพิ่งโพสต์ใหม่ที่นี่ดังนั้นฉันจึงไม่สามารถโพสต์มากกว่าหนึ่งลิงก์ได้ในตอนนี้)

pypi.python.org/pypi/requests

pypi.python.org/pypi/suds_requests/0.1

เมื่อคุณดาวน์โหลดและติดตั้งโมดูลเหล่านี้สำเร็จคุณก็พร้อมใช้งาน

รหัส

ทำตามขั้นตอนที่ระบุไว้ก่อนหน้านี้รหัสจะมีลักษณะดังต่อไปนี้:

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

คำขอเซสชันและการรับรองความถูกต้อง:

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

สร้างลูกค้า:

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

เพิ่ม WS-Security Header:

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

โปรดทราบว่าวิธีนี้จะสร้างส่วนหัวการรักษาความปลอดภัยที่แสดงในรูปที่ 1 ดังนั้นการใช้งานของคุณอาจแตกต่างกันไปขึ้นอยู่กับรูปแบบส่วนหัวความปลอดภัยที่ถูกต้องที่เจ้าของบริการที่คุณใช้อยู่

ใช้วิธีการที่เกี่ยวข้อง (หรือการดำเนินการ):

result=client.service.methodName(Inputs)

เข้าสู่ระบบ :

หนึ่งในแนวทางปฏิบัติที่ดีที่สุดในการใช้งานเช่นนี้คือการบันทึกเพื่อดูวิธีดำเนินการสื่อสาร ในกรณีที่มีปัญหาบางอย่างจะทำให้การดีบักทำได้ง่าย รหัสต่อไปนี้ทำการบันทึกพื้นฐาน อย่างไรก็ตามคุณสามารถบันทึกการสื่อสารได้หลายแง่มุมนอกเหนือจากที่อธิบายไว้ในโค้ด

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

ผลลัพธ์:

นี่คือผลลัพธ์ในกรณีของฉัน โปรดสังเกตว่าเซิร์ฟเวอร์ส่งคืน HTTP 200 นี่คือรหัสความสำเร็จมาตรฐานสำหรับการตอบกลับคำขอ 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
อาจคุ้มค่าที่suds_requestจะบอกว่าจะล้มเหลวในขณะติดตั้งดังนั้นหากคุณใช้suds-jurkoส้อมคุณสามารถติดตั้งsuds_requestซึ่งปรับให้เข้ากับ suds รุ่นของ Jurko ได้:pip install git+https://github.com/chrcoe/suds_requests.git@feature/python3_suds_jurko
errata

7

ตอนนี้ (ณ ปี 2008) ไลบรารี SOAP ทั้งหมดที่มีให้สำหรับ Python suck ฉันแนะนำให้หลีกเลี่ยง SOAP ถ้าเป็นไปได้ ครั้งสุดท้ายที่เราบังคับให้ใช้บริการเว็บ SOAP จาก Python เราเขียน Wrapper ใน C # ที่จัดการ SOAP ที่ด้านหนึ่งและพูด COM กับอีกด้านหนึ่ง


15
ดูเหมือนจะเป็นวิธีที่ซับซ้อนอย่างไม่น่าเชื่อในการใช้โปรโตคอลง่ายๆโดยใช้ xml และ http
ddaa

1
ในช่วงปี 2008 นี่เป็นวิธีที่ดูดน้อยที่สุดสำหรับความต้องการของเรา ฉันดูเหมือนจะจำได้ว่าบริการเว็บนั้นเป็นเรื่องที่จู้จี้จุกจิกอย่างมากเกี่ยวกับบางสิ่งที่ไลบรารี python ทั้งหมดทำผิด
Matthew Scouten

1
2019 python zeep, suds, ยังคงมีปัญหาความไม่ลงรอยกันในการแยกวิเคราะห์มากมาย การดูแลรักษาเอกสาร wsdl ไม่ดีจะทำให้โมดูลเหล่านั้นมีข้อยกเว้นเช่นประทัดไม่หยุด
mootmoot


6

ฉันค้นหาคำตอบที่น่าพอใจเป็นระยะ ๆ แต่ก็ยังไม่มีโชค ฉันใช้ soapUI + คำขอ + แรงงานด้วยตนเอง

ฉันยอมแพ้และใช้ Java เป็นครั้งสุดท้ายที่ฉันต้องทำสิ่งนี้และยอมแพ้เพียงสองสามครั้งในครั้งสุดท้ายที่ฉันต้องการทำสิ่งนี้ แต่มันก็ไม่จำเป็น

หลังจากใช้ไลบรารีคำขอสำเร็จเมื่อปีที่แล้วด้วย RESTful API ของ Project Place มันเกิดขึ้นกับฉันว่าบางทีฉันอาจจะม้วนคำขอ SOAP ที่ฉันต้องการส่งด้วยมือในลักษณะเดียวกัน

ปรากฎว่าไม่ยากเกินไป แต่ก็เป็นเวลานานและมีแนวโน้มที่จะเกิดข้อผิดพลาดโดยเฉพาะอย่างยิ่งถ้าเขตข้อมูลมีชื่อไม่ลงรอยกัน (หนึ่งฉันกำลังทำงานในวันนี้มี 'jobID' jobID' และ 'jobID'. ผมใช้ soapUI โหลด WSDL เพื่อให้ง่ายต่อการแยกจุดสิ้นสุด ฯลฯ และทำการทดสอบด้วยตนเองจนถึงตอนนี้ฉันโชคดีที่ไม่ได้รับผลกระทบจากการเปลี่ยนแปลง WSDL ใด ๆ ที่ฉันใช้


3

SOAPpy ไม่จริงใช้ไม่ได้กับ Python 2.5 - มันใช้งานได้แม้ว่ามันจะง่ายมากและเป็นพื้นฐานจริงๆ หากคุณต้องการคุยกับบริการเว็บที่ซับซ้อนมากขึ้น ZSI คือเพื่อนคนเดียวของคุณ

การสาธิตที่มีประโยชน์มากที่ฉันพบอยู่ที่http://www.ebi.ac.uk/Tools/webservices/tutorials/pythonซึ่งช่วยให้ฉันเข้าใจวิธีการทำงานของ ZSI ได้มาก


1
การติดตั้ง python setup.py ให้ข้อผิดพลาดกับรุ่นล่าสุด สำเนา dev ล่าสุดอาจใช้งานได้ แต่เป็นความเจ็บปวดที่ต้องทำ
davidmytton

1

หากคุณกำลังกลิ้งของคุณเองผมขออยากแนะนำให้มองหาที่http://effbot.org/zone/element-soap.htm


1

SOAPpy ล้าสมัย AFAIK ถูกแทนที่ด้วย ZSL มันเป็นจุดที่สงสัยเพราะฉันไม่สามารถใช้งานได้เลยคอมไพล์น้อยกว่ามากทั้งบน Python 2.5 หรือ 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 แสดงไว้ที่นี่: code.google.com/archive/p/pysimplesoap
ลงสตรีม

ตัวอย่างผลลัพธ์: ... DEBUG: pysimplesoap.helpers: complexContent / simpleType / element string = string [u'StockQuote '] GetQuote: <StockQuotes><Stock><Symbol>GOOG</Symbol> <Last> 816.13 </Last> <วันที่> 2017/03/23 </ วัน> <เวลา> 11:41 </ เวลา> <เปลี่ยน> -13.46 </ เปลี่ยน> <เปิด> 820.01 </ เปิด> <สูง> 822.57 </ สูง> <ต่ำ> 812.26 </Low> <Volume> 1973140 </Volume> <MktCap> 564.29B </MktCap> <PreviousClose> 829.59 </PreviousClose> <PercentageChange> -1.62% </PercentageChange> <AnnRange> 663.28 - 853.50 </AnnRange> <Earns>27.88</Earns><PE>29.28</PE> <Name> Alphabet Inc. </Name> </Stock> </StockQuotes>
ลงสตรีม

ล้มเหลวบน Python3 ใน pysimplesoap / client.py: 757 - วัตถุ 'dict' ไม่มีแอตทริบิวต์ 'iteritems'
ierdna

เห็นได้ชัดว่าเวอร์ชันที่มาพร้อมกับ PIP เสีย ต้องติดตั้งด้วยตนเองจาก GIT - มันแก้ไขสิ่งต่างๆ
ierdna

จุดดี: ดูลิงค์นี้: stackoverflow.com/questions/13998492/iteritems-in-python "dict.iteritems ถูกลบออกเพราะตอนนี้ dict.items ทำสิ่งที่ dict.iteritems ทำใน python 2 ... "
ลงสตรีม
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.