Как я могу использовать веб-сервис WSDL (SOAP) в Python?
Я хочу использовать веб-сервис на основе WSDL SOAP в Python. Я посмотрел код Dive Into Python, но модуль SOAPpy не работает в Python 2.5.
Я попытался использовать suds, который работает частично, но не работает с определенными типами (suds.TypeNotFound: Тип не найден: 'item').
Я также посмотрел на клиента, но это не поддерживает WSDL.
И я посмотрел на ZSI, но это выглядит очень сложно. У кого-нибудь есть пример кода для него?
WSDL - https://ws.pingdom.com/soap/PingdomAPI.wsdl и отлично работает с клиентом PHP 5 SOAP.
11 ответов
Я знаю, что это старый поток, но он показывал в верхней части результатов Google, поэтому я хотел бы поделиться более актуальным обсуждением Python и SOAP.
Смотрите: http://www.diveintopython.net/soap_web_services/index.html
Я бы порекомендовал вам взглянуть на SUDS
"Suds - это легкий Python-клиент SOAP для использования веб-сервисов".
Существует относительно новая библиотека, которая является очень многообещающей и хотя все еще плохо документированной, кажется очень чистой и питонской: python zeep.
Смотрите также этот ответ для примера.
Я недавно наткнулся на ту же проблему. Вот краткий обзор моего решения:
Необходимы базовые блоки кода
Ниже приведены обязательные базовые блоки кода вашего клиентского приложения.
- Раздел запроса сеанса: запрос сеанса у провайдера
- Раздел аутентификации сеанса: предоставьте учетные данные провайдеру
- Клиентский раздел: создать клиента
- Раздел заголовка безопасности: добавьте заголовок WS-Security на клиент
- Раздел потребления: потреблять доступные операции (или методы) по мере необходимости
Какие модули вам нужны?
Многие предлагали использовать модули Python, такие как urllib2; однако ни один из модулей не работает - по крайней мере, для этого конкретного проекта.
Итак, вот список модулей, которые вам нужно получить. Прежде всего, вам необходимо скачать и установить последнюю версию suds по следующей ссылке:
pypi.python.org/pypi/suds-jurko/0.4.1.jurko.2
Кроме того, вам необходимо загрузить и установить модули request и suds_requests по следующим ссылкам соответственно (отказ от ответственности: я новичок в публикации здесь, поэтому я не могу опубликовать более одной ссылки на данный момент).
pypi.python.org/pypi/requests
pypi.python.org/pypi/suds_requests/0.1
После того, как вы успешно загрузите и установите эти модули, вы готовы к работе.
Код
В соответствии с шагами, описанными ранее, код выглядит следующим образом: Imports:
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:
...
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
},
})
Zeep - достойная SOAP-библиотека для Python, которая соответствует тому, что вы просите: http://docs.python-zeep.org/
Прямо сейчас (по состоянию на 2008) все библиотеки SOAP, доступные для Python, отстой. Я рекомендую избегать SOAP, если это возможно. В прошлый раз, когда мы были вынуждены использовать веб-сервис SOAP из Python, мы написали оболочку на C#, которая обрабатывает SOAP с одной стороны и говорит COM с другой.
Я периодически ищу удовлетворительный ответ на этот вопрос, но пока не повезло. Я использую soapUI + запросы + ручной труд.
Я отказался и использовал Java в последний раз, когда мне нужно было это сделать, и просто несколько раз отказывался от последнего раза, когда я хотел это сделать, но это было не существенно.
После успешного использования библиотеки запросов в прошлом году с RESTful API в Project Place мне пришло в голову, что, возможно, я мог бы просто свернуть запросы SOAP, которые я хочу отправить, аналогичным образом.
Оказывается, это не так уж сложно, но это отнимает много времени и подвержено ошибкам, особенно если поля имеют непоследовательные имена (у того, над которым я сейчас работаю сегодня, есть 'jobId', JobId'и'JobID'. Я использую soapUI для загрузки WSDL, чтобы упростить извлечение конечных точек и т. д. и выполнить некоторое ручное тестирование. До сих пор мне повезло, что на меня не повлияли изменения в любом WSDL, который я использую.
Это неправда. SOAPpy не работает с Python 2.5 - он работает, хотя он очень простой и действительно очень простой. Если вы хотите поговорить с более сложным веб-сервисом, ZSI - ваш единственный друг.
По-настоящему полезная демонстрация, которую я нашел, находится по адресу http://www.ebi.ac.uk/Tools/webservices/tutorials/python - это действительно помогло мне понять, как работает ZSI.
Если вы катаетесь самостоятельно, я настоятельно рекомендую посмотреть на http://effbot.org/zone/element-soap.htm.
#!/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']))
SOAPpy теперь устарел, AFAIK, заменен на ZSL. Это спорный вопрос, потому что я не могу заставить ни одного работать, и тем более компилировать, на Python 2.5 или Python 2.6