- PVSM.RU - https://www.pvsm.ru -
В данной статье я хочу рассказать о замечательной Python-библиотеке Spyne.
Мое знакомство с Spyne началось в тот момент, когда передо мной поставили задачу написать Веб-сервис, который будет принимать и отдавать запросы через SOAP-протокол. Немного погуглив я наткнулся на Spyne [1], которая является форком библиотеки soaplib [2]. А еще я был удивлен, насколько мало русскоязычной информации встречается о данной библиотеке.
С помощью Spyne можно писать веб-сервисы, которые умеют работать с SOAP, JSON, YAML, а написанный скрипт можно запустить через mod_wsgi Apache. Итак, давайте рассмотрим несколько примеров, напишем работающие скрипты и настроим так, чтобы скрипты работали через apache.
Давайте напишем веб-сервис, который будет служить нам переводчиком на английский язык. Наш веб-сервис будет получать запросы, обращаться в Yandex-translator, получать перевод и данный перевод отдавать клиенту. Принимаются входящие запросы в XML-формате. Ответ также будет уходить в XML-формате.
Первым делом необходимо получить API-ключ, чтобы сказать Яндексу, что мы свои. Как можно это сделать, смотрим тут [3].
Теперь переходим непосредственно к разработке.
Устанавливаем необходимые библиотеки: «pytz», «spyne», а также «yandex_translate». Библиотеки ставятся очень легко через pip.
Код приложения выглядит следующим образом:
from spyne import Application, rpc, ServiceBase, Unicode
from lxml import etree
from spyne.protocol.soap import Soap11
from spyne.protocol.json import JsonDocument
from spyne.server.wsgi import WsgiApplication
from yandex_translate import YandexTranslate
class Soap(ServiceBase):
@rpc(Unicode, _returns=Unicode)
def Insoap(ctx, words):
print(etree.tostring(ctx.in_document))
translate = YandexTranslate('trnsl.1.1.201somesymbols')
tr = translate.translate(words, 'en')
tr_answer = tr['text'][0]
return tr_answer
app = Application([Soap], tns='Translator',
in_protocol=Soap11(validator='lxml'),
out_protocol=Soap11()
application = WsgiApplication(app)
if __name__ == '__main__':
from wsgiref.simple_server import make_server
server = make_server('0.0.0.0', 8000, application)
server.serve_forever()
Разберем код:
После импортирования необходимых библиотек, мы создали класс «Soap» с аргументом «ServiceBase». Декоратор "@rpc(Unicode, _returns=Unicode)" определяет тип входящих аргументов («Unicode») и исходящих ответов ("_returns=Unicode"). Список доступных типов аргументов можно посмотреть в официальной документации. [4]. Далее создается метод «Insoap» с аргументами «ctx» и «words». Аргумент «ctx» очень важен, так как в нем содержится много информации о входящих запросах. Строка «print(etree.tostring(ctx.in_document))» выводит на экран входящий xml-запрос, в таком виде, в каком нам его отправил пользователь. В некоторых моментах это может быть важно. Например, мне в ходе написания веб-сервиса нужно было вытащить входящий xml-запрос и записать в базу данных. Но как вытащить этот xml-запрос не упомянуто в официальной документации Spyne. Burak Arslan (автор Spyne) порекомендовал смотреть в сторону библиотеки lxml. Только после этого я нашел ответ и результат видите в данноме скрипте. Далее наш метод обращается в Яндекс-переводчик и возвращает клиенту полученный от Яндекс-переводчика результат.
Переменная «app» определяет настройки нашего веб-сервиса: «Application([Soap]» — указывается, какой класс инициализируется (их может быть несколько), параметры «in_protocol» и «out_protocol» определяет тип входящих и исходящих запросов, в нашем случае это SOAP v1.1.
Строкой «application = WsgiApplication(app)» определяется, чтобы наш скрипт мог работать через wsgi.
Важно! имя переменного обязательно должен быть «application», чтобы наше приложение мог работать через apache с помощью mod_wsgi.
Последующие строки кода инициализирует и запускает Веб-сервер по порту 8000.
Запускаем скрипт и можно приступать к тестированию. Для этих целей я использую SoapUI [5]. Удобство состоит в том, что после запуска и настройки для работы с SOAP сервером, SoapUI автоматически формирует xml-запрос. Наш xml-запрос выглядит следующим образом:
Наш веб-сервис дал следующий ответ:
Все просто, не правда ли?
Предположим, что теперь у нас поменялось тех. задание, и нужно сделать веб-сервис, который работает через JSON. Что делать? Переписывать наш сервис на другом фреймворке, например Django Rest Framework [7] или Flask [8]? или можно обойтись меньшими усилиями? Да, можно! И нужно!
Библиотека Spyne нам в помошь.
Все что потребуется поменять в нашем приложении, это переменную «app» привести к следующему виду:
app = Application([Soap], tns='Translator',
in_protocol=JsonDocument(validator='soft'),
out_protocol=JsonDocument())
Запускаем наш веб-сервис и тестируемся.
Наш JSON-запрос выглядит так:
Веб сервер вернул следующий ответ:
Для запуска нашего веб-сервиса через apache, необходимо на сервер установить и настроить веб-сервер apache [9] и mod_wsgi [10]. Данные работы несложно выполнить, опираясь на документацию. Кроме этого, в нашем скрипте мы должны удалить следующие строки:
Ура! Наш веб-сервис готов к использованию в эксплуатации.
P.S. о дополнительных возможностях Spyne (а их немало) всегда можно ознакомиться на официальном сайте [1], чего я вам очень рекомендую.
Автор: maxpy
Источник [11]
Сайт-источник PVSM.RU: https://www.pvsm.ru
Путь до страницы источника: https://www.pvsm.ru/python/261277
Ссылки в тексте:
[1] Spyne: http://spyne.io/
[2] soaplib: https://github.com/soaplib/soaplib
[3] тут: https://tech.yandex.ru/translate/
[4] официальной документации.: http://spyne.io/docs/index.html
[5] SoapUI: https://www.soapui.org/
[6] schemas.xmlsoap.org/soap/envelope: http://schemas.xmlsoap.org/soap/envelope/
[7] Django Rest Framework: http://www.django-rest-framework.org/
[8] Flask: http://flask.pocoo.org/
[9] apache: https://www.apache.org/
[10] mod_wsgi: https://modwsgi.readthedocs.io/en/develop/index.html
[11] Источник: https://habrahabr.ru/post/334290/?utm_source=habrahabr&utm_medium=rss&utm_campaign=sandbox
Нажмите здесь для печати.