Esempio n. 1
0
    def post(self, request, collection):
        """Create a new collection

        View to create a new collection and an associated bosskey for that collection
        Args:
            request: DRF Request object
            collection : Collection name
        Returns:
            Collection

        """
        col_data = request.data.copy()
        col_data['name'] = collection

        # Save the object
        serializer = CollectionSerializer(data=col_data)
        if serializer.is_valid():
            serializer.save(creator=self.request.user)
            collection_obj = Collection.objects.get(name=col_data['name'])

            # Assign permissions to the users primary group and admin group
            BossPermissionManager.add_permissions_primary_group(self.request.user, collection_obj)
            BossPermissionManager.add_permissions_admin_group(collection_obj)

            lookup_key = str(collection_obj.pk)
            boss_key = collection_obj.name
            LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name)

            return Response(serializer.data, status=status.HTTP_201_CREATED)
        else:
            return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
Esempio n. 2
0
    def post(self, request, collection, experiment):
        """Create a new experiment

        View to create a new experiment and an associated bosskey for that experiment
        Args:
            request: DRF Request object
            collection : Collection name
            experiment : Experiment name
        Returns:
            Experiment

        """
        experiment_data = request.data.copy()
        experiment_data['name'] = experiment
        try:
            # Get the collection information
            collection_obj = Collection.objects.get(name=collection)

            if request.user.has_perm("add", collection_obj):
                experiment_data['collection'] = collection_obj.pk

                # Update the coordinate frame
                if 'coord_frame' not in experiment_data:
                    return BossHTTPError("This request requires a valid coordinate frame",
                                         ErrorCodes.INVALID_POST_ARGUMENT)

                coord_frame_obj = CoordinateFrame.objects.get(name=experiment_data['coord_frame'])
                experiment_data['coord_frame'] = coord_frame_obj.pk

                serializer = ExperimentSerializer(data=experiment_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    experiment_obj = Experiment.objects.get(name=experiment_data['name'], collection=collection_obj)

                    # Assign permissions to the users primary group and admin group
                    BossPermissionManager.add_permissions_primary_group(self.request.user, experiment_obj)
                    BossPermissionManager.add_permissions_admin_group(experiment_obj)

                    lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name, experiment_obj.name)

                    serializer = ExperimentReadSerializer(experiment_obj)
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', collection)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except CoordinateFrame.DoesNotExist:
            return BossResourceNotFoundError(experiment_data['coord_frame'])
        except ValueError:
            return BossHTTPError("Value Error.Collection id {} in post data needs to be an integer"
                                 .format(experiment_data['collection']), ErrorCodes.TYPE_ERROR)
Esempio n. 3
0
    def post(self, request, collection, experiment, channel):
        """
        Post a new Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel: Channel name

        Returns :
            Channel
        """

        channel_data = request.data.copy()
        channel_data['name'] = channel

        try:
            # Get the collection and experiment
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)

            # Check for add permissions
            if request.user.has_perm("add", experiment_obj):
                channel_data['experiment'] = experiment_obj.pk

                # The source and related channels are names and need to be removed from the dict before serialization
                source_channels = channel_data.pop('sources', [])
                related_channels = channel_data.pop('related', [])

                # Source channels have to be included for new annotation channels
                if 'type' in channel_data and channel_data['type'] == 'annotation' and len(source_channels) == 0:
                    return BossHTTPError("Annotation channels require the source channel to be set. "
                                         "Specify a valid source channel in the post", ErrorCodes.INVALID_POST_ARGUMENT)

                # Validate the source and related channels if they are incuded
                channels = self.validate_source_related_channels(experiment_obj, source_channels, related_channels)
                source_channels_objs = channels[0]
                related_channels_objs = channels[1]

                # Validate and create the channel
                serializer = ChannelSerializer(data=channel_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    channel_obj = Channel.objects.get(name=channel_data['name'], experiment=experiment_obj)

                    # Save source and related channels if they are valid
                    channel_obj = self.add_source_related_channels(channel_obj, experiment_obj, source_channels_objs,
                                                                   related_channels_objs)

                    # Assign permissions to the users primary group and admin group
                    BossPermissionManager.add_permissions_primary_group(self.request.user, channel_obj)
                    BossPermissionManager.add_permissions_admin_group(channel_obj)

                    # Add Lookup key
                    lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk) + '&' + str(channel_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name + '&' + channel_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name, experiment_obj.name,
                                         channel_obj.name)

                    serializer = ChannelReadSerializer(channel_obj)
                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except Channel.DoesNotExist:
            return BossResourceNotFoundError(channel)
        except BossError as err:
            return err.to_http()
        except ValueError:
            return BossHTTPError("Value Error in post data", ErrorCodes.TYPE_ERROR)
