Installation and QuickStart guide¶
Установка¶
Чтобы установить приложение достаточно выполнить в окружении:
pip install wsfactory -i http://pypi.bars-open.ru/simple
Вместе с приложением будут установлены следующие зависимости:
- lxml
- spyne
Добавление приложения в проект¶
Как и все обычные django приложения, нужно просто добавить wsfactory в список установленных приложений и расширить urlpatterns:
# где-то в settings.py
INSTALLED_APPS += "wsfactory",
# где-то в urls.py
import wsfactory.urls
urlpatterns += wsfactory.urls.urlpatterns
Теперь необходимо с конфигурировать wsfactory. Сначала скопируем болванку для конфига, выполним менедж-комманду:
cd path/to/directory/you/place/config/
django_admin.py wsfactory_default_config
После чего в директории, в которой выполнялась команда появится файл wsfactory_config.xml
примерно следующего содержания:
<WSConfig xmlns="http://bars-open.ru/schema/wsfactory"
ApplicationClass="spyne.application.Application"
WsgiClass="spyne.server.django.DjangoApplication"
ServiceClass="spyne.service.ServiceBase"
ApiHandler="wsfactory.views.api_handler">
<Protocols>
<!-- Протоколы -->
<Protocol code="soap11" direction="BOTH" module="spyne.protocol.soap.soap11.Soap11" name="SOAP 1.1"/>
<Protocol code="json" direction="BOTH" module="spyne.protocol.json.JsonDocument" name="JSON Protocol"/>
<Protocol code="http-rpc" direction="IN" module="spyne.protocol.http.HttpRpc" name="HTTP RPC"/>
<!-- установите модуль spyne-smev и раскомментируйте следующие строки, чтобы добавить поддежку протоколв СМЭВ -->
<Protocol code="soap11wsse" direction="BOTH" module="spyne_smev.wsse.Soap11WSSE" name="SOAP 1.1 WSSE"/>
<Protocol code="smev256" direction="BOTH" module="spyne_smev.smev256.Smev256" name="СМЭВ 2.5.6"/>
</Protocols>
<ApiRegistry>
<!-- API-методы -->
<Api code="Code" module="some.module.ApiFunction" name="Do some action"/>
</ApiRegistry>
<Services>
<!-- Сервисы, они же услуги - наборы методов-API -->
<Service code="Service" name="Sample service">
<Api code="Code"/>
</Service>
</Services>
<SecurityProfile>
<!-- Профили безопасности WS-Security. Требует установки модуля spyne-smev -->
<Modules>
<!-- Описание модулей -->
<Module code="x509token" path="spyne_smev.wsse.protocols.X509TokenProfile" name="X509 Token Profile"/>
</Modules>
<Security module="x509token" code="security" name="Default security profile">
<!-- Декларация объектов профилей безопасности -->
<Param key="certificate" valueType="string">path_to_certificate_file</Param>
<Param key="private_key" valueType="string">path_to_pkey_file</Param>
<Param key="private_key_pass" valueType="string">pkey_password</Param>
</Security>
</SecurityProfile>
<Applications>
<!-- Реестр веб-сервисов (Соответствия протоколов-сервисов) -->
<Application name="SampleApp" service="Service">
<InProtocol code="soap11"/>
<OutProtocol code="soap11"/>
</Application>
</Applications>
</WSConfig>
Пишем код¶
Подробно файл конфигурации, разберем позже, а пока создадим в нашем проекте один простой сервис:
# гдето в проекте файл project/service.py
from itertools import repeat
from spyne import srpc, Integer, Unicode, Iterable
@srpc(Unicode, Integer, _returns=Iterable(Unicode))
def SayHello(name, times):
return repeat(u"Hello, {0}!".format(name), times)
Декларируем веб-сервис¶
После чего отредактируем файл wsfactory_config.xml
. Сперва добавим api-метод
в соответствующую секцию - в теге ApiRegistry:
<ApiRegistry>
<Api code="SayHello" module="project.service.SayHello" name="Приветствие"/>
</ApiRegistry>
Где атрибут code
- это уникальный идентификатор метода, module
- путь, по
которому можно импортировать этот метод, name
- человечное название метода.
Все атрибуты являются обязательными.
Tip
Для редактирования xml лучше использовать IDE или редактор с поддержкой xsd-схем,
т.к. в данном случае, будет автокомплит и проверка типов. xsd-схема
конфигурации лежит в пакете wsfactory
, и если файл конфигурации был создан
менедж-коммандой, то она будет подключена к файлу конфигурации через xsi:schemaLocation.
Дальше задекларируем сервис - то есть набор api-методов:
<Services>
<Service code="SayHelloService" name="Say Hello Service">
<Api code="SayHello"/>
</Service>
</Services
Здесь атрибут code
также является идентификатором, а name
человечным названием.
В элементе Service
обязательно должен содержаться хотя бы один элемент Api
, у которого в
атрибуте code
указывается ссылка на api-метод из элемента ApiRegistry
.
Теперь осталось задекларировать сам веб-сервис:
<Applications>
<Application name="SayHelloService" service="SayHelloService" tns="http://company.domain/tns">
<InProtocol code="http-rpc"/>
<OutProtocol code="json"/>
</Application>
</Applications>
Здесь атрибут name
является идентификатором веб-сервиса, атрибут service
ссылкой на сервис описанный в елементе Services
, a tns
- это неймспейс,
который будет использоваться для wsdl-документа.
В элементах InProtocol
и OutProtocol
в атрибутах code
указывается
ссылка на протоколы, описанные в элементе Protocols
. В нашем примере мы
выбрали spyne-протоколы HttpRpc на входе и JsonDocument на выходе.
Note
Тут же можно указать параметры инициализации протоколов, а так же профиль безопасности ws-security, но об этом будет сказано дальше.
В итоге должен получиться такой xml-документ:
<WSConfig xmlns="http://bars-open.ru/schema/wsfactory"
ApplicationClass="spyne.application.Application"
WsgiClass="spyne.server.django.DjangoApplication"
ServiceClass="spyne.service.ServiceBase"
ApiHandler="wsfactory.views.api_handler">
<Protocols>
<!-- Протоколы -->
<Protocol code="soap11" direction="BOTH" module="spyne.protocol.soap.soap11.Soap11" name="SOAP 1.1"/>
<Protocol code="json" direction="BOTH" module="spyne.protocol.json.JsonDocument" name="JSON Protocol"/>
<Protocol code="http-rpc" direction="IN" module="spyne.protocol.http.HttpRpc" name="HTTP RPC"/>
<!-- установите модуль spyne-smev и раскомментируйте следующие строки, чтобы добавить поддежку протоколв СМЭВ -->
<Protocol code="soap11wsse" direction="BOTH" module="spyne_smev.wsse.Soap11WSSE" name="SOAP 1.1 WSSE"/>
<Protocol code="smev256" direction="BOTH" module="spyne_smev.smev256.Smev256" name="СМЭВ 2.5.6"/>
</Protocols>
<ApiRegistry>
<!-- API-методы -->
<Api code="SayHello" module="project.service.SayHello" name="Приветствие"/>
</ApiRegistry>
<Services>
<!-- Сервисы, они же услуги - наборы методов-API -->
<Service code="SayHelloService" name="Say Hello Service">
<Api code="SayHello"/>
</Service>
</Services>
<SecurityProfile>
<!-- Профили безопасности WS-Security. Требует установки модуля spyne-smev -->
<Modules>
<!-- Описание модулей -->
<Module code="x509token" path="spyne_smev.wsse.protocols.X509TokenProfile" name="X509 Token Profile"/>
</Modules>
<Security module="x509token" code="security" name="Default security profile">
<!-- Декларация объектов профилей безопасности -->
<Param key="certificate" valueType="string">path_to_certificate_file</Param>
<Param key="private_key" valueType="string">path_to_pkey_file</Param>
<Param key="private_key_pass" valueType="string">pkey_password</Param>
</Security>
</SecurityProfile>
<Applications>
<!-- Реестр веб-сервисов (Соответствия протоколов-сервисов) -->
<Application name="SayHelloService" service="SayHelloService">
<InProtocol code="http-rpc"/>
<OutProtocol code="json"/>
</Application>
</WSConfig>
Подключение файла конфигурации¶
Теперь осталось подключить файл конфигурации, для этого гдето в settings.py добавим:
WSFACTORY_CONFIG_FILE = "/path/to/config/file/wsfactory_config.xml"
Проверяем¶
Запустим dev-сервер и наш сервис станет доступен по урлу:
http://localhost:8000/wsfactory/api/SayHelloService
Выполним запрос:
curl "http://localhost:8000/wsfactory/api/SayHelloService/SayHello?name=Tim×=4 | python -m json.tool
В результате получим:
[
"Hello, Tim!",
"Hello, Tim!",
"Hello, Tim!",
"Hello, Tim!"
]
Допустим нам понадобилось чтобы, этот же сервис отдавал данные по спецификации Soap 1.1.
Все что нам нужно - это просто добавить новый Application
в конфигурацию:
<Applications>
<!-- Реестр веб-сервисов (Соответствия протоколов-сервисов) -->
<Application name="SayHelloService" service="SayHelloService">
<InProtocol code="http-rpc"/>
<OutProtocol code="json"/>
</Application>
<Application name="SayHelloSoap" service="SayHelloSercice">
<InProtocol code="http-rpc"/>
<OutProtocol code="soap11"/>
</Application>
</Applications>
Чтобы новая версия конфигурации применилась необходимо либо перезапустить сервер, либо выполнить менедж-комманду:
django_admin.py wsfactory_reload
Ещё раз повторим запрос, немного изменив урл:
curl "http://localhost:8000/wsfactory/api/SayHelloSoap/SayHello?name=Tim×=4 | python -m json.tool
И получим результат:
<senv:Envelope xmlns:tns="http://company.domain/tns" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/">
<senv:Body>
<tns:SayHelloResponse>
<tns:SayHelloResult>
<tns:string>Hello, Tim!</tns:string>
<tns:string>Hello, Tim!</tns:string>
<tns:string>Hello, Tim!</tns:string>
<tns:string>Hello, Tim!</tns:string>
</tns:SayHelloResult>
</tns:SayHelloResponse>
</senv:Body>
</senv:Envelope>
Немного модифицируем наш api-метод:
@srpc(Unicode, Integer,
_returns=Iterable(Unicode, member_name="Greeting"),
_out_variable_name="Greetings")
def SayHello(name, times):
return repeat(u"Hello, {0}!".format(name), times)
Перезапустим сервер, поновой выполним запрос и получим результат:
<senv:Envelope xmlns:tns="http://company.domain/tns" xmlns:senv="http://schemas.xmlsoap.org/soap/envelope/">
<senv:Body>
<tns:SayHelloResponse>
<tns:Greetings>
<tns:Greeting>Hello, Tim!</tns:Greeting>
<tns:Greeting>Hello, Tim!</tns:Greeting>
<tns:Greeting>Hello, Tim!</tns:Greeting>
<tns:Greeting>Hello, Tim!</tns:Greeting>
</tns:Greetings>
</tns:SayHelloResponse>
</senv:Body>
</senv:Envelope>
Таким образом, мы написали в коде api-метод, а сам веб-сервис описали декларативно в конфигурации.