def setUp(self): def hello(request): pass def ping(request): pass processes = [ Process( hello, 'hello', 'Process Hello', metadata=[ Metadata( 'hello metadata', 'http://example.org/hello', role= 'http://www.opengis.net/spec/wps/2.0/def/process/description/documentation' ) ]), Process(ping, 'ping', 'Process Ping', metadata=[ Metadata('ping metadata', 'http://example.org/ping') ]), ] self.client = client_for(Service(processes=processes))
def create_app(): service = Service(processes=[ Process(say_hello, inputs=[LiteralInput('name', 'string')], outputs=[LiteralOutput('response', 'string')]), Process(feature_count, inputs=[ComplexInput('layer', [Format(Formats.GML)])], outputs=[ComplexInput('layer', [Format(Formats.GML)])]), Process(centroids, inputs=[ComplexInput('layer', [Format(Formats.GML)])]), ]) app = flask.Flask(__name__) @app.route('/') def home(): url = flask.url_for('wps', _external=True) return flask.render_template('home.html', url=url) @app.route('/wps', methods=['GET', 'POST']) def wps(): return service @app.route('/datafile/<uuid>') def datafile(uuid): for data_file in recent_data_files: if data_file['uuid'] == uuid: return flask.Response(data_file['bytes']) else: flask.abort(404) return app
def setUp(self): def hello(request): pass def ping(request): pass processes = [Process(hello), Process(ping)] self.client = client_for(Service(processes=processes))
def setUp(self): def pr1(): pass def pr2(): pass self.client = client_for( Service(processes=[Process(pr1), Process(pr2)]))
def test20FTPSupport(self): """Testing FTP support""" #NOTE: pyftpdlib uses a pure Python thread to work, if using the normal Thread class thins get blocked #Better to use mutiprocessor or a suprocess.Popen call try: from pyftpdlib import ftpserver except: assert False, "Please install pyftpdlib from http://code.google.com/p/pyftpdlib/" from multiprocessing import Process import time,os.path import hashlib import pywps #PyWPS configuration -- setConfiguration added to in SVN - pywps-soap:1260 pywps.config.setConfigValue("server","outputPath", self.outputPath) pywps.config.setConfigValue("server","outputUrl",self.outputURL) pywps.config.setConfigValue("server","ftplogin",self.ftpLogin) pywps.config.setConfigValue("server","ftppasswd",self.ftpPasswd) #ATTENTION EVERYTHING HAS TO BE STRING OTHERWISE IT DOESNT WORK pywps.config.setConfigValue("server","ftpport",str(self.ftpPort)) p=Process(target=ftpServer,args=(self.ftpHost,self.ftpPort,self.ftpLogin,self.ftpPasswd,self.ftpPath,self.ftpPerm,)) p.start() time.sleep(20) #running the WPS getpywps=pywps.Pywps(pywps.METHOD_GET) getinputs = getpywps.parseRequest("service=wps&version=1.0.0&request=Execute&identifier=referencedefault&responsedocument=vectorout=@asReference=True;string=@asReference=True;bboxout=@asReference=True") getpywps.performRequest(getinputs) xmldom = minidom.parseString(getpywps.response) time.sleep(3)# give some time to sync all code, maybe it's not necessary p.terminate() #SEE: if there is some error exceptionText=xmldom.getElementsByTagNameNS(self.owsns,"Reference") if len(exceptionText)>0: #We have an error, probably no FTP connection self.assertTrue(False,self.exceptionText.childNodes[0].nodeValue) #RESET FTP parameters pywps.config.loadConfiguration() #ASSIGNED PROCESS OUTPUT # 2nd part output interactor, 1st part lambda case ComplexOutput then open file and read content processOutputs=list(map(lambda output:open(os.path.join(self.ftpPath,output.value)).read() if isinstance(output,pywps.Process.InAndOutputs.ComplexOutput) else output.value,getpywps.request.process.outputs.values() )) processOutputsMD5=[hashlib.md5(item).hexdigest() for item in processOutputs] #FTP PROCESS OUTPUT referenceNodes=xmldom.getElementsByTagNameNS(self.wpsns,"Reference") urlList=[node.getAttribute("href") for node in referenceNodes] #getContent from folfer, FTP is already dead outputFTP=[open(os.path.join(self.ftpPath,os.path.basename(url))).read() for url in urlList] outputFTPMD5=[hashlib.md5(item).hexdigest() for item in outputFTP] #assertFalse (empty array) self.assertFalse(bool([item in outputFTP for item in outputFTPMD5 if not item]))
def setUp(self): def hello(request): pass def ping(request): pass processes = [ Process(hello, 'hello', 'Process Hello'), Process(ping, 'ping', 'Process Ping') ] self.client = client_for(Service(processes=processes))
def testQuoteChar(self): """Text exception with escape chars""" from pywps.Process import WPSProcess import re name = "proc_name" exception_message = "<<to-be-escaped>>" wps = pywps.Pywps(pywps.METHOD_GET) wps.parseRequest( 'service=WPS&version=1.0.0&request=Execute&identifier=%s' % name) class Process(WPSProcess): def __init__(self): WPSProcess.__init__(self, identifier=name, title="Testing process") def execute(self): raise RuntimeError(exception_message) response = wps.performRequest(processes=[Process()]) pattern = re.compile('<ows:ExceptionText>(.*)</ows:ExceptionText>') if pattern.search(response): exception_text = pattern.search(response).group(1) else: assert False, "ExceptionText not found in response:\n%s" % response self.assertEquals( 'Failed to execute WPS process [proc_name]: <<to-be-escaped>>', exception_text) self.assertNotEquals( 'Failed to execute WPS process [proc_name]: <<to-be-escaped>>', exception_text)
def test_one_literal_string_input(self): def hello(request): pass hello_process = Process(hello, inputs=[LiteralInput('the_name')]) result = self.describe_process(hello_process) assert result.inputs == [('the_name', 'literal', 'string')]
def test_get_input_title(self): """Test returning the proper input title""" # configure def donothing(*args, **kwargs): pass process = Process(donothing, "process", title="Process", inputs=[ LiteralInput("length", title="Length"), BoundingBoxInput("bbox", title="BBox", crss=[]), ComplexInput("vector", title="Vector") ], outputs=[], metadata=[ Metadata('process metadata 1', 'http://example.org/1'), Metadata('process metadata 2', 'http://example.org/2') ]) inputs = {input.identifier: input.title for input in process.inputs} self.assertEqual("Length", inputs['length']) self.assertEqual("BBox", inputs["bbox"]) self.assertEqual("Vector", inputs["vector"])
def create_sum_one(): def sum_one(request, response): input = request.inputs['input'] # What do we need to assert a Complex input? #assert type(input) is text_type sys.path.append("/usr/lib/grass64/etc/python/") import grass.script as grass # Import the raster and set the region if grass.run_command("r.in.gdal", flags="o", out="input", input=input) != 0: raise NoApplicableCode("Could not import cost map. Please check the WCS service.") if grass.run_command("g.region", flags="ap", rast="input") != 0: raise NoApplicableCode("Could not set GRASS region.") # Add 1 if grass.mapcalc("$output = $input + $value", output="output", input="input", value=1.0) != 0: raise NoApplicableCode("Could not set GRASS region.") # Export the result out = "./output.tif" if grass.run_command("r.out.gdal", input="output", type="Float32", output=out) != 0: raise NoApplicableCode("Could not export result from GRASS.") response.outputs['output'] = out return response return Process(handler=sum_one, identifier='sum_one', title='Process Sum One', inputs=[ComplexInput('input', [Format('image/img')])], outputs=[ComplexOutput('output', [Format('image/tiff')])])
def from_json(cls, value): """init this request from json back again :param value: the json (not string) representation """ process = Process.from_json(value['process']) wps_request = WPSRequest() wps_request.json = json.loads(value['wps_request']) wps_response = ExecuteResponse(wps_request=wps_request, uuid=process.uuid, process=process) wps_response.store_status_file = True new_job = Job(process=Process.from_json(value['process']), wps_request=wps_request, wps_response=wps_response) return new_job
def test_one_literal_integer_input(self): def hello(request): pass hello_process = Process(hello, inputs=[LiteralInput('the_number', 'integer')]) result = self.describe_process(hello_process) assert result.inputs == [('the_number', 'literal', 'integer')]
def create_ultimate_question(): def handler(request, response): response.outputs['outvalue'].setvalue('42') return response return Process(identifier='ultimate_question', outputs=[LiteralOutput('outvalue', data_type='string')], handler=handler)
def __init__(self): inputs = [ ComplexInput('workflow', 'Workflow description', abstract='Workflow description in JSON.', metadata=[Metadata('Info')], min_occurs=1, max_occurs=1, supported_formats=[Format('application/json')]), ] outputs = [ ComplexOutput('output', 'Workflow result', abstract="Workflow result document in JSON.", as_reference=False, supported_formats=[Format('application/json')]), ComplexOutput('logfile', 'Workflow log file', abstract="Workflow log file.", as_reference=True, supported_formats=[Format('text/plain')]), ] Process.__init__( self, self._handler, identifier="custom_workflow", title="Custom Workflow", version="0.1", abstract="Runs custom workflow with dispel4py.", metadata=[ Metadata('Birdhouse', 'http://bird-house.github.io/'), Metadata('User Guide', 'http://malleefowl.readthedocs.io/en/latest/'), ], inputs=inputs, outputs=outputs, status_supported=True, store_supported=True, ) synch = Manager() self.full_log = synch.list() self.overall_progress = synch.dict() self.exceptions_list = synch.list() self.result_summary = synch.dict()
def create_ultimate_question(): def handler(request, response): response.outputs['outvalue'].data = '42' return response return Process(handler=handler, identifier='ultimate_question', title='Ultimate Question', outputs=[LiteralOutput('outvalue', 'Output Value', data_type='string')])
def test_one_literal_integer_input(self): def hello(request): pass hello_process = Process(hello, 'hello', 'Process Hello', inputs=[LiteralInput('the_number', 'Input number', data_type='positiveInteger')]) result = self.describe_process(hello_process) assert result.inputs == [('the_number', 'literal', 'positiveInteger')]
def create_greeter(): def greeter(request, response): name = request.inputs['name'] assert type(name) is text_type response.outputs['message'].setvalue("Hello %s!" % name) return response return Process(handler=greeter, inputs=[LiteralInput('name', data_type='string')], outputs=[LiteralOutput('message', data_type='string')])
def create_sum_one(): def sum_one(request, response): input = request.inputs['input'][0].file # What do we need to assert a Complex input? # assert type(input) is text_type import grass.script as grass # Import the raster and set the region if grass.run_command( "r.in.gdal", flags="o", out="input", input=input, quiet=True) != 0: raise NoApplicableCode("Could not import cost map. " "Please check the WCS service.") if grass.run_command("g.region", flags="a", rast="input") != 0: raise NoApplicableCode("Could not set GRASS region.") # Add 1 if grass.mapcalc("$output = $input + $value", output="output", input="input", value=1.0, quiet=True): raise NoApplicableCode("Could not use GRASS map calculator.") # Export the result _, out = tempfile.mkstemp() os.environ['GRASS_VERBOSE'] = '-1' if grass.run_command("r.out.gdal", flags="f", input="output", type="UInt16", output=out, overwrite=True) != 0: raise NoApplicableCode("Could not export result from GRASS.") del os.environ['GRASS_VERBOSE'] response.outputs['output'].file = out return response return Process(handler=sum_one, identifier='sum_one', title='Process Sum One', inputs=[ ComplexInput('input', title='Input', supported_formats=[Format('image/img')]) ], outputs=[ ComplexOutput('output', title='Output', supported_formats=[get_format('GEOTIFF')]) ], grass_location='epsg:4326')
def create_feature(): def feature(request, response): input = request.inputs['input'][0].file # What do we need to assert a Complex input? #assert type(input) is text_type # open the input file try: inSource = ogr.Open(input) except Exception as e: return "Could not open given vector file: %s" % e inLayer = inSource.GetLayer() # create output file out = 'point' outPath = os.path.join(tempfile.gettempdir(), out) driver = ogr.GetDriverByName('GML') outSource = driver.CreateDataSource( outPath, ["XSISCHEMAURI=http://schemas.opengis.net/gml/2.1.2/feature.xsd"]) outLayer = outSource.CreateLayer(out, None, ogr.wkbUnknown) # get the first feature inFeature = inLayer.GetNextFeature() inGeometry = inFeature.GetGeometryRef() # make the buffer buff = inGeometry.Buffer(float(100000)) # create output feature to the file outFeature = ogr.Feature(feature_def=outLayer.GetLayerDefn()) outFeature.SetGeometryDirectly(buff) outLayer.CreateFeature(outFeature) outFeature.Destroy() response.outputs['output'].output_format = Format( **FORMATS.GML._asdict()) response.outputs['output'].file = outPath return response return Process(handler=feature, identifier='feature', title='Process Feature', inputs=[ ComplexInput('input', 'Input', supported_formats=[get_format('GML')]) ], outputs=[ ComplexOutput('output', 'Output', supported_formats=[get_format('GML')]) ])
def create_greeter(): def greeter(request, response): name = request.inputs['name'][0].data assert type(name) is text_type response.outputs['message'].data = "Hello %s!" % name return response return Process(handler=greeter, identifier='greeter', title='Greeter', inputs=[LiteralInput('name', 'Input name', data_type='string')], outputs=[LiteralOutput('message', 'Output message', data_type='string')])
def test_json(self): new_process = Process.from_json(self.process.json) self.assertEqual(new_process.identifier, self.process.identifier) self.assertEqual(new_process.title, self.process.title) self.assertEqual(len(new_process.inputs), len(self.process.inputs)) new_inputs = { inpt.identifier: inpt.title for inpt in new_process.inputs } self.assertEqual("Length", new_inputs['length']) self.assertEqual("BBox", new_inputs["bbox"]) self.assertEqual("Vector", new_inputs["vector"])
def test_one_literal_string_input(self): def hello(request): pass hello_process = Process( hello, 'hello', 'Process Hello', inputs=[LiteralInput('the_name', 'Input name')], metadata=[Metadata('process metadata 1', 'http://example.org/1'), Metadata('process metadata 2', 'http://example.org/2')] ) result = self.describe_process(hello_process) assert result.inputs == [('the_name', 'literal', 'integer')] assert result.metadata == ['process metadata 1', 'process metadata 2']
def create_bbox_process(): def bbox_process(request, response): coords = request.inputs['mybbox'][0].data assert isinstance(coords, list) assert len(coords) == 4 assert coords[0] == '15' response.outputs['outbbox'].data = coords return response return Process(handler=bbox_process, identifier='my_bbox_process', title='Bbox process', inputs=[BoundingBoxInput('mybbox', 'Input name', ["EPSG:4326"])], outputs=[BoundingBoxOutput('outbbox', 'Output message', ["EPSG:4326"])])
def setUp(self): def handler(request, response): response.outputs['output'].data = '42' return response self.uuid = 1234 self.dummy_process = Process( handler=handler, identifier='dummy', title='Dummy Process', outputs=[LiteralOutput('output', 'Output', data_type='string')]) self.wps_request = WPSRequest() self.wps_response = ExecuteResponse(self.wps_request, self.uuid, process=self.dummy_process)
def create_greeter(): def greeter(request, response): name = request.inputs['name'][0].data assert isinstance(name, str) response.outputs['message'].data = "Hello {}!".format(name) return response return Process( handler=greeter, identifier='greeter', title='Greeter', inputs=[LiteralInput('name', 'Input name', data_type='string')], outputs=[ LiteralOutput('message', 'Output message', data_type='string') ])
def grass_epsg_based_location(): """Return a Process creating a GRASS location based on an EPSG code.""" def epsg_location(request, response): """Check whether the EPSG of a mapset corresponds the specified one.""" from grass.script import parse_command g_proj = parse_command('g.proj', flags='g') assert g_proj['epsg'] == '5514', \ 'Error in creating a GRASS location based on an EPSG code' return response return Process(handler=epsg_location, identifier='my_epsg_based_location', title='EPSG location', grass_location="EPSG:5514")
def create_translated_greeter(): def greeter(request, response): name = request.inputs['name'][0].data response.outputs['message'].data = "Hello {}!".format(name) return response return Process( handler=greeter, identifier='greeter', title='Greeter', abstract='Say hello', inputs=[ LiteralInput( 'name', 'Input name', data_type='string', abstract='Input description', translations={ "fr-CA": { "title": "Nom", "abstract": "Description" } }, ) ], outputs=[ LiteralOutput( 'message', 'Output message', data_type='string', abstract='Output description', translations={ "fr-CA": { "title": "Message de retour", "abstract": "Description" } }, ) ], translations={ "fr-CA": { "title": "Salutations", "abstract": "Dire allô" } }, )
def createProcess(): process = Process( handler, identifier='file_checker', inputs=[ LiteralInput('type', 'string'), LiteralInput('options', 'string'), ComplexInput('file', [Format('text/UTF-8')]), ], outputs=[ LiteralOutput('msg', data_type='string'), LiteralOutput('success', data_type='boolean') #,LiteralOutput('nij',data_type='string') #,LiteralOutput('bounds',data_type='string') #,BBoxOutput('bbox') ]) return process
def create_mimetype_process(): def _handler(request, response): response.outputs['mimetype'].data = response.outputs[ 'mimetype'].data_format.mime_type return response frmt_txt = Format(mime_type='text/plain') frmt_txt2 = Format(mime_type='text/plain+test') return Process(handler=_handler, identifier='get_mimetype_process', title='Get mimeType process', inputs=[], outputs=[ ComplexOutput('mimetype', 'mimetype of requested output', supported_formats=[frmt_txt, frmt_txt2]) ])
def create_complex_nc_process(): def complex_proces(request, response): from pywps.dependencies import netCDF4 as nc url = request.inputs['dods'][0].url with nc.Dataset(url) as D: response.outputs['conventions'].data = D.Conventions response.outputs['outdods'].url = url response.outputs['ncraw'].file = os.path.join(DATA_DIR, 'netcdf', 'time.nc') response.outputs['ncraw'].data_format = FORMATS.NETCDF return response return Process( handler=complex_proces, identifier='my_opendap_process', title='Opendap process', inputs=[ ComplexInput( 'dods', 'Opendap input', supported_formats=[Format('DODS'), Format('NETCDF')], # mode=MODE.STRICT ) ], outputs=[ LiteralOutput( 'conventions', 'NetCDF convention', ), ComplexOutput('outdods', 'Opendap output', supported_formats=[ FORMATS.DODS, ], as_reference=True), ComplexOutput('ncraw', 'NetCDF raw data output', supported_formats=[ FORMATS.NETCDF, ], as_reference=False) ])
def create_complex_proces(): def complex_proces(request, response): response.outputs['complex'].data = request.inputs['complex'][0].data return response frmt = Format(mime_type='application/gml') # this is unknown mimetype return Process(handler=complex_proces, identifier='my_complex_process', title='Complex process', inputs=[ ComplexInput('complex', 'Complex input', supported_formats=[frmt]) ], outputs=[ ComplexOutput('complex', 'Complex output', supported_formats=[frmt]) ])