Як я можу споживати веб-службу WSDL (SOAP) на Python?


124

Я хочу використовувати веб-сервіс на базі WSDL SOAP в Python. Я переглянув код Dive Into Python, але модуль SOAPpy не працює під Python 2.5.

Я спробував використовувати suds, який працює частково, але розривається з певними типами (suds.TypeNotFound: Type not found: 'item').

Я також подивився на Клієнта, але це, здається, не підтримує WSDL.

І я подивився на ZSI, але це виглядає дуже складно. Хтось має для цього зразок коду?

WSDL є https://ws.pingdom.com/soap/PingdomAPI.wsdl і прекрасно працює з клієнтом PHP 5 SOAP.


3
Чи могли б ви змінити прийняту відповідь? На даний момент прийнята відповідь - -1, а ще одна відповідь - +19. Я знаю, що це з 2008 року; Я просто пропоную.
Марк Е. Хааз

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 для користування веб-сервісами."


Відряджений. Суди для мене негайно мали сенс, не покоління класу, воно завантажує живий WSDL і створює об'єкт, який ви можете негайно використовувати з нього.
EnigmaCurry

19
Суди мають нескінченну проблему з рекурсією при відкритті WSDL з рекурсивним імпортом. Суд вважає, що помилка блокує проблему, і ця проблема була створена понад 3 роки тому, але вона ще не була виправлена. fedorahosted.org/suds/ticket/239 Мене змушує задуматися, чи Suds підходить для використання у 2012 році?
Кнопки840

2
шари здаються мертвими. Довго живі SUDS - це, здається, активний Fork.
nerdoc

3
Це найкраща відповідь, але якщо хтось шукає відповідь, яка працює сьогодні, розгляне Zeep , як підказують нові відповіді.
Тобіас

25

Існує відносно нова бібліотека, яка дуже перспективна і хоча ще недостатньо задокументована, здається дуже чистою та пітонічною: python zeep .

Дивіться також цю відповідь для прикладу.


2
+1 для цього. Я спробував зеп сьогодні, і це було дивно просто у використанні. Вміла споживати та викликати послугу Soap 1.1 / 1.2 з 3 рядками коду.
Ягу

20

Нещодавно я натрапив на ту ж проблему. Ось конспект мого рішення:

Необхідні основні складові кодові блоки

Нижче наведено необхідні базові кодові блоки вашої клієнтської програми

  1. Розділ запиту на сеанс: запит на сеанс з провайдером
  2. Розділ аутентифікації сесії: надайте облікові дані провайдеру
  3. Розділ Клієнт: створіть Клієнта
  4. Розділ Заголовок безпеки: додайте Заголовок безпеки WS до Клієнта
  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-безпеки:

...
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-jurkofork, ви можете встановити, suds_requestякий був адаптований для роботи з версією jurko suds:pip install git+https://github.com/chrcoe/suds_requests.git@feature/python3_suds_jurko
errata

7

Зараз (станом на 2008 рік) всі бібліотеки SOAP, доступні для Python, висмоктуються. Я рекомендую уникати SOAP, якщо це можливо. Минулого разу, коли ми змушені користуватися веб-сервісом SOAP від ​​Python, ми написали обгортку на C #, яка обробляла SOAP з одного боку та говорила COM з іншого.


15
Це звучить як шалено складний спосіб використання простого протоколу, заснованого на xml та http.
ddaa

1
У той час, 2008 рік, це був метод, який найменше відповідав нашим потребам. Я, мабуть, пам’ятаю, що саме ця веб-служба була надзвичайно прискіпливою до чогось, що всі бібліотеки пітона помиляються.
Метью Скаутен

1
2019, python zeep, suds, як і раніше, схильний до багатьох проблем, що розбирають проблеми несумісності. Погана підтримка документів wsdl змусить цих модулів виключати вигляд, наприклад, безперервний петард.
mootmoot


6

Я періодично шукаю задовільну відповідь на це, але поки що не пощастило. Я використовую запити soapUI + + ручна праця.

Я відмовився від використання Java в останній раз, коли мені потрібно було це зробити, і просто відмовився кілька разів останній раз, коли я хотів це зробити, але це не було суттєво.

Після успішного використання бібліотеки запитів минулого року з API RESTful Project Project, мені спало на думку, що, можливо, я міг би просто вручну прокрутити запити 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 install встановлює помилки з останньою версією. Остання копія розробника може спрацювати, але це біль.
Девідміттон


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']))


вибір виводу: ... DEBUG: pysimplesoap.helpers: complexContent / simpleType / element string = string [u'StockQuote '] GetQuote: <StockQuotes><Stock><Symbol>GOOG</Symbol> <Останній> 816.13 </Last> <Date>3/23/2017</Date><Time>11:41am</Time><Change>-13.46</Change><Open>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.50An <Earns>27.88</Earns><PE>29.28</PE> <Ім'я> 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 ...»
вниз за течією
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.