Bagaimana saya dapat menggunakan layanan web WSDL (SOAP) dengan Python?

124

Saya ingin menggunakan layanan web berbasis SOAP WSDL dengan Python. Saya telah melihat kode Dive Into Python tetapi modul SOAPpy tidak berfungsi dengan Python 2.5.

Saya telah mencoba menggunakan busa yang berfungsi sebagian, tetapi rusak dengan jenis tertentu (suds.TypeNotFound: Type not found: 'item').

Saya juga telah melihat Klien tetapi tampaknya ini tidak mendukung WSDL.

Dan saya telah melihat ZSI tetapi terlihat sangat kompleks. Apakah ada yang punya kode sampel untuk itu?

WSDL adalah https://ws.pingdom.com/soap/PingdomAPI.wsdl dan berfungsi dengan baik dengan klien SOAP PHP 5.

davidmytton
sumber
3
Apakah Anda mempertimbangkan untuk mengubah jawaban yang Anda terima? Jawaban yang diterima saat ini adalah -1, dan ada jawaban lain dengan +19. Saya tahu ini dari 2008; Saya hanya menyarankan.
Mark E. Haase
SUDS tidak berfungsi karena tidak dapat mengurai WSDL dengan benar tetapi akan menjadi pilihan yang baik jika tidak. Jadi saya mengubah jawaban tutorial dari Dive Into Python yang memiliki beberapa alternatif. Sebagai catatan tambahan, Pingdom sekarang memiliki REST API pingdom.com/services/api-documentation-rest dengan perpustakaan klien di blog.pingdom.com/2011/04/11/pingdom-rest-api-wrappers
davidmytton

Jawaban:

49

Saya akan merekomendasikan agar Anda melihat SUDS

"Suds adalah klien python SOAP yang ringan untuk menggunakan Layanan Web."

Yusufk
sumber
Didukung. Suds langsung masuk akal bagi saya, tidak ada generasi kelas, itu memuat WSDL secara langsung dan membuat objek yang dapat Anda gunakan langsung darinya.
EnigmaCurry
19
Suds memiliki masalah rekursi tak terbatas saat membuka WSDL dengan impor rekursif. Ini dianggap sebagai bug pemblokiran oleh Suds, dan masalah ini dibuat lebih dari 3 tahun yang lalu, tetapi belum diperbaiki. fedorahosted.org/suds/ticket/239 Membuat saya bertanya-tanya apakah Suds cocok digunakan di tahun 2012?
Buttons840
2
busa sepertinya sudah mati. Panjang umur SUDS - ini tampaknya menjadi Fork aktif.
nerdoc
3
Ini adalah jawaban teratas, tetapi jika ada yang mencari jawaban yang berhasil hari ini, pertimbangkan Zeep , seperti yang disarankan oleh jawaban yang lebih baru juga.
Tobias Feil
25

Ada perpustakaan yang relatif baru yang sangat menjanjikan dan meskipun masih kurang terdokumentasi, tampaknya sangat bersih dan pythonic: python zeep .

Lihat juga jawaban ini sebagai contoh.

lorenzog.dll
sumber
2
1 untuk ini. Saya mencoba zeep hari ini dan ternyata sangat mudah digunakan. Mampu mengkonsumsi dan memanggil layanan Soap 1.1 / 1.2 dengan 3 baris kode.
Jagu
20

Saya baru-baru ini tersandung pada masalah yang sama. Inilah sinopsis solusi saya:

Diperlukan blok kode konstituen dasar

Berikut ini adalah blok kode dasar yang diperlukan dari aplikasi klien Anda

  1. Bagian permintaan sesi: meminta sesi dengan penyedia
  2. Bagian otentikasi sesi: berikan kredensial ke penyedia
  3. Bagian Klien: buat Klien
  4. Bagian Header Keamanan: tambahkan Header WS-Security ke Klien
  5. Bagian konsumsi: konsumsi operasi (atau metode) yang tersedia sesuai kebutuhan

Modul apa yang Anda butuhkan?

Banyak yang menyarankan untuk menggunakan modul Python seperti urllib2; Namun, tidak ada modul yang berfungsi-setidaknya untuk proyek khusus ini.

Jadi, berikut adalah daftar modul yang perlu Anda dapatkan. Pertama-tama, Anda perlu mengunduh dan menginstal suds versi terbaru dari tautan berikut:

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

Selain itu, Anda perlu mengunduh dan menginstal permintaan dan modul suds_requests dari tautan berikut masing-masing (pelepasan tanggung jawab: Saya baru memposting di sini, jadi saya tidak dapat memposting lebih dari satu tautan untuk saat ini).

pypi.python.org/pypi/requests

pypi.python.org/pypi/suds_requests/0.1

Setelah Anda berhasil mengunduh dan menginstal modul ini, Anda siap untuk melanjutkan.

Kode

Mengikuti langkah-langkah yang diuraikan sebelumnya, kode tersebut terlihat seperti berikut ini: Impor:

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

Permintaan sesi dan otentikasi:

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

Buat Klien:

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

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

Harap dicatat bahwa metode ini membuat tajuk keamanan yang digambarkan pada Gambar 1. Jadi, penerapan Anda mungkin berbeda-beda bergantung pada format header keamanan yang benar yang disediakan oleh pemilik layanan yang Anda gunakan.

Gunakan metode (atau operasi) yang relevan:

result=client.service.methodName(Inputs)

Logging :

Salah satu praktik terbaik dalam implementasi seperti ini adalah pencatatan untuk melihat bagaimana komunikasi dijalankan. Jika ada masalah, ini membuat debugging menjadi mudah. Kode berikut melakukan logging dasar. Namun, Anda dapat mencatat banyak aspek komunikasi selain yang digambarkan dalam kode.

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

Hasil:

Inilah hasil dalam kasus saya. Perhatikan bahwa server mengembalikan HTTP 200. Ini adalah kode sukses standar untuk respons permintaan 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
      },
 })
Teddy Belay
sumber
1
Mungkin layak dikatakan bahwa itu suds_requestakan gagal saat menginstal, jadi jika Anda menggunakan suds-jurkofork, Anda dapat menginstal suds_requestyang telah disesuaikan untuk bekerja dengan suds versi jurko:pip install git+https://github.com/chrcoe/suds_requests.git@feature/python3_suds_jurko
errata
7

Saat ini (pada 2008), semua perpustakaan SOAP tersedia untuk Python menyedot. Saya sarankan menghindari SOAP jika memungkinkan. Terakhir kali kami dipaksa untuk menggunakan layanan web SOAP dari Python, kami menulis pembungkus dalam C # yang menangani SOAP di satu sisi dan mengeluarkan COM di sisi lain.

Matthew Scouten
sumber
15
Kedengarannya seperti cara yang sangat rumit untuk menggunakan protokol sederhana berdasarkan xml dan http.
ddaa
1
Saat itu, 2008, ini adalah metode yang paling sedikit menyedot kebutuhan kita. Sepertinya saya ingat bahwa layanan web tertentu itu sangat pilih-pilih tentang sesuatu yang membuat semua pustaka python salah.
Matthew Scouten
1
2019, python zeep, busa, masih rentan terhadap banyak masalah ketidakcocokan parsing. Pemeliharaan dokumen wsdl yang buruk akan membuat modul-modul tersebut mengeluarkan pengecualian seperti petasan non-stop.
mootmoot
6

Saya secara berkala mencari jawaban yang memuaskan untuk ini, tetapi sejauh ini tidak berhasil. Saya menggunakan permintaan soapUI + + tenaga kerja manual.

Saya menyerah dan menggunakan Java terakhir kali saya perlu melakukan ini, dan menyerah beberapa kali terakhir kali saya ingin melakukan ini, tetapi itu tidak penting.

Setelah berhasil menggunakan pustaka permintaan tahun lalu dengan API RESTful Project Place, terpikir oleh saya bahwa mungkin saya bisa langsung menggulung permintaan SOAP yang ingin saya kirim dengan cara yang sama.

Ternyata bahwa tidak terlalu sulit, tetapi adalah memakan waktu dan rawan kesalahan, terutama jika bidang yang tidak konsisten bernama (yang saya sedang mengerjakan saat ini memiliki 'jobId', JobId' dan 'JobID'. Saya menggunakan soapUI ke beban WSDL untuk mempermudah mengekstrak titik akhir dll dan melakukan beberapa pengujian manual Sejauh ini saya beruntung tidak terpengaruh oleh perubahan pada WSDL yang saya gunakan.

Hywel Thomas
sumber
3

Ini tidak benar SOAPpy tidak bekerja dengan Python 2.5 - ini bekerja, meskipun sangat sederhana dan sangat, sangat mendasar. Jika Anda ingin berbicara dengan layanan web yang lebih rumit, ZSI adalah satu-satunya teman Anda.

Demo yang sangat berguna yang saya temukan ada di http://www.ebi.ac.uk/Tools/webservices/tutorials/python - ini sangat membantu saya untuk memahami cara kerja ZSI.

zgoda.dll
sumber
1
python setup.py install memberikan kesalahan dengan rilis terbaru. Salinan dev terbaru mungkin berfungsi tetapi itu sulit dilakukan.
davidmytton
1

SOAPpy sekarang sudah usang, AFAIK, digantikan oleh ZSL. Ini adalah poin yang bisa diperdebatkan, karena saya tidak bisa mendapatkan salah satunya untuk bekerja, apalagi mengkompilasi, pada Python 2.5 atau Python 2.6

Manusia Timah
sumber
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']))
Down the Stream
sumber
lib tercantum di sini: code.google.com/archive/p/pysimplesoap
Down the Stream
contoh keluaran: ... DEBUG: pysimplesoap.helpers: complexContent / simpleType / element string = string [u'StockQuote '] GetQuote: <StockQuotes><Stock><Symbol>GOOG</Symbol> <Last> 816.13 </Last> <Tanggal>3/23/2017</Tanggal><Waktu>11:41 pagi</Waktu><Ubah>-13.46</Ubah><Buka>820.01</Open><High>822.57</High> <Low> 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>
Down the Stream
gagal pada Python3 di pysimplesoap / client.py: 757 - objek 'dict' tidak memiliki atribut 'iteritems'
ierdna
tampaknya versi yang disertakan dengan PIP rusak. harus menginstalnya secara manual dari GIT - ini memperbaiki banyak hal
ierdna
Poin yang bagus: lihat tautan ini: stackoverflow.com/questions/13998492/iteritems-in-python "dict.iteritems telah dihapus karena dict.items sekarang melakukan hal yang dilakukan dict.iteritems di python 2 ..."
Down the Stream