Introducing the Spyne Library
In this article I want to talk about the wonderful Python library Spyne. My acquaintance with Spyne began at the moment when the task was set before me to write a Web service that would accept and send requests via the SOAP protocol. A little googling I stumbled upon
Spyne , which is a fork of the
soaplib library. And I was surprised how little Russian-language information is found about this library.
With the help of Spyne, you can write web services that can work with SOAP, JSON, YAML, and you can run the written script via Apache mod_wsgi. So, let's look at a few examples, write working scripts and configure them so that the scripts work through apache.
1. SOAP service
Let's write a web service that will serve us as an English translator. Our web service will receive requests, contact Yandex-translator, receive a translation and give this translation to the client. Incoming requests are accepted in XML format. The answer will also go away in XML format.
')
The first step is to get an API key to tell Yandex that we are ours. How can I do this, look
here .
Now go directly to the development.
Install the necessary libraries: “pytz”, “spyne”, and also “yandex_translate”. Libraries are installed very easily via pip.
The application code looks like this:
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()
Let's sort the code:
After importing the required libraries, we created the
“Soap” class with the
“ServiceBase” argument. The
"@rpc (Unicode, _returns = Unicode)" decorator defines the type of incoming arguments
("Unicode") and outgoing responses
("_returns = Unicode") . The list of available argument types can be found in the
official documentation. . Next, the
“Insoap” method is created with the arguments
“ctx” and
“words” . The
“ctx” argument is very important, as it contains a lot of information about incoming requests. The string
“print (etree.tostring (ctx.in_document))” displays the incoming xml request, in the form in which the user sent it to us. At some points it may be important.
For example, in the course of writing a web service, I needed to pull in an incoming xml request and write it to the database. But how to get this xml request out is not mentioned in the official Spyne documentation. Burak Arslan (by Spyne) recommended looking towards the lxml library. Only after that I found the answer and see the result in this script. Further, our method refers to the Yandex-translator and returns the result obtained from the Yandex-translator to the client.
The variable
“app” defines the settings of our web service:
“Application ([Soap]” ) indicates which class is initialized (there may be several), the
“in_protocol” and
“out_protocol” parameters determine the type of incoming and outgoing requests, in our case this SOAP v1.1.
The string
"application = WsgiApplication (app)" is defined so that our script can work through wsgi.
Important! the name of the variable must be “application” so that our application can work through apache using mod_wsgi. The following lines of code initialize and start the Web server on port 8000.
Run the script and you can start testing. For these purposes, I use
SoapUI . Convenience is that after launching and configuring to work with the SOAP server, SoapUI automatically generates an xml request. Configure the URL:
localhost : 8000? Wsdl (assuming that the script is running on the local machine), and our xml request looks like this:
Body xml request<soapenv: Envelope xmlns: soapenv = "
schemas.xmlsoap.org/soap/envelope " xmlns: tran = "Translator">
<soapenv: Header />
<soapenv: Body>
<tran: Insoap>
<tran: words> Test our application </ tran: words>
</ tran: Insoap>
</ soapenv: Body>
</ soapenv: Envelope>
Our web service gave the following response:
Server response<soap11env: Envelope xmlns: soap11env = "
schemas.xmlsoap.org/soap/envelope " xmlns: tns = "Translator">
<soap11env: Body>
<tns: InsoapResponse>
<tns: InsoapResult> Test our app </ tns: InsoapResult>
</ tns: InsoapResponse>
</ soap11env: Body>
</ soap11env: Envelope>
It's simple, is not it?
2. REST service
Suppose that now we have changed those. task, and you need to make a web service that works through JSON. What to do? To rewrite our service on another framework, such as the
Django Rest Framework or
Flask ? or can you manage with less effort? Yes you can! And you need!
Spyne library to help us.
All that needs to be changed in our application, is the “app” variable to result in the following form:
app = Application([Soap], tns='Translator', in_protocol=JsonDocument(validator='soft'), out_protocol=JsonDocument())
We start our web service and are tested.
Our JSON request looks like this:
JSON request body{“Insoap”: {“words”: “we are testing our web service. Use JSON »}}
The web server returned the following response:
Web server response«Test our web service. Use JSON
3. Output to production
To start our web service via apache, you need to install and configure
apache and
mod_wsgi web server on the server. These works are easy to perform, based on the documentation. In addition, in our script we have to delete the following lines:
Strings to remove if __name__ == '__main__': from wsgiref.simple_server import make_server server = make_server('0.0.0.0', 8000, application) server.serve_forever()
Hooray! Our web service is ready to use.
PS about the additional features of Spyne (and there are a lot of them) are always available on the
official website , which I highly recommend to you.