source: trunk/workshop/2014/first_service.rst @ 848

Last change on this file since 848 was 725, checked in by djay, 9 years ago

Fix issue with rst files displayed from Trac. Fix strings to be translated. Always use the same string in all messages.

  • Property svn:keywords set to Date Author
  • Property svn:mime-type set to text/plain
File size: 14.8 KB
Line 
1.. _first_service:
2
3Creating your first ZOO Service
4========================================
5
6.. contents:: Table of Contents
7    :depth: 5
8    :backlinks: top
9
10Introduction
11-----------------------------------------------------
12
13In this part, you will create and publish a simple ZOO-Service named ``Hello`` which
14will simply return a hello message containing the input value provided. It will be usefull
15to present in deeper details general concept on how ZOO-Kernel works and handles
16Execute requests.
17
18Service and publication process overview
19-----------------------------------------------------
20
21Before starting developing a ZOO Service, you should remember that in
22ZOO-Project, a Service is a couple made of:
23
24 * a metadata file: a ZOO Service Configuration File (ZCFG) containing metadata
25   informations about a Service (providing informations about default / supported
26   inputs and outputs for a Service)
27 * a Services Provider: it depends on the programming language used, but for Python it
28   is a module and for JavaScript a script file.
29
30To publish your Service, which means make your ZOO Kernel aware of its presence,
31you should copy a ZCFG file in the directory where ``zoo_loader.cgi`` is located (in this workshop, ``/usr/lib/cgi-bin``) or in any subdirectory.
32
33.. warning:: only the ZCFG file is required  for the Service to be considerate as
34    available. So if you don't get the Service Provider, obviously your Execute
35    request will fail as we will discuss later.
36
37Before publication, you should store your ongoing work, so you'll start by
38creating a directory to store the files of your Services Provider:
39
40.. code-block:: none
41   
42    mkdir -p /home/user/zoo-ws/ws_sp/cgi-env
43
44Once the ZCFG and the Python module are both ready, you can publish simply
45by copying the corresponding files in the same directory as the ZOO-Kernel.
46
47Creating your first ZCFG file
48-----------------------------------------------------
49
50You will start by creating the ZCFG file for the ``Hello`` Service. Edit the
51``/home/user/zoo-ws/ws_sp/cgi-env/Hello.zcfg`` file
52and add the following content:
53
54.. code-block:: none
55    :linenos:
56   
57    [Hello]
58     Title = Return a hello message.
59     Abstract = Create a welcome string.
60     processVersion = 2
61     storeSupported = true
62     statusSupported = true
63     serviceProvider = test_service
64     serviceType = Python
65     <DataInputs>
66      [name]
67       Title = Input string
68       Abstract = The string to insert in the hello message.
69       minOccurs = 1
70       maxOccurs = 1
71       <LiteralData>
72           dataType = string
73           <Default />
74       </LiteralData>
75     </DataInputs>
76     <DataOutputs>
77      [Result]
78       Title = The resulting string
79       Abstract = The hello message containing the input string
80       <LiteralData>
81           dataType = string
82           <Default />
83       </LiteralData>
84     </DataOutputs>
85
86.. note:: the name of the ZCFG file and the name between braket (here ``[Hello]``)
87    should be the same and correspond to the function name you will define in your
88    Services provider.
89
90As you can see in the ZOO Service Configuration File presented above it is divided into
91three distinct sections:
92  #. Main Metadata information (from line 2 to 8)
93  #. List of Inputs metadata information (from 9 line to 19)
94  #. List of Outputs metadata information (from line 20 to 28)
95
96You can get more informations about ZCFG from `the reference documentation
97<http://zoo-project.org/docs/services/zcfg-reference.html>`__.
98
99If you copy the ``Hello.zcfg`` file in the same directory as your ZOO Kernel
100then you will be able to request for DescribeProcess using the ``Hello``
101``Identifier``. The ``Hello`` service should also be listed from Capabilities
102document.
103
104.. code-block:: none
105   cp /home/user/zoo-ws/ws_sp/cgi-env/Hello.zcfg /usr/lib/cgi-bin
106
107Test requests
108-----------------------------------------------------
109
110In this section you will tests each WPS requests : GetCapabilities,
111DescribeProcess and Execute. Note that only GetCapabilities and DescribeProcess
112should work at this step.
113
114Test the GetCapabilities request
115.......................................................
116
117If you run the ``GetCapabilities`` request:
118
119.. code-block:: none
120   
121    http://localhost/cgi-bin/zoo_loader.cgi?request=GetCapabilities&service=WPS
122
123Now, you should find your Hello Service in a ``Process`` node in
124``ProcessOfferings``:
125
126.. code-block:: xml
127   
128    <wps:Process wps:processVersion="2">
129     <ows:Identifier>Hello</ows:Identifier>
130     <ows:Title>Return a hello message.</ows:Title>
131     <ows:Abstract>Create a welcome string.</ows:Abstract>
132    </wps:Process>
133
134Test the DescribeProcess request
135.......................................................
136
137You can access the ``ProcessDescription`` of the ``Hello`` service using the
138following ``DescribeProcess`` request:
139
140.. code-block:: none
141   
142    http://localhost/cgi-bin/zoo_loader.cgi?request=DescribeProcess&service=WPS&version=1.0.0&Identifier=Hello
143
144You should get the following response:
145
146.. code-block:: xml
147   
148    <wps:ProcessDescriptions xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:wps="http://www.opengis.net/wps/1.0.0" xmlns:xlink="http://www.w3.org/1999/xlink" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xsi:schemaLocation="http://www.opengis.net/wps/1.0.0 http://schemas.opengis.net/wps/1.0.0/wpsDescribeProcess_response.xsd" service="WPS" version="1.0.0" xml:lang="en-US">
149      <ProcessDescription wps:processVersion="2" storeSupported="true" statusSupported="true">
150        <ows:Identifier>Hello</ows:Identifier>
151        <ows:Title>Return a hello message.</ows:Title>
152        <ows:Abstract>Create a welcome string.</ows:Abstract>
153        <DataInputs>
154          <Input minOccurs="1" maxOccurs="1">
155            <ows:Identifier>name</ows:Identifier>
156            <ows:Title>Input string</ows:Title>
157            <ows:Abstract>The string to insert in the hello message.</ows:Abstract>
158            <LiteralData>
159              <ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#string">string</ows:DataType>
160              <ows:AnyValue/>
161            </LiteralData>
162          </Input>
163        </DataInputs>
164        <ProcessOutputs>
165          <Output>
166            <ows:Identifier>Result</ows:Identifier>
167            <ows:Title>The resulting string</ows:Title>
168            <ows:Abstract>The hello message containing the input string</ows:Abstract>
169            <LiteralOutput>
170              <ows:DataType ows:reference="http://www.w3.org/TR/xmlschema-2/#string">string</ows:DataType>
171            </LiteralOutput>
172          </Output>
173        </ProcessOutputs>
174      </ProcessDescription>
175    </wps:ProcessDescriptions>
176
177Test the Execute request
178.......................................................
179
180Obviously, you cannot run your Service because the Python file was not published
181yet. If you try the following ``Execute`` request:
182
183.. code-block:: none
184   
185    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto
186
187You should get an ExceptionReport similar to the one provided in the following,
188which is normal behavior:
189
190.. code-block:: xml
191
192    <ows:ExceptionReport xmlns:ows="http://www.opengis.net/ows/1.1" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:xlink="http://www.w3.org/1999/xlink" xsi:schemaLocation="http://www.opengis.net/ows/1.1 http://schemas.opengis.net/ows/1.1.0/owsExceptionReport.xsd" xml:lang="en-US" version="1.1.0">
193      <ows:Exception exceptionCode="NoApplicableCode">
194        <ows:ExceptionText>Python module test_service cannot be loaded.</ows:ExceptionText>
195      </ows:Exception>
196    </ows:ExceptionReport>
197
198Implementing the Python Service
199-----------------------------------------------------
200
201General Principles
202.......................................................
203
204The most important thing you must know when implementing a new ZOO-Services
205using the Python language is that the function corresponding to your Service
206returns an integer value representing the status of execution
207(``SERVICE_FAILED`` [#f1]_ or ``SERVICE_SUCCEEDED`` [#f2]_) and takes three
208arguments (`Python dictionaries
209<http://docs.python.org/tutorial/datastructures.html#dictionaries>`__):
210
211  -  ``conf`` : the main environment configuration (corresponding to the main.cfg content)
212  - ``inputs`` : the requested / default inputs (used to access input values)
213  - ``outputs`` : the requested / default outputs (used to store computation result)
214
215.. note:: when your service return ``SERVICE_FAILED`` you can set
216    ``conf["lenv"]["message"]`` to add a personalized message in the ExceptionReport
217    returned by the ZOO Kernel in such case.
218
219You get in the following a sample ``conf`` value based on the ``main.cfg`` file you
220saw `before <using_zoo_from_osgeolivevm.html#zoo-kernel-configuration>`__.
221
222.. code-block:: javascript
223    :linenos:   
224
225    {
226      "main": {
227        language: "en-US",
228        lang: "fr-FR,ja-JP",
229        version: "1.0.0",
230        encoding: "utf-8",
231        serverAddress: "http://localhost/cgi-bin/zoo_loader.cgi",
232        dataPath: "/var/data",
233        tmpPath: "/var/www/temp",
234        tmpUrl: "../temp",
235        cacheDir: "/var/www/temp/"
236      },
237      "identification": {
238        title: "ZOO-Project Workshop - FOSS4G 2014",
239        keywords: "WPS,GIS,buffer",
240        abstract: "Deploying Web Processing Services using ZOO-Project – Examples of Python based WPS using PgRouting",
241        accessConstraints: "none",
242        fees: "None"
243      },
244      "provider": {
245        positionName: "Developer",
246        providerName: "ZOO-Project",
247        addressAdministrativeArea: "Lattes",
248        addressCountry: "fr",
249        phoneVoice: "False",
250        addressPostalCode: "34970",
251        role: "Dev",
252        providerSite: "http://www.zoo-project.org",
253        phoneFacsimile: "False",
254        addressElectronicMailAddress: "gerald.fenoy@geolabs.fr",
255        addressCity: "Denver",
256        individualName: "Gérald FENOY"
257      }
258
259In the following you get a sample outputs value passed to a Python or a JavaScript Service:
260
261.. code-block:: javascript
262    :linenos:   
263
264    {
265      'Result': {
266        'mimeType': 'application/json',
267        'inRequest': 'true',
268        'encoding': 'UTF-8'
269      }
270    }
271
272.. note:: the ``inRequest`` value is set internally by the ZOO-Kernel and can be    used to determine from the Service if the key was provided in the request.
273
274ZOO-Project provide a ZOO-API which was originally only available for
275JavaScript services, but thanks to the work of the ZOO-Project
276community, now you have also access to a ZOO-API when using
277the Python language. Thanks to the Python ZOO-API you don't have to remember anymore
278the value of SERVICE_SUCCEDED and SERVICE_FAILED, you
279have the capability to translate any string from your Python service
280by calling the ``_`` function (ie: ``zoo._('My string to
281translate')``) or to update the current status of a running service by
282using the ``update_status`` [#f4]_ function the same way you use it from
283JavaScript or C services.
284
285The Hello Service
286.......................................................
287
288You can copy and paste the following into the
289``/home/user/zoo-ws/ws_sp/cgi-env/test_service.py`` file.
290
291.. code-block:: python
292   
293    import zoo
294    def Hello(conf,inputs,outputs):
295        outputs["Result"]["value"]=\
296                "Hello "+inputs["name"]["value"]+" from the ZOO-Project Python world !"
297        return zoo.SERVICE_SUCCEEDED
298
299Once you finish editing the file, you should copy it in the ``/usr/lib/cgi-bin`` directory:
300
301.. code-block:: none
302   
303    sudo cp /home/user/zoo-ws/ws_sp/cgi-env/* /usr/lib/cgi-bin
304
305
306Interracting with your service using Execute requests
307
308
309Now, you can request for Execute using the following basic url:
310
311.. code-block:: none
312   
313    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto
314
315You can request the WPS Server to return a XML WPS Response containing the result of
316your computation, requesting for ResponseDocument or you can access the data directly
317requesting for RawDataOutput.
318
319* Sample request using the RawDataOutput parameter:
320
321.. code-block:: none
322   
323    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&RawDataOutput=Result
324
325* Sample request using the default ResponseDocument parameter:
326
327.. code-block:: none
328   
329    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result
330
331When you are using ResponseDocument there is specific attribut you can use to ask
332the ZOO Kernel to store the result: ``asReference``. You can use the following example:
333
334.. code-block:: none
335   
336    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result@asReference=true
337
338When computation take long time, the client should request the
339execution of a Service by setting both ``storeExecuteResponse`` and
340``status`` parameter to true to force asynchronous execution. This
341will make the ZOO-Kernel return, without waiting for the Service execution
342completion but after starting another ZOO-Kernel process responsible
343of the Service execution, a ResponseDocument containing a ``statusLocation``
344attribute which can be used to access the status of an ongoing service
345or the result when the process ended [#f3]_.
346
347.. code-block:: none
348   
349    http://localhost/cgi-bin/zoo_loader.cgi?request=Execute&service=WPS&version=1.0.0&Identifier=Hello&DataInputs=name=toto&ResponseDocument=Result&storeExecuteResponse=true&status=true
350
351Conclusion
352-----------------------------------------------------
353
354Even if this first service was really simple it was useful to illustrate how the
355ZOO-Kernel fill ``conf``, ``inputs`` and ``outputs`` parameter prior to load
356and run your function service, how to write a ZCFG file, how to publish a Services
357Provider by placing the ZCFG and Python files in the same directory as the
358ZOO-Kernel, then how to interract with your service using both
359``GetCapabilities``, ``DescribeProcess`` and ``Execute`` requests. We will see
360in the `next section <building_blocks_presentation.html>`__ how to write similar requests
361using the XML syntax.
362
363.. rubric:: Footnotes
364
365.. [#f1] ``SERVICE_FAILED=4``
366.. [#f2] ``SERVICE_SUCCEEDED=3``
367.. [#f4] sample use of update_status is available `here <http://zoo-project.org/trac/browser/trunk/zoo-project/zoo-services/utils/status/cgi-env/service.py#L1>`_
368.. [#f3]  To get on-going status url in ``statusLocation``, you'll
369    need to setup the `utils/status
370    <http://www.zoo-project.org/trac/browser/trunk/zoo-project/zoo-services/utils/status>`_
371    Service. If you don't get this service available, the ZOO-Kernel will
372    simply give the url to a flat XML file stored on the server which will
373    contain, at the end of the execution, the result of the Service
374    execution. For more informations please take a look into the
375    reference  `documentation <http://zoo-project.org/docs/services/status.html>`__.
Note: See TracBrowser for help on using the repository browser.

Search

ZOO Sponsors

http://www.zoo-project.org/trac/chrome/site/img/geolabs-logo.pnghttp://www.zoo-project.org/trac/chrome/site/img/neogeo-logo.png http://www.zoo-project.org/trac/chrome/site/img/apptech-logo.png http://www.zoo-project.org/trac/chrome/site/img/3liz-logo.png http://www.zoo-project.org/trac/chrome/site/img/gateway-logo.png

Become a sponsor !

Knowledge partners

http://www.zoo-project.org/trac/chrome/site/img/ocu-logo.png http://www.zoo-project.org/trac/chrome/site/img/gucas-logo.png http://www.zoo-project.org/trac/chrome/site/img/polimi-logo.png http://www.zoo-project.org/trac/chrome/site/img/fem-logo.png http://www.zoo-project.org/trac/chrome/site/img/supsi-logo.png http://www.zoo-project.org/trac/chrome/site/img/cumtb-logo.png

Become a knowledge partner

Related links

http://zoo-project.org/img/ogclogo.png http://zoo-project.org/img/osgeologo.png