class CatalogueItemElementCommands(HTTPCommands):
    @command(
        name=name.Read(CatalogueItem),
        meta=Meta(title='Read Catalogue Item', domain=CATALOGUE),
        access=Access(access_list=[
            AccountType.RESEARCHER.value,
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=CatalogueItemSerializer),
    )
    def get(self, request, item_id):

        raise self.event.Read(CatalogueItem.objects.get(id=item_id))

    @command(
        name=name.Update(CatalogueItem),
        meta=Meta(title='Update Catalogue Item', domain=CATALOGUE),
        access=Access(access_list=[
            AccountType.ADMIN.value,
        ]),
        input=Input(body_parser=CatalogueItemUpdateParser),
        output=Output(serializer=CatalogueItemSerializer),
    )
    def put(self, request, item_id):

        item = CatalogueItem.objects.get(id=item_id)
        for field, value in request.input.body.items():
            setattr(item, field, value)

        item.updated_by = request.access['account']
        item.save()

        raise self.event.Updated(item)

    @command(
        name=name.Delete(CatalogueItem),
        meta=Meta(title='Delete Catalogue Item', domain=CATALOGUE),
        access=Access(access_list=[
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=serializers.EmptySerializer),
    )
    def delete(self, request, item_id):

        item = CatalogueItem.objects.get(id=item_id)
        not_cancelled_count = (item.download_requests.filter(
            is_cancelled=False).count())

        if not_cancelled_count:
            raise self.event.BrokenRequest(
                'NOT_CANCELLED_DOWNLOAD_REQEUSTS_DETECTED',
                data={
                    'item_id': int(item_id),
                    'not_cancelled_count': not_cancelled_count,
                })

        item.delete()

        raise self.event.Deleted()
class DownloadRequestCollectionCommands(HTTPCommands):
    @command(
        name=name.CreateOrRead(DownloadRequest),
        meta=Meta(title='Create Download Request',
                  description='''
                Create a Download Request in a smart way meaning that:
                - if same `DownloadRequest` already exists do not start
                  another one. (FIXME: maybe just attach user to the
                  waiters list)
                -
            ''',
                  domain=DOWNLOAD_REQUESTS),
        input=Input(body_parser=DownloadRequestParser),
        access=Access(access_list=[
            AccountType.RESEARCHER.value,
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=DownloadRequestSerializer),
    )
    def post(self, request):

        spec = request.input.body['spec']

        r, created = DownloadRequest.objects.get_or_create(
            normalized_spec=DownloadRequest.normalize_spec(spec),
            catalogue_item_id=request.input.body['catalogue_item_id'],
            defaults={
                'created_by': request.access['account'],
                'spec': spec,
            })

        r.waiters.add(request.access['account'])

        if created:
            r.execute()
            raise self.event.Created(r)

        else:
            raise self.event.Read(r)

    @command(
        name=name.BulkRead(DownloadRequest),
        meta=Meta(
            title='Bulk Read Download Requests which you are waiting for',
            domain=DOWNLOAD_REQUESTS),
        access=Access(access_list=[
            AccountType.RESEARCHER.value,
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=DownloadRequestListSerializer),
    )
    def get(self, request):

        requests = DownloadRequest.objects.filter(
            waiters__id=request.access['account'].id)

        raise self.event.BulkRead({'requests': requests})
Exemple #3
0
    def test_render__with_markdown_description(self):
        renderer = self.mocker.patch(
            'lily.entrypoint.renderer.SchemaRenderer')
        serialize = Mock()
        renderer.return_value.render.return_value = Mock(
            serialize=serialize, enums=[])
        serialize.side_effect = [
            {'output': 'schema'},
            {'query': 'schema'},
            {'body': 'schema'},
        ]

        meta = Meta(
            title='hi',
            description='./description.md',
            domain=Domain(id='h', name='hh'))
        access = Access(access_list=['EVERYONE'], is_private=True)
        source = Source(fn)
        self.mocker.patch.object(BaseRenderer, 'render').return_value = {
            'READ_CARD': {
                'method': 'get',
                'path_conf': {
                    'path': '/hi',
                    'pattern': '/hi',
                    'parameters': [],
                },
                'meta': meta,
                'access': access,
                'input': Input(query_parser=Mock(), body_parser=Mock()),
                'output': Output(serializer=Mock()),
                'source': source,
            }
        }

        result = CommandsRenderer().render()

        meta = Meta(
            title='hi',
            description='# this is test of markdown description',
            domain=Domain(id='h', name='hh'))
        assert result == {
            'enums': [],
            'READ_CARD': {
                'access': access,
                'meta': meta,
                'method': 'get',
                'path_conf': {
                    'parameters': [],
                    'path': '/hi',
                },
                'schemas': {
                    'input_body': {'body': 'schema'},
                    'input_query': {'query': 'schema'},
                    'output': {'output': 'schema'},
                },
                'source': source,
                'examples': {},
            }
        }
class DownloadRequestElementCommands(HTTPCommands):
    @command(
        name=name.Read(DownloadRequest),
        meta=Meta(title='Read DownloadRequest one is waiting for',
                  domain=DOWNLOAD_REQUESTS),
        access=Access(access_list=[
            AccountType.RESEARCHER.value,
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=DownloadRequestSerializer),
    )
    def get(self, request, request_id):

        raise self.event.Read(
            DownloadRequest.objects.get(
                waiters__id=request.access['account'].id, id=request_id))

    @command(
        name=name.Delete(DownloadRequest),
        meta=Meta(
            title='Creator can cancel request or remove himself from waiters',
            domain=DOWNLOAD_REQUESTS),
        access=Access(access_list=[
            AccountType.RESEARCHER.value,
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=serializers.EmptySerializer),
    )
    def delete(self, request, request_id):

        account = request.access['account']
        r = DownloadRequest.objects.get(id=request_id)
        r.waiters.remove(account)

        if r.waiters.count() == 0:
            r.is_cancelled = True
            r.save()

        raise self.event.Deleted()
Exemple #5
0
class AuthRequestAuthTokenCommands(HTTPCommands):
    class BodyParser(parsers.Parser):

        request_uuid = parsers.UUIDField()

    @command(
        name=name.Create('AUTH_TOKEN_FOR_AUTH_REQUEST'),
        meta=Meta(title='Create Auth Token', domain=ACCOUNT_AUTHENTICATION),
        input=Input(body_parser=BodyParser),
        output=Output(serializer=AuthTokenSerializer),
    )
    def post(self, request):

        r = AuthRequest.objects.get(uuid=request.input.body['request_uuid'],
                                    account__isnull=False)

        raise self.event.Created({'token': r.get_token_and_delete()})
class CatalogueItemSampleAndDistributionsCommands(HTTPCommands):
    @command(
        name=name.Execute('WITH_SAMPLE_AND_DISTRIBUTION_UPDATE',
                          CatalogueItem),
        meta=Meta(title='Update Catalogue Item with Samples and Distributions',
                  domain=CATALOGUE),
        is_atomic=True,
        access=Access(access_list=[
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=serializers.EmptySerializer),
    )
    def put(self, request, item_id):

        item = CatalogueItem.objects.get(id=item_id)
        item.update_samples_and_distributions()

        raise self.event.Executed()
class DownloadRequestEstimateCommands(HTTPCommands):
    @command(
        name=name.Execute('ESTIMATE', 'SIZE_OF_DOWNLOAD_REQUEST'),
        meta=Meta(
            title='Estimate the size download based on the provided spec',
            domain=DOWNLOAD_REQUESTS),
        input=Input(body_parser=DownloadRequestParser),
        access=Access(access_list=[
            AccountType.RESEARCHER.value,
            AccountType.ADMIN.value,
        ]),
        output=Output(serializer=DownloadRequestEstimateSerializer),
    )
    def post(self, request):

        raise self.event.Executed({
            'estimated_size':
            DownloadRequest.objects.estimate_size(**request.input.body),
        })
Exemple #8
0
class AuthRequestCommands(HTTPCommands):
    @command(
        name=name.Create('AUTH_REQUEST'),
        meta=Meta(title='Create Auth Request', domain=ACCOUNT_AUTHENTICATION),
        output=Output(serializer=AuthRequestSerializer),
    )
    def post(self, request):

        r = AuthRequest.objects.create()

        # FIXME: !!!! fix this URL!!!
        # - make it absolute
        # - make it add query param
        raise self.event.Created({
            # 'authenticate_ui_uri': reverse(
            #     'account:auth.requests.authenticate.ui',
            #     kwargs={'request_uuid': r.uuid}),
            'request_uuid': r.uuid,
        })
Exemple #9
0
class AuthTokenCommands(HTTPCommands):
    class BodyParser(parsers.Parser):

        oauth_token = parsers.CharField()

        email = parsers.EmailField()

    @command(
        name=name.Create('AUTH_TOKEN'),
        meta=Meta(title='Generate Token', domain=ACCOUNT_AUTHENTICATION),
        input=Input(body_parser=BodyParser),
        output=Output(serializer=AuthTokenSerializer),
    )
    def post(self, request):

        email = request.input.body['email']

        oauth_token = request.input.body['oauth_token']

        account = Account.objects.get_or_create_oauth2(email, oauth_token)

        raise self.event.Created({'token': AuthToken.encode(account)})
Exemple #10
0
class AuthRequestAttachAccountCommands(HTTPCommands):
    class BodyParser(parsers.Parser):

        request_uuid = parsers.UUIDField()

        oauth_token = parsers.CharField()

        email = parsers.EmailField()

    @command(
        name=name.Execute('ATTACH', 'ACCOUNT_TO_AUTH_REQUEST'),
        meta=Meta(title='Attach Account to Auth Request',
                  domain=ACCOUNT_AUTHENTICATION),
        input=Input(body_parser=BodyParser),
        output=Output(serializer=serializers.EmptySerializer),
    )
    def post(self, request):

        AuthRequest.objects.get(
            uuid=request.input.body['request_uuid']).attach_account(
                email=request.input.body['email'],
                oauth_token=request.input.body['oauth_token'])

        raise self.event.Executed()
Exemple #11
0
    def test_render__with_examples(self):
        renderer = self.mocker.patch(
            'lily.entrypoint.renderer.SchemaRenderer')
        serialize = Mock()
        renderer.return_value.render.return_value = Mock(
            serialize=serialize, enums=[])
        serialize.side_effect = [
            {'output': 'schema'},
            {'query': 'schema'},
            {'body': 'schema'},
        ]

        meta = Meta(
            title='hi',
            description='ho',
            domain=Domain(id='h', name='hh'))
        access = Access(access_list=['EVERYONE'], is_private=True)
        source = Source(fn)
        self.mocker.patch.object(BaseRenderer, 'render').return_value = {
            'READ_CARD': {
                'method': 'get',
                'path_conf': {
                    'path': '/hi',
                    'pattern': '/hi',
                    'parameters': [],
                },
                'meta': meta,
                'access': access,
                'input': Input(query_parser=Mock(), body_parser=Mock()),
                'output': Output(serializer=Mock()),
                'source': source,
            }
        }

        with open(self.examples_filepath, 'w') as f:
            f.write(json.dumps({
                'READ_CARD': {
                    '200 (OK)': {
                        'request': {
                            'path': '/hi',
                            'parameters': {},
                        },
                    },
                },
            }))

        assert CommandsRenderer().render() == {
            'enums': [],
            'READ_CARD': {
                'access': access,
                'meta': meta,
                'method': 'get',
                'path_conf': {
                    'parameters': [],
                    'path': '/hi',
                },
                'schemas': {
                    'input_body': {'body': 'schema'},
                    'input_query': {'query': 'schema'},
                    'output': {'output': 'schema'},
                },
                'source': source,
                'examples': {
                    '200 (OK)': {
                        'request': {
                            'path': '/hi',
                            'parameters': {},
                        },
                    },
                },
            }
        }
Exemple #12
0
    def test_render__many_commands(self):
        renderer = self.mocker.patch(
            'lily.entrypoint.renderer.SchemaRenderer')
        serialize = Mock()
        renderer.return_value.render.return_value = Mock(
            serialize=serialize, enums=[])
        serialize.side_effect = [
            {'output': 'read.schema'},
            {'query': 'read.schema'},
            {'body': 'read.schema'},
            {'output': 'delete.schema'},
            {'query': 'delete.schema'},
            {'body': 'delete.schema'},
        ]

        meta = Meta(
            title='hi',
            description='ho',
            domain=Domain(id='h', name='hh'))
        access = Access(access_list=['EVERYONE'], is_private=True)
        source = Source(fn)
        self.mocker.patch.object(
            BaseRenderer,
            'render'
        ).return_value = OrderedDict([
            (
                'READ_CARD',
                {
                    'method': 'get',
                    'path_conf': {
                        'path': '/hi',
                        'pattern': '/hi',
                        'parameters': [],
                    },
                    'meta': meta,
                    'access': access,
                    'input': Input(query_parser=Mock(), body_parser=Mock()),
                    'output': Output(serializer=Mock()),
                    'source': source,
                },
            ),
            (
                'DELETE_TASK',
                {
                    'method': 'delete',
                    'path_conf': {
                        'path': '/hi/{id}',
                        'pattern': '/hi/(?P<id>\\d+)',
                        'parameters': [{'name': 'id', 'type': 'integer'}],
                    },
                    'meta': meta,
                    'access': access,
                    'input': Input(query_parser=Mock(), body_parser=Mock()),
                    'output': Output(serializer=Mock()),
                    'source': source,
                }
            )])

        assert CommandsRenderer().render() == {
            'enums': [],
            'READ_CARD': {
                'access': access,
                'meta': meta,
                'method': 'get',
                'path_conf': {
                    'parameters': [],
                    'path': '/hi',
                },
                'schemas': {
                    'input_body': {'body': 'read.schema'},
                    'input_query': {'query': 'read.schema'},
                    'output': {'output': 'read.schema'},
                },
                'source': source,
                'examples': {},
            },
            'DELETE_TASK': {
                'access': access,
                'meta': meta,
                'method': 'delete',
                'path_conf': {
                    'path': '/hi/{id}',
                    'parameters': [{'name': 'id', 'type': 'integer'}],
                },
                'schemas': {
                    'input_body': {'body': 'delete.schema'},
                    'input_query': {'query': 'delete.schema'},
                    'output': {'output': 'delete.schema'},
                },
                'source': source,
                'examples': {},
            },
        }
class CatalogueItemCollectionCommands(HTTPCommands):
    @command(
        name=name.Create(CatalogueItem),
        meta=Meta(title='Create Catalogue Item', domain=CATALOGUE),
        access=Access(access_list=[
            AccountType.ADMIN.value,
        ]),
        input=Input(body_parser=CatalogueItemCreateParser),
        output=Output(serializer=CatalogueItemSerializer),
    )
    def post(self, request):

        raise self.event.Created(
            CatalogueItem.objects.create(created_by=request.access['account'],
                                         updated_by=request.access['account'],
                                         **request.input.body))

    class QueryParser(parsers.Parser):

        query = parsers.CharField(default=None)

        has_samples = parsers.BooleanField(default=None)

    @command(
        name=name.BulkRead(CatalogueItem),
        meta=Meta(title='Bulk Read Catalogue Items', domain=CATALOGUE),
        access=Access(access_list=[
            AccountType.RESEARCHER.value,
            AccountType.ADMIN.value,
        ]),
        input=Input(query_parser=QueryParser),
        output=Output(serializer=CatalogueItemListSerializer),
    )
    def get(self, request):

        query = request.input.query['query']

        has_samples = request.input.query['has_samples']

        if query:
            qs = Q()
            expression = re.compile(r'([\&\|\~])(\s+)')
            query = expression.sub('\\1', query)

            for word in query.split():
                if word[0] == '~':
                    qs = qs & ~Q(name__icontains=word[1:])

                elif word[0] == '&':
                    qs = qs & Q(name__icontains=word[1:])

                elif word[0] == '|':
                    qs = qs | Q(name__icontains=word[1:])

                else:
                    qs = qs | Q(name__icontains=word)

            items = CatalogueItem.objects.filter(qs)

        else:
            items = CatalogueItem.objects.all()

        if has_samples:
            items = items.exclude(sample=[])

        elif not has_samples and has_samples is not None:
            items = items.filter(sample=[])

        raise self.event.BulkRead({'items': items})