source: TI02-CSML/trunk/services/3rdParty/pywps-1.0.0/wps.py @ 2194

Subversion URL: http://proj.badc.rl.ac.uk/svn/ndg/TI02-CSML/trunk/services/3rdParty/pywps-1.0.0/wps.py@2194
Revision 2194, 9.5 KB checked in by lawrence, 13 years ago (diff)

Adding various specs and 3rd party code of interest for the CSML
services development.

  • Property svn:executable set to *
Line 
1#!/usr/bin/python
2#-*- coding: utf-8 -*-
3"""
4This program is simple implementation of OGS's [http://opengeospatial.org]
5Web Processing Service (OpenGIS(r) Web Processing Service - OGC 05-007r4)
6version 0.4.0 from 2005-09-16
7
8Target of this application is to bring functionality of GIS GRASS
9[http://grass.itc.it] to the World Wide Web - it should work like
10wrapper for modules of this GIS. Though GRASS was at the first place in the
11focuse, it is not necessery to use it's modules - you can use any program
12you can script in Python or other language.
13
14This first version was written with support of Deutsche Bundesstiftung
15Umwelt, Osnabrueck, Germany on the spring 2006. SVN server is hosted by
16GDF-Hannover, Hannover, Germany.
17
18For setting see comments in 'etc' directory and documentation.
19
20This program is free sotware, distributed under the terms of GNU General
21Public License as bulished by the Free Software Foundation version 2 of the
22License.
23
24Enjoy and happy GISing!
25"""
26# Author:       Jachym Cepicky
27#               http://les-ejk.cz
28# Lince:
29#
30# Web Processing Service implementation
31# Copyright (C) 2006 Jachym Cepicky
32#
33# This program is free software; you can redistribute it and/or modify
34# it under the terms of the GNU General Public License as published by
35# the Free Software Foundation; either version 2 of the License.
36#
37# This program is distributed in the hope that it will be useful,
38# but WITHOUT ANY WARRANTY; without even the implied warranty of
39# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
40# GNU General Public License for more details.
41#
42# You should have received a copy of the GNU General Public License
43# along with this program; if not, write to the Free Software
44# Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
45
46import pywps
47from pywps.etc import grass
48from pywps.etc import settings
49from pywps import Wps
50from pywps.Wps import wpsexceptions
51from pywps.Wps import capabilities
52from pywps.Wps import describe
53from pywps.Wps import execute
54from pywps.Wps import inputs
55from pywps import processes
56from pywps.processes import *
57
58
59import string, sys, os, tempfile, glob, shutil, time, cgi
60#import cgitb; cgitb.enable()
61
62def main():
63    """
64    This main function controlls input variables and calls either
65    GetCapabilities, DescribeProcess or Execute functions.
66
67    If Execute request is called, the temporary directory will be created
68    and everything should happen in this directory.
69    """
70   
71    wpsExceptions = wpsexceptions.WPSExceptions() # class for exceptions
72    formValues = {}  # input values
73    serverSettings = settings.ServerSettings
74    inpts = inputs.Inputs() # data inputs
75    pid = os.getpid()
76   
77
78    try: #  Maximal length of one input
79        if os.getenv("REQUEST_METHOD") == "GET":
80            maxSize = int(serverSettings['maxInputParamLength'])
81            maxSize = int(serverSettings['maxSize'])
82    except:
83        if os.getenv("REQUEST_METHOD") == "GET":
84            maxSize = 1024
85        else:
86            maxSize = 0 # will be controlled later
87
88    # key values to lower case
89    if os.getenv("REQUEST_METHOD") == "GET":
90        form = cgi.FieldStorage()  # the input values (GET method)
91        for key in form.keys():
92            value = form.getvalue(key)
93            # to avoid problems with more then one inputs
94            if type(form.getvalue(key)) == type([]):
95                value = value[-1].strip()
96
97            value = value.strip()
98
99            if len(value) > maxSize and maxSize > 0:
100                print "Content-type: text/xml\n"
101                print wpsExceptions.make_exception("FileSizeExceeded",key)
102                return
103            formValues[key.lower()] = value
104
105    #
106    # HTTP GET
107    if os.getenv("REQUEST_METHOD") == "GET":
108        e = inpts.formvalsGet2dict(formValues)
109        if e:
110            print "Content-type: text/xml\n"
111            print wpsExceptions.make_exception(e,"")
112            return
113
114        # request
115        if not 'request' in inpts.values.keys():
116            print "Content-type: text/xml\n"
117            print wpsExceptions.make_exception("MissingParameterValue","request")
118            return
119
120        #
121        # Check inputs again
122        if not 'service' in inpts.values.keys(): 
123            print "Content-type: text/xml\n"
124            print wpsExceptions.make_exception("MissingParameterValue",'service')
125            return
126
127        elif not 'version' in inpts.values.keys() and \
128            inpts.values['request'].lower() != "getcapabilities":
129            print "Content-type: text/xml\n"
130            print wpsExceptions.make_exception("MissingParameterValue",'version')
131            return
132       
133        # service == wps
134        if inpts.values['service'].lower() != 'wps':
135            print "Content-type: text/xml\n"
136            print wpsExceptions.make_exception("InvalidParameterValue",
137                    'service')
138            return
139        # version == 0.4.0
140        elif inpts.values['request'].lower() != "getcapabilities" \
141            and inpts.values['version'].lower() != '0.4.0':
142            print "Content-type: text/xml\n"
143            print wpsExceptions.make_exception("InvalidParameterValue",
144                    'version')
145            return
146
147
148    #
149    # HTTP POST
150    else:
151        try:
152            size = serverSettings['maxSize']
153        except:
154            size = 0
155        e = inpts.formvalsPost2dict(sys.stdin,size)
156        if e:
157            print "Content-type: text/xml\n"
158            print wpsExceptions.make_exception(str(e))
159            return
160
161
162
163    # Controll of all 'identifier' values - if wrongprocess is
164    # set, exception, nothing otherwice
165    wrongprocess = inpts.controllProcesses(
166            processes.__all__,inpts.values)
167    if wrongprocess:
168        if wrongprocess != "identifier":
169            print "Content-type: text/xml\n"
170            print wpsExceptions.make_exception(
171                    "InvalidParameterValue",wrongprocess
172                    )
173        else:
174            print "Content-type: text/xml\n"
175            print wpsExceptions.make_exception(
176                    "MissingParameterValue",wrongprocess
177                    )
178
179        return
180
181    #---------------------------------------------------------------------
182
183    #
184    # Request  handeling
185    #
186   
187    #
188    # GetCapabilities
189    if inpts.values['request'].lower() == "getcapabilities":
190        getCapabilities = capabilities.Capabilities(settings,processes)
191        print "Content-type: text/xml\n"
192        print getCapabilities.document.toprettyxml()
193    #
194    # DescribeProcess
195    elif inpts.values["request"].lower() == "describeprocess":
196        describeProc = describe.Describe(settings,processes,inpts.values)
197        if describeProc.document != None:
198            print "Content-type: text/xml\n"
199            print describeProc.document.toprettyxml()
200    #
201    # Execute
202    elif inpts.values["request"].lower() == "execute":
203
204        # Create PID file, temp directory etc.
205        # check for number of running operations
206        try:
207            nPIDFiles = len(glob.glob(
208                os.path.join(settings.ServerSettings['tempPath'],"pywps-pidfile-*")))
209            # cleaning if something goes wrong
210            # for file in glob.glob(
211            #         os.path.join(settings.ServerSettings['tempPath'],"pywps*")):
212            #     sys.stderr.write(file+"\n")
213            #     os.remove(file)
214        except (IOError, OSError), what:
215            print "Content-type: text/xml\n"
216            print wpsExceptions.make_exception(
217                    "ServerError","IOError,OSError: %s" % what)
218            return
219
220        try:
221            maxPIDFiles = settings.ServerSettings['maxOperations']
222        except KeyError:
223            maxPIDFiles = 1
224
225        # too many processes ?
226        if nPIDFiles >=  maxPIDFiles:
227            print "Content-type: text/xml\n"
228            print wpsExceptions.make_exception("ServerBusy","%d %d" % (nPIDFiles, maxPIDFiles))
229            #os.remove(PIDFile[1])
230            return
231        else:
232            PIDFile = tempfile.mkstemp(prefix="pywps-pidfile-")
233            pass
234
235
236        # MAKE
237        process = eval("processes.%s.Process()" %
238                (inpts.values['identifier'][0]))
239        executeProc = None
240        try:
241            executeProc =  execute.Execute(settings,grass.grassenv,process,inpts.values)
242        except Exception,e:
243            # error reporting
244            sys.stderr.write("PyWPS ERROR in execute.Execute(): "+str(e)+"\n")
245            # cleaning
246            os.remove(PIDFile[1])
247            return 1
248
249
250        # asynchronous?
251        # only, if this is child process:
252        if not executeProc.pid:
253            file = open(
254                os.path.join(settings.ServerSettings['outputPath'],executeProc.executeresponseXmlName),"w")
255            sys.stdout = file
256
257        # clean the PID file       
258        if not (executeProc.status.lower() == "processaccepted" or \
259                executeProc.status.lower() == "processstarted"):
260                os.remove(PIDFile[1])
261
262        if executeProc.document:
263            if sys.stdout == sys.__stdout__:
264                print "Content-type: text/xml\n"
265            print executeProc.document.toprettyxml(indent='\t', newl='\n')
266        else:
267            # clean the PID file       
268            try:
269                os.remove(PIDFile[1])
270            except:
271                pass
272
273        # only, if this is child process:
274        if not executeProc.pid:
275            file.close()
276    else:
277        print "Content-type: text/xml\n"
278        print wpsExceptions.make_exception("InvalidParameterValue","request")
279        return
280
281       
282if __name__ == "__main__":
283    main()
Note: See TracBrowser for help on using the repository browser.