def test_request_tile_init_tileargs_time(self): """ Test initialization of timesample arguments with a single time :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/0/1/1/' # Create the request dict request_args = { "service": "tile", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel1", "orientation": "xy", "tile_size": 512, "resolution": 2, "x_args": "0", "y_args": "0", "z_args": "1", "time_args": "1" } # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Tile().initialize_request(request) drfrequest.version = version ret = BossRequest(drfrequest, request_args) time = ret.get_time() self.assertEqual(time, range(1, 2))
def setUp(self): """Setup test by inserting data model items into the database""" dbsetup = SetupTestDB() user = dbsetup.create_user() self.client.force_login(user) dbsetup.insert_test_data() url = '/' + version + '/image/col1/exp1/channel1/xy/2/0:5/0:6/1/' # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version self.request_channel = BossRequest(drfrequest) # Setup Layer url = '/' + version + '/image/col1/exp1/layer1/xy/2/0:5/0:6/1/' # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version self.request_layer = BossRequest(drfrequest)
def test_request_ids_service(self): """ Test initialization of cutout requests for the datamodel :return: """ url = '/' + version + '/reserve/col1/exp1/layer1/10' col = 'col1' exp = 'exp1' channel = 'layer1' boss_key = 'col1&exp1&layer1' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Reserve().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "reserve", "version": version, "collection_name": col, "experiment_name": exp, "channel_name": channel, } ret = BossRequest(drfrequest, request_args) self.assertEqual(ret.get_collection(), col) self.assertEqual(ret.get_experiment(), exp) self.assertEqual(ret.get_channel(), channel) self.assertEqual(ret.get_boss_key(), boss_key)
def get(self, request, collection, experiment=None, channel=None): """ View to handle GET requests for metadata Args: request: DRF Request object collection: Collection Name experiment: Experiment name. default = None channel: Channel name Returns: """ try: # Validate the request and get the lookup Key if 'key' in request.query_params: key = request.query_params['key'] else: key = None # Create the request dict request_args = { "service": "meta", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, "key": key } req = BossRequest(request, request_args) lookup_key = req.get_lookup_key() except BossError as err: return err.to_http() if not lookup_key or lookup_key == "": return BossHTTPError("Invalid request. Unable to parse the datamodel arguments", ) if key is None: # List all keys that are valid for the query mdb = metadb.MetaDB() mdata = mdb.get_meta_list(lookup_key) keys = [] if mdata: for meta in mdata: keys.append(meta['key']) data = {'keys': keys} return Response(data) else: mkey = request.query_params['key'] mdb = metadb.MetaDB() mdata = mdb.get_meta(lookup_key, mkey) if mdata: data = {'key': mdata['key'], 'value': mdata['metavalue']} return Response(data) else: return BossHTTPError("Invalid request. Key {} Not found in the database".format(mkey), ErrorCodes.INVALID_POST_ARGUMENT)
def setUp(self): """Setup test by inserting data model items into the database""" self.rf = APIRequestFactory() dbsetup = SetupTestDB() self.user = dbsetup.create_user() dbsetup.add_role("resource-manager", self.user) self.client.force_login(self.user) dbsetup.insert_cloudvolume_test_data() url = '/' + version + '/cutout/col1/exp1/chan1/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "chan1", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_channel = BossRequest(drfrequest, request_args) # Setup Layer url = '/' + version + '/cutout/col1/exp1/anno1/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "anno1", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_annotation = BossRequest(drfrequest, request_args)
def test_bossrequest_init_layer(self): """ Test initialization of requests from the meta data service with a valid collection and experiment and layer """ # create the request with collection name and experiment name and channel name url = '/' + version + '/meta/col1/exp1/layer1/?key=mkey&value=TestValue' expected_col = 'col1' expected_exp = 'exp1' expected_layer = 'layer1' expected_bosskey = 'col1&exp1&layer1' expected_key = 'mkey' expected_value = 'TestValue' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version # Datamodel object ret = BossRequest(drfrequest) self.assertEqual(ret.get_collection(), expected_col) self.assertEqual(ret.get_experiment(), expected_exp) self.assertEqual(ret.get_channel_layer(), expected_layer) # Boss key boss_key = ret.get_boss_key() self.assertEqual(boss_key, expected_bosskey) # Key and value key = ret.get_key() self.assertEqual(key, expected_key) value = ret.get_value() self.assertEqual(value, expected_value)
def post(self, request, collection, experiment=None, channel=None): """ View to handle POST requests for metadata Args: request: DRF Request object collection: Collection Name specifying the collection you want to get the meta data for experiment: Experiment name. default = None channel: Channel name. Default = None Returns: """ if 'key' not in request.query_params or 'value' not in request.query_params: return BossHTTPError( "Missing optional argument key/value in the request", ErrorCodes.INVALID_POST_ARGUMENT) try: # Create the request dict request_args = { "service": "meta", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, "key": request.query_params['key'], "value": request.query_params['value'] } req = BossRequest(request, request_args) lookup_key = req.get_lookup_key() except BossError as err: return err.to_http() if not lookup_key: return BossHTTPError( "Invalid request. Unable to parse the datamodel arguments", ErrorCodes.INVALID_POST_ARGUMENT) mkey = request.query_params['key'] value = request.query_params['value'] # Post Metadata the dynamodb database mdb = metadb.MetaDB() if mdb.get_meta(lookup_key, mkey): return BossHTTPError( "Invalid request. The key {} already exists".format(mkey), ErrorCodes.INVALID_POST_ARGUMENT) mdb.write_meta(lookup_key, mkey, value) return HttpResponse(status=201)
def test_request_tile_init_tileargs_time(self): """ Test initialization of timesample arguments with a single time :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/0/1/1/' # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version ret = BossRequest(drfrequest) time = ret.get_time() self.assertEqual(time, range(1, 2))
def get(self, request, collection, experiment=None, channel_layer=None): """ View to handle GET requests for metadata Args: request: DRF Request object collection: Collection Name experiment: Experiment name. default = None channel_layer: Channel or Layer name Returns: """ try: # Validate the request and get the lookup Key req = BossRequest(request) lookup_key = req.get_lookup_key() except BossError as err: return err.to_http() if not lookup_key or lookup_key == "": return BossHTTPError( "Invalid request. Unable to parse the datamodel arguments", ) if 'key' not in request.query_params: # List all keys that are valid for the query mdb = metadb.MetaDB() mdata = mdb.get_meta_list(lookup_key) keys = [] if mdata: for meta in mdata: keys.append(meta['key']) data = {'keys': keys} return Response(data) else: mkey = request.query_params['key'] mdb = metadb.MetaDB() mdata = mdb.get_meta(lookup_key, mkey) if mdata: data = {'key': mdata['key'], 'value': mdata['metavalue']} return Response(data) else: return BossHTTPError( "Invalid request. Key {} Not found in the database".format( mkey), ErrorCodes.INVALID_POST_ARGUMENT)
def test_request_ids_service_invalid_channel_type(self): """ Test initialization of cutout requests for the datamodel :return: """ url = '/' + version + '/reserve/col1/exp1/channel1/10' col = 'col1' exp = 'exp1' channel = 'channel' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Reserve().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "reserve", "version": version, "collection_name": col, "experiment_name": exp, "channel_name": channel, } with self.assertRaises(BossError): ret = BossRequest(drfrequest, request_args)
def test_bounding_box_service_invalid_resolution(self): """ Test initialization of cutout requests for the datamodel :return: """ url = '/' + version + '/boundingbox/col1/exp1/layer1/25/10' col = 'col1' exp = 'exp1' channel = 'layer1' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Reserve().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "boundingbox", "version": version, "collection_name": col, "experiment_name": exp, "channel_name": channel, "resolution": 25, "id": 10 } with self.assertRaises(BossError): ret = BossRequest(drfrequest, request_args)
def test_basic_resource_get_downsampled_extent_dims_isotropic(self): """Test downsample extent isotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_iso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_iso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) extent_dims = resource.get_downsampled_extent_dims() self.assertEqual(len(extent_dims), 8) self.assertEqual(extent_dims[0], [2000, 5000, 200]) self.assertEqual(extent_dims[1], [1000, 2500, 100]) self.assertEqual(extent_dims[3], [250, 625, 25])
def test_request_tile_invalid_orientation(self): """ Test initialization of tile arguments for a invalid tile request. Unrecognized orientation :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xe/512/2/0/1/1/1/' # Create the request dict request_args = { "service": "tile", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel1", "orientation": "xe", "tile_size": 512, "resolution": 2, "x_args": "0", "y_args": "0", "z_args": "1", "time_args": "1" } # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Tile().initialize_request(request) drfrequest.version = version with self.assertRaises(BossError): BossRequest(drfrequest, request_args)
def test_bossrequest_channel_not_found(self): """ Test initialization of requests with a channel that does not exist """ # create the request url = '/' + version + '/meta/col1/exp1/channel2/?key=mkey' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "user": self.user, "method": request.method, "service": "meta", "version": version, "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel2", "key": "mkey", "value": None } try: BossRequest(drfrequest,request_args) except BossError as err: assert err.args[0] == 404
def test_basic_resource_get_iso_level_isotropic(self): """Test get iso level isotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_iso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_iso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) self.assertEqual(resource.get_isotropic_level(), 0)
def post(self, request, collection, experiment, channel): """View to kick off a channel's downsample process Args: request: DRF Request object collection (str): Unique Collection identifier, indicating which collection you want to access experiment (str): Experiment identifier, indicating which experiment you want to access channel (str): Channel identifier, indicating which channel you want to access Returns: """ # Process request and validate try: request_args = { "service": "downsample", "collection_name": collection, "experiment_name": experiment, "channel_name": channel } req = BossRequest(request, request_args) except BossError as err: return err.to_http() # Convert to Resource resource = project.BossResourceDjango(req) return start(request, resource)
def post(self, request, collection, experiment=None, channel=None): """ View to handle POST requests for metadata Args: request: DRF Request object collection: Collection Name specifying the collection you want to get the meta data for experiment: Experiment name. default = None channel: Channel name. Default = None Returns: """ if 'key' not in request.query_params or 'value' not in request.query_params: return BossHTTPError("Missing optional argument key/value in the request", ErrorCodes.INVALID_POST_ARGUMENT) try: # Create the request dict request_args = { "service": "meta", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, "key": request.query_params['key'], "value": request.query_params['value'] } req = BossRequest(request, request_args) lookup_key = req.get_lookup_key() except BossError as err: return err.to_http() if not lookup_key: return BossHTTPError("Invalid request. Unable to parse the datamodel arguments", ErrorCodes.INVALID_POST_ARGUMENT) mkey = request.query_params['key'] value = request.query_params['value'] # Post Metadata the dynamodb database mdb = metadb.MetaDB() if mdb.get_meta(lookup_key, mkey): return BossHTTPError("Invalid request. The key {} already exists".format(mkey), ErrorCodes.INVALID_POST_ARGUMENT) mdb.write_meta(lookup_key, mkey, value) return HttpResponse(status=201)
def delete(self, request, collection, experiment=None, channel=None): """ View to handle the delete requests for metadata Args: request: DRF Request object collection: Collection name. Default = None experiment: Experiment name. Default = None channel: Channel name . Default = None Returns: """ if 'key' not in request.query_params: return BossHTTPError( "Missing optional argument key in the request", ErrorCodes.INVALID_POST_ARGUMENT) try: # Create the request dict request_args = { "service": "meta", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, "key": request.query_params['key'], } req = BossRequest(request, request_args) lookup_key = req.get_lookup_key() except BossError as err: return err.to_http() if not lookup_key: return BossHTTPError( "Invalid request. Unable to parse the datamodel arguments", ErrorCodes.INVALID_POST_ARGUMENT) mkey = request.query_params['key'] # Delete metadata from the dynamodb database mdb = metadb.MetaDB() response = mdb.delete_meta(lookup_key, mkey) if 'Attributes' in response: return HttpResponse(status=204) else: return BossHTTPError("[ERROR]- Key {} not found ".format(mkey), ErrorCodes.INVALID_POST_ARGUMENT)
def test_request_tile_init_channel(self): """ Test initialization of tile requests for the datamodel with a channel :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/0/1' col = 'col1' exp = 'exp1' channel = 'channel1' boss_key = 'col1&exp1&channel1' boss_key_list = 'col1&exp1&channel1&2&0' # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version ret = BossRequest(drfrequest) self.assertEqual(ret.get_collection(), col) self.assertEqual(ret.get_experiment(), exp) self.assertEqual(ret.get_channel_layer(), channel) self.assertEqual(ret.get_boss_key(), boss_key) self.assertEqual(ret.get_boss_key_list()[0], boss_key_list)
def delete(self, request, collection, experiment=None, channel=None): """ View to handle the delete requests for metadata Args: request: DRF Request object collection: Collection name. Default = None experiment: Experiment name. Default = None channel: Channel name . Default = None Returns: """ if 'key' not in request.query_params: return BossHTTPError("Missing optional argument key in the request", ErrorCodes.INVALID_POST_ARGUMENT) try: # Create the request dict request_args = { "service": "meta", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, "key": request.query_params['key'], } req = BossRequest(request, request_args) lookup_key = req.get_lookup_key() except BossError as err: return err.to_http() if not lookup_key: return BossHTTPError("Invalid request. Unable to parse the datamodel arguments", ErrorCodes.INVALID_POST_ARGUMENT) mkey = request.query_params['key'] # Delete metadata from the dynamodb database mdb = metadb.MetaDB() response = mdb.delete_meta(lookup_key, mkey) if 'Attributes' in response: return HttpResponse(status=204) else: return BossHTTPError("[ERROR]- Key {} not found ".format(mkey), ErrorCodes.INVALID_POST_ARGUMENT)
def delete(self, request, collection, experiment, channel): """View to cancel an in-progress downsample operation Args: request: DRF Request object collection (str): Unique Collection identifier, indicating which collection you want to access experiment (str): Experiment identifier, indicating which experiment you want to access channel (str): Channel identifier, indicating which channel you want to access Returns: """ # Process request and validate try: request_args = { "service": "downsample", "collection_name": collection, "experiment_name": experiment, "channel_name": channel } req = BossRequest(request, request_args) except BossError as err: return err.to_http() # Convert to Resource resource = project.BossResourceDjango(req) channel = resource.get_channel() if channel.downsample_status.upper() != "IN_PROGRESS": return BossHTTPError( "You can only cancel and in-progress downsample operation.", ErrorCodes.INVALID_STATE) # Get Channel object lookup_key = resource.get_lookup_key() _, exp_id, _ = lookup_key.split("&") channel_obj = Channel.objects.get(name=channel.name, experiment=int(exp_id)) # Call cancel on the Step Function session = bossutils.aws.get_session() bossutils.aws.sfn_cancel( session, channel_obj.downsample_arn, error="User Cancel", cause="User has requested the downsample operation to stop.") # Clear ARN channel_obj.downsample_arn = "" # Change Status channel_obj.downsample_status = "NOT_DOWNSAMPLED" channel_obj.save() return HttpResponse(status=204)
def test_request_tile_bosskey_time(self): """ Test initialization of boss_key for a time sample range :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/0/1/' exp_boss_keys = ['col1&exp1&channel1&2&0'] # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version ret = BossRequest(drfrequest) boss_keys = ret.get_boss_key_list() self.assertEqual(boss_keys, exp_boss_keys) url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/0/1/1/' exp_boss_keys = ['col1&exp1&channel1&2&1'] # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version ret = BossRequest(drfrequest) boss_keys = ret.get_boss_key_list() self.assertEqual(boss_keys, exp_boss_keys)
def test_collection_init(self): """ Test initialization of requests from the meta data service with collection :return: """ # create the request with collection name # log in user url = '/' + version + '/meta/col1/?key=mkey&value=TestValue' expected_col = 'col1' expected_bosskey = 'col1' expected_key = 'mkey' expected_value = 'TestValue' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version # Datamodel object ret = BossRequest(drfrequest) self.assertEqual(ret.get_collection(), expected_col) # Boss key boss_key = ret.get_boss_key() self.assertEqual(boss_key, expected_bosskey) # Key and value key = ret.get_key() self.assertEqual(key, expected_key) value = ret.get_value() self.assertEqual(value, expected_value)
def test_bossrequest_init_coordinateframe(self): """ Test initialization of requests from the meta data service with a valid collection and experiment and dataset """ # create the request url = '/' + version + '/meta/col1/exp1/channel1/?key=mkey' expected_col = 'col1' expected_exp = 'exp1' expected_channel = 'channel1' expected_coord = 'cf1' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "user": self.user, "method": request.method, "service": "meta", "version": version, "collection_name": expected_col, "experiment_name": expected_exp, "channel_name": expected_channel, "key": "mkey", } ret = BossRequest(drfrequest, request_args) # Data model objects self.assertEqual(ret.get_collection(), expected_col) self.assertEqual(ret.get_experiment(), expected_exp) self.assertEqual(ret.get_channel(), expected_channel) # Check coordinate frame self.assertEqual(ret.get_coordinate_frame(), expected_coord)
def put(self, request, collection, experiment=None, channel_layer=None): """ View to handle update requests for metadata Args: request: DRF Request object collection: Collection Name. Default = None experiment: Experiment Name. Default = None channel_layer: Channel Name Default + None Returns: """ if 'key' not in request.query_params or 'value' not in request.query_params: return BossHTTPError( "Missing optional argument key/value in the request", ErrorCodes.INVALID_POST_ARGUMENT) try: req = BossRequest(request) lookup_key = req.get_lookup_key() except BossError as err: return err.to_http() if not lookup_key: return BossHTTPError( "Invalid request. Unable to parse the datamodel arguments", ErrorCodes.INVALID_POST_ARGUMENT) mkey = request.query_params['key'] value = request.query_params['value'] # Post Metadata the dynamodb database mdb = metadb.MetaDB() if not mdb.get_meta(lookup_key, mkey): return BossHTTPError( "Invalid request. The key {} does not exists".format(mkey), ErrorCodes.INVALID_POST_ARGUMENT) mdb.update_meta(lookup_key, mkey, value) return HttpResponse(status=200)
def test_bossrequest_init_channel(self): """ Test initialization of requests from the meta data service with a valid collection and experiment and channel """ # create the request url = '/' + version + '/meta/col1/exp1/channel1/?key=mkey&value=TestValue' expected_col = 'col1' expected_exp = 'exp1' expected_channel = 'channel1' expected_bosskey = 'col1&exp1&channel1' expected_key = 'mkey' expected_value = 'TestValue' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "user": self.user, "method": request.method, "service": "meta", "version": version, "collection_name": expected_col, "experiment_name": expected_exp, "channel_name": expected_channel, "key": "mkey", "value": "TestValue" } # Data model Objects ret = BossRequest(drfrequest, request_args) self.assertEqual(ret.get_collection(), expected_col) self.assertEqual(ret.get_experiment(), expected_exp) self.assertEqual(ret.get_channel(), expected_channel) # Boss key boss_key = ret.get_boss_key() self.assertEqual(boss_key, expected_bosskey) # Key and value key = ret.get_key() self.assertEqual(key, expected_key) value = ret.get_value() self.assertEqual(value, expected_value)
def test_request_tile_init_channel(self): """ Test initialization of tile requests for the datamodel with a channel :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/0/1' col = 'col1' exp = 'exp1' channel = 'channel1' boss_key = 'col1&exp1&channel1' # Create the request dict request_args = { "service": "tile", "collection_name": col, "experiment_name": exp, "channel_name": channel, "orientation": "xy", "tile_size": 512, "resolution": 2, "x_args": "0", "y_args": "0", "z_args": "1", "time_args": None } # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Tile().initialize_request(request) drfrequest.version = version ret = BossRequest(drfrequest, request_args) self.assertEqual(ret.get_collection(), col) self.assertEqual(ret.get_experiment(), exp) self.assertEqual(ret.get_channel(), channel) self.assertEqual(ret.get_boss_key(), boss_key)
def test_request_tile_invalid_orientation(self): """ Test initialization of tile arguments for a invalid tile request. Unrecognized orientation :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xe/512/2/0/1/1/1/' # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version with self.assertRaises(BossError): BossRequest(drfrequest)
def test_bossrequest_experiment_not_found(self): """ Test initialization of requests with a experiment that does not exist """ # create the request url = '/' + version + '/meta/col1/exp2/?key=mkey' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version try: BossRequest(drfrequest) except BossError as err: assert err.status_code == 404
def get(self, request, collection, experiment,channel, resolution, x_range, y_range, z_range, t_range=None): """ Return a list of ids in the spatial region. Args: request: DRF Request object collection: Collection name specifying the collection you want experiment: Experiment name specifying the experiment channel: Channel_name num_ids: Number of id you want to reserve Returns: JSON dict with start_id and count of ids reserved Raises: BossHTTPError for an invalid request """ # validate resource # permissions? # Check if this is annotation channel # Process request and validate try: request_args = { "service": "ids", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, "resolution": resolution, "x_args": x_range, "y_args": y_range, "z_args": z_range, "time_args": t_range } req = BossRequest(request, request_args) except BossError as err: return err.to_http() # create a resource resource = project.BossResourceDjango(req) # Get the params to pull data out of the cache corner = (req.get_x_start(), req.get_y_start(), req.get_z_start()) extent = (req.get_x_span(), req.get_y_span(), req.get_z_span()) try: # Reserve ids spdb = SpatialDB(settings.KVIO_SETTINGS, settings.STATEIO_CONFIG, settings.OBJECTIO_CONFIG) ids = spdb.get_ids_in_region(resource, int(resolution), corner, extent) return Response(ids, status=200) except (TypeError, ValueError) as e: return BossHTTPError("Type error in the ids view. {}".format(e), ErrorCodes.TYPE_ERROR)
def test_request_tile_invalid_zargs(self): """ Test initialization of tile arguments for a invalid tile request. The z-args are outside the coordinate frame :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/1/7000/1/' # Create the request req = HttpRequest() req.META = {'PATH_INFO': url} drfrequest = Request(req) drfrequest.version = version with self.assertRaises(BossError): BossRequest(drfrequest)
def test_bossrequest_channel_layer_not_found(self): """ Test initialization of requests with a channel that does not exist """ # create the request url = '/' + version + '/meta/col1/exp1/channel2/?key=mkey' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version try: BossRequest(drfrequest) except BossError as err: assert err.args[0] == 404
def get(self, request, collection, experiment, channel, num_ids): """ Reserve a unique, sequential list of annotation ids for the provided channel to use as object ids for annotations. Args: request: DRF Request object collection: Collection name specifying the collection you want experiment: Experiment name specifying the experiment channel: Channel_name num_ids: Number of id you want to reserve Returns: JSON dict with start_id and count of ids reserved Raises: BossHTTPError for an invalid request """ # validate resource # permissions? # validate that num_ids is an int # Check if this is annotation channel try: request_args = { "service": "reserve", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, } req = BossRequest(request, request_args) except BossError as err: return err.to_http() # create a resource resource = project.BossResourceDjango(req) try: # Reserve ids spdb = SpatialDB(settings.KVIO_SETTINGS, settings.STATEIO_CONFIG, settings.OBJECTIO_CONFIG) start_id = spdb.reserve_ids(resource, int(num_ids)) data = {'start_id': start_id[0], 'count': num_ids} return Response(data, status=200) except (TypeError, ValueError) as e: return BossHTTPError( "Type error in the reserve id view. {}".format(e), ErrorCodes.TYPE_ERROR)
def test_collection_special_char_dash(self): """ Test initialization of requests from the meta data service with collection that has a dash in the name :return: """ # create the request with collection name # log in user url = '/' + version + '/meta/col1-22/?key=mkey&value=TestValue' expected_col = 'col1-22' expected_bosskey = 'col1-22' expected_key = 'mkey' expected_value = 'TestValue' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "user": self.user, "method": request.method, "service": "meta", "version": version, "collection_name": expected_col, "experiment_name": None, "channel_name": None, "key": "mkey", "value": "TestValue" } # Datamodel object ret = BossRequest(drfrequest, request_args) self.assertEqual(ret.get_collection(), expected_col) # Boss key boss_key = ret.get_boss_key() self.assertEqual(boss_key, expected_bosskey) # Key and value key = ret.get_key() self.assertEqual(key, expected_key) value = ret.get_value() self.assertEqual(value, expected_value)
def test_basic_resource_get_downsampled_voxel_dims_anisotropic_iso(self): """Test downsample voxel dims anisotropic with iso flag Returns: None """ url = '/' + version + '/cutout/col1/exp_aniso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_aniso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) voxel_dims = resource.get_downsampled_voxel_dims(iso=True) self.assertEqual(len(voxel_dims), 8) self.assertEqual(voxel_dims[0], [4, 4, 35]) self.assertEqual(voxel_dims[1], [8, 8, 35]) self.assertEqual(voxel_dims[2], [16, 16, 35]) self.assertEqual(voxel_dims[3], [32, 32, 35]) self.assertEqual(voxel_dims[4], [64, 64, 70]) self.assertEqual(voxel_dims[5], [128, 128, 140])
def test_bossrequest_list_all_keys(self): """ Test initialization of requests from the meta data service with a valid collection and experiment and channel """ # create the request url = '/' + version + '/meta/col1/exp1/channel1/' expected_col = 'col1' expected_exp = 'exp1' expected_channel = 'channel1' expected_coord = 'cf1' request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = BossMeta().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "user": self.user, "method": request.method, "service": "meta", "version": version, "collection_name": expected_col, "experiment_name": expected_exp, "channel_name": expected_channel, "key": None, "value": None } ret = BossRequest(drfrequest, request_args) # Data model objects self.assertEqual(ret.get_collection(), expected_col) self.assertEqual(ret.get_experiment(), expected_exp) self.assertEqual(ret.get_channel(), expected_channel) # Key and value should be empty self.assertEqual(ret.get_key(), None) self.assertEqual(ret.get_value(), None)
def setUp(self): """Setup test by inserting data model items into the database""" self.rf = APIRequestFactory() dbsetup = SetupTestDB() self.user = dbsetup.create_user() dbsetup.add_role("resource-manager", self.user) self.client.force_login(self.user) dbsetup.insert_test_data() dbsetup.insert_iso_data() url = '/' + version + '/collection/col1/experiment/exp1/channel/channel33/' data = {'description': 'This is a new channel', 'type': 'annotation', 'datatype': 'uint8', 'sources': ['channel1'], 'related': ['channel2', 'channel3']} response = self.client.post(url, data=data) url = '/' + version + '/cutout/col1/exp1/channel1/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel1", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_channel = BossRequest(drfrequest, request_args) # Setup Layer url = '/' + version + '/cutout/col1/exp1/layer1/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "layer1", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_annotation = BossRequest(drfrequest, request_args) url = '/' + version + '/cutout/col1/exp1/channel33/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel33", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_channel_links = BossRequest(drfrequest, request_args)
class TestDjangoResource(APITestCase): def setUp(self): """Setup test by inserting data model items into the database""" self.rf = APIRequestFactory() dbsetup = SetupTestDB() self.user = dbsetup.create_user() dbsetup.add_role("resource-manager", self.user) self.client.force_login(self.user) dbsetup.insert_test_data() dbsetup.insert_iso_data() url = '/' + version + '/collection/col1/experiment/exp1/channel/channel33/' data = {'description': 'This is a new channel', 'type': 'annotation', 'datatype': 'uint8', 'sources': ['channel1'], 'related': ['channel2', 'channel3']} response = self.client.post(url, data=data) url = '/' + version + '/cutout/col1/exp1/channel1/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel1", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_channel = BossRequest(drfrequest, request_args) # Setup Layer url = '/' + version + '/cutout/col1/exp1/layer1/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "layer1", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_annotation = BossRequest(drfrequest, request_args) url = '/' + version + '/cutout/col1/exp1/channel33/2/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version # Create the request dict request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel33", "resolution": 2, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } self.request_channel_links = BossRequest(drfrequest, request_args) def test_django_resource_col(self): """Test basic get collection interface Returns: None """ resource = BossResourceDjango(self.request_channel) col = resource.get_collection() assert col.name == self.request_channel.collection.name assert col.description == self.request_channel.collection.description def test_django_resource_coord_frame(self): """Test basic get coordinate frame interface Returns: None """ resource = BossResourceDjango(self.request_channel) coord = resource.get_coord_frame() assert coord.name == self.request_channel.coord_frame.name assert coord.description == self.request_channel.coord_frame.description assert coord.x_start == self.request_channel.coord_frame.x_start assert coord.x_stop == self.request_channel.coord_frame.x_stop assert coord.y_start == self.request_channel.coord_frame.y_start assert coord.y_stop == self.request_channel.coord_frame.y_stop assert coord.z_start == self.request_channel.coord_frame.z_start assert coord.z_stop == self.request_channel.coord_frame.z_stop assert coord.x_voxel_size == self.request_channel.coord_frame.x_voxel_size assert coord.y_voxel_size == self.request_channel.coord_frame.y_voxel_size assert coord.z_voxel_size == self.request_channel.coord_frame.z_voxel_size assert coord.voxel_unit == self.request_channel.coord_frame.voxel_unit def test_django_resource_experiment(self): """Test basic get experiment interface Returns: None """ resource = BossResourceDjango(self.request_channel) exp = resource.get_experiment() assert exp.name == self.request_channel.experiment.name assert exp.description == self.request_channel.experiment.description assert exp.num_hierarchy_levels == self.request_channel.experiment.num_hierarchy_levels assert exp.hierarchy_method == self.request_channel.experiment.hierarchy_method assert exp.time_step == self.request_channel.experiment.time_step assert exp.time_step_unit == self.request_channel.experiment.time_step_unit def test_django_resource_channel_image(self): """Test basic get channel interface Returns: None """ resource = BossResourceDjango(self.request_channel) channel = resource.get_channel() assert channel.is_image() is True assert channel.name == self.request_channel.channel.name assert channel.description == self.request_channel.channel.description assert channel.datatype == self.request_channel.channel.datatype assert channel.type == self.request_channel.channel.type assert channel.base_resolution == self.request_channel.channel.base_resolution assert channel.default_time_sample == self.request_channel.channel.default_time_sample assert channel.related == [] assert channel.sources == [] def test_django_resource_channel_annotation(self): """Test basic get channel when an annotation interface Returns: None """ resource = BossResourceDjango(self.request_annotation) channel = resource.get_channel() assert channel.is_image() is False assert channel.name == self.request_annotation.channel.name assert channel.description == self.request_annotation.channel.description assert channel.datatype == self.request_annotation.channel.datatype assert channel.type == self.request_annotation.channel.type assert channel.base_resolution == self.request_annotation.channel.base_resolution assert channel.default_time_sample == self.request_annotation.channel.default_time_sample assert channel.related == [] assert channel.sources == ['channel1'] def test_django_resource_channel_image_with_links(self): """Test basic get channel interface Returns: None """ resource = BossResourceDjango(self.request_channel_links) channel = resource.get_channel() assert channel.is_image() is False assert channel.name == self.request_channel_links.channel.name assert channel.description == self.request_channel_links.channel.description assert channel.datatype == self.request_channel_links.channel.datatype assert channel.type == self.request_channel_links.channel.type assert channel.base_resolution == self.request_channel_links.channel.base_resolution assert channel.default_time_sample == self.request_channel_links.channel.default_time_sample assert channel.related == ['channel2', 'channel3'] assert channel.sources == ['channel1'] def test_django_resource_get_boss_key(self): """Test basic get boss key interface Returns: None """ resource = BossResourceDjango(self.request_channel) assert resource.get_boss_key() == self.request_channel.get_boss_key() assert resource.get_boss_key() == 'col1&exp1&channel1' def test_django_resource_get_lookup_key(self): """Test basic get lookup key interface Returns: None """ resource = BossResourceDjango(self.request_channel) assert resource.get_lookup_key() == self.request_channel.get_lookup_key() assert isinstance(resource.get_lookup_key(), str) def test_django_resource_get_data_type(self): """Test basic get datatype interface Returns: None """ resource = BossResourceDjango(self.request_channel) assert resource.get_data_type() == self.request_channel.channel.datatype def test_django_resource_to_dict_channel(self): """Test basic get to dict interface for images Returns: None """ resource = BossResourceDjango(self.request_channel) data = resource.to_dict() assert "channel" in data assert "collection" in data assert "experiment" in data assert "lookup_key" in data assert "boss_key" in data assert "coord_frame" in data def test_django_resource_to_dict_annotation(self): """Test basic get to dict interface for annotations Returns: None """ resource = BossResourceDjango(self.request_annotation) data = resource.to_dict() assert "channel" in data assert "collection" in data assert "experiment" in data assert "lookup_key" in data assert "boss_key" in data assert "coord_frame" in data def test_basic_resource_get_iso_level_anisotropic(self): """Test get iso level anisotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_aniso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_aniso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) self.assertEqual(resource.get_isotropic_level(), 3) def test_basic_resource_get_iso_level_isotropic(self): """Test get iso level isotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_iso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_iso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) self.assertEqual(resource.get_isotropic_level(), 0) def test_basic_resource_get_downsampled_voxel_dims_anisotropic(self): """Test downsample voxel dims anisotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_aniso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_aniso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) voxel_dims = resource.get_downsampled_voxel_dims() self.assertEqual(len(voxel_dims), 8) self.assertEqual(voxel_dims[0], [4, 4, 35]) self.assertEqual(voxel_dims[4], [64, 64, 35]) def test_basic_resource_get_downsampled_voxel_dims_anisotropic_iso(self): """Test downsample voxel dims anisotropic with iso flag Returns: None """ url = '/' + version + '/cutout/col1/exp_aniso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_aniso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) voxel_dims = resource.get_downsampled_voxel_dims(iso=True) self.assertEqual(len(voxel_dims), 8) self.assertEqual(voxel_dims[0], [4, 4, 35]) self.assertEqual(voxel_dims[1], [8, 8, 35]) self.assertEqual(voxel_dims[2], [16, 16, 35]) self.assertEqual(voxel_dims[3], [32, 32, 35]) self.assertEqual(voxel_dims[4], [64, 64, 70]) self.assertEqual(voxel_dims[5], [128, 128, 140]) def test_basic_resource_get_downsampled_voxel_dims_isotropic(self): """Test downsample voxel dims isotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_iso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_iso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) voxel_dims = resource.get_downsampled_voxel_dims() self.assertEqual(len(voxel_dims), 8) self.assertEqual(voxel_dims[0], [6, 6, 6]) self.assertEqual(voxel_dims[3], [48, 48, 48]) def test_basic_resource_get_downsampled_extent_dims_anisotropic(self): """Test downsample extent anisotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_aniso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_aniso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) extent_dims = resource.get_downsampled_extent_dims() self.assertEqual(len(extent_dims), 8) self.assertEqual(extent_dims[0], [2000, 5000, 200]) self.assertEqual(extent_dims[4], [125, 313, 200]) def test_basic_resource_get_downsampled_extent_dims_anisotropic_iso(self): """Test downsample extent anisotropic with isotropic flag Returns: None """ url = '/' + version + '/cutout/col1/exp_aniso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_aniso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) extent_dims = resource.get_downsampled_extent_dims(iso=True) self.assertEqual(len(extent_dims), 8) self.assertEqual(extent_dims[0], [2000, 5000, 200]) self.assertEqual(extent_dims[3], [250, 625, 200]) self.assertEqual(extent_dims[4], [125, 313, 100]) def test_basic_resource_get_downsampled_extent_dims_isotropic(self): """Test downsample extent isotropic Returns: None """ url = '/' + version + '/cutout/col1/exp_iso/channel1/0/0:5/0:6/0:2/' # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Cutout().initialize_request(request) drfrequest.version = version request_args = { "service": "cutout", "collection_name": "col1", "experiment_name": "exp_iso", "channel_name": "channel1", "resolution": 0, "x_args": "0:5", "y_args": "0:6", "z_args": "0:2", "time_args": None } req = BossRequest(drfrequest, request_args) resource = BossResourceDjango(req) extent_dims = resource.get_downsampled_extent_dims() self.assertEqual(len(extent_dims), 8) self.assertEqual(extent_dims[0], [2000, 5000, 200]) self.assertEqual(extent_dims[1], [1000, 2500, 100]) self.assertEqual(extent_dims[3], [250, 625, 25])
def test_request_tile_init_tileargs_channel(self): """ Test initialization of tile arguments for a tile request for a channel :return: """ url = '/' + version + '/tile/col1/exp1/channel1/xy/512/2/0/0/1' res = 2 (x_start, x_stop) = (0, 512) (y_start, y_stop) = (0, 512) (z_start, z_stop) = (1, 2) # Create the request dict request_args = { "service": "tile", "collection_name": "col1", "experiment_name": "exp1", "channel_name": "channel1", "orientation": "xy", "tile_size": 512, "resolution": 2, "x_args": "0", "y_args": "0", "z_args": "1", "time_args": None } # Create the request request = self.rf.get(url) force_authenticate(request, user=self.user) drfrequest = Tile().initialize_request(request) drfrequest.version = version ret = BossRequest(drfrequest, request_args) self.assertEqual(ret.get_resolution(), res) self.assertEqual(ret.get_x_start(), x_start) self.assertEqual(ret.get_x_stop(), x_stop) self.assertEqual(ret.get_x_span(), x_stop - x_start) self.assertEqual(ret.get_y_start(), y_start) self.assertEqual(ret.get_y_stop(), y_stop) self.assertEqual(ret.get_y_span(), y_stop - y_start) self.assertEqual(ret.get_z_start(), z_start) self.assertEqual(ret.get_z_stop(), z_stop) self.assertEqual(ret.get_z_span(), z_stop - z_start)
def get(self, request, collection, experiment, channel, resolution, x_range, y_range, z_range, t_range=None): """ View to handle GET requests for a cuboid of data while providing all params :param request: DRF Request object :type request: rest_framework.request.Request :param collection: Unique Collection identifier, indicating which collection you want to access :param experiment: Experiment identifier, indicating which experiment you want to access :param channel: Channel identifier, indicating which channel you want to access :param resolution: Integer indicating the level in the resolution hierarchy (0 = native) :param x_range: Python style range indicating the X coordinates of where to post the cuboid (eg. 100:200) :param y_range: Python style range indicating the Y coordinates of where to post the cuboid (eg. 100:200) :param z_range: Python style range indicating the Z coordinates of where to post the cuboid (eg. 100:200) :return: """ # Check if parsing completed without error. If an error did occur, return to user. if "filter" in request.query_params: ids = request.query_params["filter"] else: ids = None if "iso" in request.query_params: if request.query_params["iso"].lower() == "true": iso = True else: iso = False else: iso = False # Define access mode. access_mode = utils.get_access_mode(request) if isinstance(request.data, BossParserError): return request.data.to_http() # Process request and validate try: request_args = { "service": "cutout", "collection_name": collection, "experiment_name": experiment, "channel_name": channel, "resolution": resolution, "x_args": x_range, "y_args": y_range, "z_args": z_range, "time_args": t_range, "ids": ids } req = BossRequest(request, request_args) except BossError as err: return err.to_http() # Convert to Resource resource = project.BossResourceDjango(req) # Get bit depth try: self.bit_depth = resource.get_bit_depth() except ValueError: return BossHTTPError("Unsupported data type: {}".format(resource.get_data_type()), ErrorCodes.TYPE_ERROR) # Make sure cutout request is under 500MB UNCOMPRESSED if is_too_large(req, self.bit_depth): return BossHTTPError("Cutout request is over 500MB when uncompressed. Reduce cutout dimensions.", ErrorCodes.REQUEST_TOO_LARGE) # Get interface to SPDB cache cache = SpatialDB(settings.KVIO_SETTINGS, settings.STATEIO_CONFIG, settings.OBJECTIO_CONFIG) # Get the params to pull data out of the cache corner = (req.get_x_start(), req.get_y_start(), req.get_z_start()) extent = (req.get_x_span(), req.get_y_span(), req.get_z_span()) # Get a Cube instance with all time samples data = cache.cutout(resource, corner, extent, req.get_resolution(), [req.get_time().start, req.get_time().stop], filter_ids=req.get_filter_ids(), iso=iso, access_mode=access_mode) to_renderer = {"time_request": req.time_request, "data": data} # Send data to renderer return Response(to_renderer)
def parse(self, stream, media_type=None, parser_context=None): """Method to decompress bytes from a POST that contains blosc compressed matrix data **Bytes object decompressed should be C-ordered** :param stream: Request stream stream type: django.core.handlers.wsgi.WSGIRequest :param media_type: :param parser_context: :return: """ # Process request and validate try: request_args = { "service": "cutout", "collection_name": parser_context['kwargs']['collection'], "experiment_name": parser_context['kwargs']['experiment'], "channel_name": parser_context['kwargs']['channel'], "resolution": parser_context['kwargs']['resolution'], "x_args": parser_context['kwargs']['x_range'], "y_args": parser_context['kwargs']['y_range'], "z_args": parser_context['kwargs']['z_range'], } if 't_range' in parser_context['kwargs']: request_args["time_args"] = parser_context['kwargs']['t_range'] else: request_args["time_args"] = None req = BossRequest(parser_context['request'], request_args) except BossError as err: self.consume_request(stream) return BossParserError(err.message, err.error_code) except Exception as err: self.consume_request(stream) return BossParserError(str(err), ErrorCodes.UNHANDLED_EXCEPTION) # Convert to Resource resource = spdb.project.BossResourceDjango(req) # Get bit depth try: bit_depth = resource.get_bit_depth() except ValueError: return BossParserError("Unsupported data type provided to parser: {}".format(resource.get_data_type()), ErrorCodes.TYPE_ERROR) # Make sure cutout request is under 500MB UNCOMPRESSED if is_too_large(req, bit_depth): return BossParserError("Cutout request is over 500MB when uncompressed. Reduce cutout dimensions.", ErrorCodes.REQUEST_TOO_LARGE) try: # Decompress raw_data = blosc.decompress(stream.read()) data_mat = np.fromstring(raw_data, dtype=resource.get_numpy_data_type()) except MemoryError: return BossParserError("Ran out of memory decompressing data.", ErrorCodes.BOSS_SYSTEM_ERROR) except: return BossParserError("Failed to decompress data. Verify the datatype/bitdepth of your data " "matches the channel.", ErrorCodes.DATATYPE_DOES_NOT_MATCH) # Reshape and return try: if req.time_request: # Time series request (even if single time point) - Get 4D matrix parsed_data = np.reshape(data_mat, (len(req.get_time()), req.get_z_span(), req.get_y_span(), req.get_x_span()), order='C') else: # Not a time series request (time range [0,1] auto-populated) - Get 3D matrix parsed_data = np.reshape(data_mat, (req.get_z_span(), req.get_y_span(), req.get_x_span()), order='C') except ValueError: return BossParserError("Failed to unpack data. Verify the datatype of your POSTed data and " "xyz dimensions used in the POST URL.", ErrorCodes.DATA_DIMENSION_MISMATCH) return req, resource, parsed_data