def __call__(self, req): """WSGI application callable. Returns either a file download, directory listing or DAP response. """ path = os.path.abspath( os.path.join(self.path, *req.path_info.split("/"))) if not path.startswith(self.path): return HTTPForbidden() elif os.path.exists(path): if os.path.isdir(path): return self.index(path, req) else: return FileApp(path) # strip DAP extension (``.das``, eg) and see if the file exists base, ext = os.path.splitext(path) if os.path.isfile(base): req.environ["pydap.jinja2.environment"] = self.env app = ServerSideFunctions(get_handler(base, self.handlers)) return req.get_response(app) else: return HTTPNotFound(comment=path)
def ssf_app(): """Test the local implementation of server-side functions. Calling server-side functions is implemented using a lazy mechanism where arbitrary names are mapped to remove calls. The resulting dataset is only evaluated when ``__getitem__`` or ``__getattr__`` are called, allowing nested calls to be evaluated only once. """ from pydap.wsgi.ssf import ServerSideFunctions return ServerSideFunctions(BaseHandler(SimpleGrid))
def test_nested_projection(self): """Test a nested function call.""" app = TestApp(ServerSideFunctions(BaseHandler(SimpleGrid))) res = app.get("/.asc?mean(mean(SimpleGrid.SimpleGrid,0),0)") self.assertEqual(res.text, """Dataset { Float64 SimpleGrid; } SimpleGrid; --------------------------------------------- SimpleGrid 2.5 """)
def test_projection(self): """Test a simple function call on a projection.""" app = TestApp(ServerSideFunctions(BaseHandler(SimpleGrid))) res = app.get("/.asc?mean(x)") self.assertEqual(res.text, """Dataset { Float64 x; } SimpleGrid; --------------------------------------------- x 1 """)
def test_das(self): """Test that DAS requests are ignored.""" # create a simple app app = App(ServerSideFunctions(BaseHandler(SimpleSequence))) # test a DAS response with a non-existing function app.get("/.das?non_existing_function(sequence)") # now test a DDS response with self.assertRaises(KeyError): app.get("/.dds?non_existing_function(sequence)")
def test_projection_clash(self): """Test a function call creating a variable with a conflicting name.""" app = TestApp(ServerSideFunctions(BaseHandler(SimpleGrid))) res = app.get("/.asc?mean(x),x") self.assertEqual(res.text, """Dataset { Int32 x[x = 3]; } SimpleGrid; --------------------------------------------- x [0] 0 [1] 1 [2] 2 """)
def test_no_parsed_response(self): """Test that non-parsed responses work or raise error. pydap returns WSGI responses that contain the "parsed" dataset, so it can be manipulated by middleware. """ app = App(ServerSideFunctions(Accumulator(BaseHandler(SimpleGrid)))) # a normal request should work, even though server-side functions are # not working in the WSGI pipeline app.get("/.dds") # this will fail, since it's impossible to build the response with self.assertRaises(ServerError): app.get("/.dds?mean(x)")
def test_selection_no_comparison(self): """Test function calls in the selection without comparison. Some functions, like ``bounds``, have no comparison. In this case, the selection is implicitely applied by comparing the result to 1. """ app = App(ServerSideFunctions(BaseHandler(SimpleSequence))) res = app.get("/.asc?cast.lat,cast.lon&" "bounds(0,360,-90,0,0,500,00Z01JAN1900,00Z01JAN2000)") self.assertEqual( res.text, """Dataset { Sequence { Int32 lat; Int32 lon; } cast; } SimpleSequence; --------------------------------------------- cast.lat, cast.lon -10, 100 """)
def test_selection(self): """Test a selection server-side function.""" app = TestApp(ServerSideFunctions(BaseHandler(SimpleSequence))) res = app.get( "/.asc?density(cast.salinity,cast.temperature,cast.pressure)>1025") self.assertEqual(res.text, """Dataset { Sequence { String id; Int32 lon; Int32 lat; Int32 depth; Int32 time; Int32 temperature; Int32 salinity; Int32 pressure; } cast; } SimpleSequence; --------------------------------------------- cast.id, cast.lon, cast.lat, cast.depth, cast.time, cast.temperature, cast.salinity, cast.pressure "2", 200, 10, 500, 1, 15, 35, 100 """)
def test_wrong_type(self): """Test passing a wrong type to the function.""" app = TestApp(ServerSideFunctions(BaseHandler(SimpleGrid))) with self.assertRaises(ConstraintExpressionError): app.get('/.dds?SimpleGrid' '&bounds(0,360,-90,90,500,500,00Z01JAN1970,00Z01JAN1970)')
def setUp(self): """Create a simple WSGI app.""" self.app = TestApp(ServerSideFunctions(BaseHandler(SimpleSequence)))
def test_wrong_type(self): """Test passing a wrong type to mean function.""" app = TestApp(ServerSideFunctions(BaseHandler(SimpleSequence))) with self.assertRaises(ConstraintExpressionError): app.get('/.dds?mean(sequence)')
def setUp(self): """Create a simple WSGI app.""" self.app = App(ServerSideFunctions(BaseHandler(SimpleGrid)))
def test_operators(self): """Test different operators on selection using a dummy function.""" app = App( ServerSideFunctions(BaseHandler(SimpleSequence), double=double)) res = app.get("/.asc?cast.lat&double(cast.lat)>10") self.assertEqual( res.text, """Dataset { Sequence { Int32 lat; } cast; } SimpleSequence; --------------------------------------------- cast.lat 10 """) res = app.get("/.asc?cast.lat&double(cast.lat)>=20") self.assertEqual( res.text, """Dataset { Sequence { Int32 lat; } cast; } SimpleSequence; --------------------------------------------- cast.lat 10 """) res = app.get("/.asc?cast.lat&double(cast.lat)<10") self.assertEqual( res.text, """Dataset { Sequence { Int32 lat; } cast; } SimpleSequence; --------------------------------------------- cast.lat -10 """) res = app.get("/.asc?cast.lat&double(cast.lat)<=-20") self.assertEqual( res.text, """Dataset { Sequence { Int32 lat; } cast; } SimpleSequence; --------------------------------------------- cast.lat -10 """) res = app.get("/.asc?cast.lat&double(cast.lat)=20") self.assertEqual( res.text, """Dataset { Sequence { Int32 lat; } cast; } SimpleSequence; --------------------------------------------- cast.lat 10 """) res = app.get("/.asc?cast.lat&double(cast.lat)!=20") self.assertEqual( res.text, """Dataset { Sequence { Int32 lat; } cast; } SimpleSequence; --------------------------------------------- cast.lat -10 """)
def simple_application(simple_handler): from pydap.wsgi.ssf import ServerSideFunctions return ServerSideFunctions(simple_handler)
def test_wrong_type(self): """Test passing the wrong type.""" app = TestApp(ServerSideFunctions(BaseHandler(SimpleGrid))) with self.assertRaises(ConstraintExpressionError): app.get('/.dds?density(SimpleGrid,SimpleGrid,SimpleGrid)')
def test_grads_step(self): """Test different GrADS time steps.""" modified = copy.copy(SimpleSequence) modified.cast.time.attributes['grads_step'] = '1mn' app = TestApp(ServerSideFunctions(BaseHandler(modified))) res = app.get("/.asc?cast.pressure&" "bounds(0,360,-90,90,0,500,12Z01JAN1970,12Z01JAN1970)") self.assertEqual( res.text, """Dataset { Sequence { Int32 pressure; } cast; } SimpleSequence; --------------------------------------------- cast.pressure """) modified.cast.time.attributes['grads_step'] = '1hr' app = TestApp(ServerSideFunctions(BaseHandler(modified))) res = app.get("/.asc?cast.pressure&" "bounds(0,360,-90,90,0,500,12Z01JAN1970,12Z01JAN1970)") self.assertEqual( res.text, """Dataset { Sequence { Int32 pressure; } cast; } SimpleSequence; --------------------------------------------- cast.pressure """) modified.cast.time.attributes['grads_step'] = '1dy' app = TestApp(ServerSideFunctions(BaseHandler(modified))) res = app.get("/.asc?cast.pressure&" "bounds(0,360,-90,90,0,500,12Z01JAN1970,12Z01JAN1970)") self.assertEqual( res.text, """Dataset { Sequence { Int32 pressure; } cast; } SimpleSequence; --------------------------------------------- cast.pressure 100 """) modified.cast.time.attributes['grads_step'] = '1mo' app = TestApp(ServerSideFunctions(BaseHandler(modified))) with self.assertRaises(NotImplementedError): res = app.get( "/.asc?cast.pressure&" "bounds(0,360,-90,90,0,500,12Z01JAN1970,12Z01JAN1970)") modified.cast.time.attributes['grads_step'] = '1yr' app = TestApp(ServerSideFunctions(BaseHandler(modified))) with self.assertRaises(NotImplementedError): res = app.get( "/.asc?cast.pressure&" "bounds(0,360,-90,90,0,500,12Z01JAN1970,12Z01JAN1970)") modified.cast.time.attributes['grads_step'] = '1xx' app = TestApp(ServerSideFunctions(BaseHandler(modified))) with self.assertRaises(ServerError): res = app.get( "/.asc?cast.pressure&" "bounds(0,360,-90,90,0,500,12Z01JAN1970,12Z01JAN1970)")
def setUp(self): """Create a WSGI app to send requests to.""" self.app = ServerSideFunctions(BaseHandler(SimpleGrid))
raise OpenFileError(message) reader = csv.reader(fp, quoting=csv.QUOTE_NONNUMERIC) reader.next() # consume var names for row in reader: yield row fp.close() def __copy__(self): """Return a lightweight copy.""" return self.__class__(self.filepath, copy.copy(self.template), self.ifilter[:], self.imap[:], self.islice[:], self.level) def _test(): import doctest doctest.testmod() if __name__ == "__main__": import sys from werkzeug.serving import run_simple #_test() application = CSVHandler(sys.argv[1]) from pydap.wsgi.ssf import ServerSideFunctions application = ServerSideFunctions(application) run_simple('localhost', 8001, application, use_reloader=True)