Esempio n. 4
0
    def post(self, request, collection, experiment, channel):
        """
        Post a new Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel: Channel name

        Returns :
            Channel
        """

        channel_data = request.data.copy()
        channel_data['name'] = channel

        try:
            is_admin = BossPermissionManager.is_in_group(
                request.user, ADMIN_GRP)
            if 'bucket' in channel_data and channel_data[
                    'bucket'] and not is_admin:
                return BossHTTPError('Only admins can set bucket name',
                                     ErrorCodes.MISSING_PERMISSION)

            if 'cv_path' in channel_data and channel_data[
                    'cv_path'] and not is_admin:
                return BossHTTPError('Only admins can set cv_path',
                                     ErrorCodes.MISSING_PERMISSION)

            # Get the collection and experiment
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment,
                                                    collection=collection_obj)

            # Check for add permissions
            if request.user.has_perm("add", experiment_obj):
                channel_data['experiment'] = experiment_obj.pk

                use_cloudvol = channel_data.get(
                    'storage_type', None) == Channel.StorageType.CLOUD_VOLUME
                cv_path = channel_data.get('cv_path', None)
                if use_cloudvol and (cv_path is None or cv_path == ''):
                    channel_data[
                        'cv_path'] = f'/{collection}/{experiment}/{channel}'

                if use_cloudvol:
                    # DX NOTE: For now we assume that cloudvolume channels are downsampled. This means
                    # that the num_hierarchy_levels in the experiment should be limited to the available
                    # mip levels in the cloudvolume layer.
                    channel_data['downsample_status'] = 'DOWNSAMPLED'

                # The source and related channels are names and need to be removed from the dict before serialization
                source_channels = channel_data.pop('sources', [])
                related_channels = channel_data.pop('related', [])

                # TODO: Removed source channel requirement for annotation channels. Future update should allow source channel from
                # different collections.

                # Source channels have to be included for new annotation channels
                # if 'type' in channel_data and channel_data['type'] == 'annotation' and len(source_channels) == 0:
                #     return BossHTTPError("Annotation channels require the source channel to be set. "
                #                          "Specify a valid source channel in the post", ErrorCodes.INVALID_POST_ARGUMENT)

                # Validate the source and related channels if they are incuded
                channels = self.validate_source_related_channels(
                    experiment_obj, source_channels, related_channels)
                source_channels_objs = channels[0]
                related_channels_objs = channels[1]

                # Validate and create the channel
                serializer = ChannelSerializer(data=channel_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    channel_obj = Channel.objects.get(
                        name=channel_data['name'], experiment=experiment_obj)

                    # Save source and related channels if they are valid
                    channel_obj = self.add_source_related_channels(
                        channel_obj, experiment_obj, source_channels_objs,
                        related_channels_objs)

                    # Assign permissions to the users primary group and admin group
                    BossPermissionManager.add_permissions_primary_group(
                        self.request.user, channel_obj)
                    BossPermissionManager.add_permissions_admin_group(
                        channel_obj)

                    # Add Lookup key
                    lookup_key = str(collection_obj.pk) + '&' + str(
                        experiment_obj.pk) + '&' + str(channel_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name + '&' + channel_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key,
                                         collection_obj.name,
                                         experiment_obj.name, channel_obj.name)

                    serializer = ChannelReadSerializer(channel_obj)
                    return Response(serializer.data,
                                    status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors),
                                         ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except Channel.DoesNotExist:
            return BossResourceNotFoundError(channel)
        except BossError as err:
            return err.to_http()
        except ValueError:
            return BossHTTPError("Value Error in post data",
                                 ErrorCodes.TYPE_ERROR)
Esempio n. 5
0
    def post(self, request, collection, experiment, channel_layer):
        """
        Post a new Channel
        Args:
            request: DRF Request object
            collection: Collection name
            experiment: Experiment name
            channel_layer: Channel or Layer name

        Returns :
            ChannelLayer
        """

        channel_layer_data = request.data.copy()
        channel_layer_data['name'] = channel_layer

        try:
            if 'channels' in channel_layer_data:
                channels = dict(channel_layer_data)['channels']
            else:
                channels = []
            collection_obj = Collection.objects.get(name=collection)
            experiment_obj = Experiment.objects.get(name=experiment, collection=collection_obj)
            # Check for add permissions
            if request.user.has_perm("add", experiment_obj):
                channel_layer_data['experiment'] = experiment_obj.pk
                channel_layer_data['is_channel'] = self.get_bool(channel_layer_data['is_channel'])

                # layers require at least 1 channel
                if (channel_layer_data['is_channel'] is False) and (len(channels) == 0):
                    return BossHTTPError("Invalid Request.Please specify a valid channel for the layer",
                                         ErrorCodes.INVALID_POST_ARGUMENT)

                serializer = ChannelLayerSerializer(data=channel_layer_data)
                if serializer.is_valid():
                    serializer.save(creator=self.request.user)
                    channel_layer_obj = ChannelLayer.objects.get(name=channel_layer_data['name'],
                                                                 experiment=experiment_obj)

                    # Layer?
                    if not channel_layer_obj.is_channel:
                        # Layers must map to at least 1 channel
                        for channel_id in channels:
                            # Is this a valid channel?
                            channel_obj = ChannelLayer.objects.get(pk=channel_id)
                            if channel_obj:
                                channel_layer_map = {'channel': channel_id, 'layer': channel_layer_obj.pk}
                                map_serializer = ChannelLayerMapSerializer(data=channel_layer_map)
                                if map_serializer.is_valid():
                                    map_serializer.save()

                    # Assign permissions to the users primary group
                    BossPermissionManager.add_permissions_primary_group(self.request.user, channel_layer_obj)

                    # Add Lookup key
                    lookup_key = str(collection_obj.pk) + '&' + str(experiment_obj.pk) + '&' + str(channel_layer_obj.pk)
                    boss_key = collection_obj.name + '&' + experiment_obj.name + '&' + channel_layer_obj.name
                    LookUpKey.add_lookup(lookup_key, boss_key, collection_obj.name, experiment_obj.name,
                                         channel_layer_obj.name)

                    return Response(serializer.data, status=status.HTTP_201_CREATED)
                else:
                    return BossHTTPError("{}".format(serializer.errors), ErrorCodes.INVALID_POST_ARGUMENT)
            else:
                return BossPermissionError('add', experiment)
        except Collection.DoesNotExist:
            return BossResourceNotFoundError(collection)
        except Experiment.DoesNotExist:
            return BossResourceNotFoundError(experiment)
        except ChannelLayer.DoesNotExist:
            return BossResourceNotFoundError(channel_layer)
        except ValueError:
            return BossHTTPError("Value Error in post data", ErrorCodes.TYPE_ERROR)