Esempio n. 1
0
    def test_set_new_link(self):
        parent = Mock()
        parent.raw = {'links': {}}

        target = Mock()

        resolver = LinkResolver(parent)
        resolver.newlink = target
        self.assertEqual(parent.raw['links'].get('newlink', None), target)
from panoptes_client.panoptes import LinkResolver, PanoptesObject


class Classification(PanoptesObject):
    _api_slug = 'classifications'
    _link_slug = 'classification'
    _edit_attributes = ( )

    @classmethod
    def where(cls, **kwargs):
        scope = kwargs.pop('scope', None)
        if not scope:
            return super(Classification, cls).where(**kwargs)
        return cls.paginated_results(*cls.get(scope, params=kwargs))

LinkResolver.register(Classification)
    @batchable
    def remove(self, subjects):
        _subjects = self._build_subject_list(subjects)

        _subjects_ids = ",".join(_subjects)
        self.http_delete('{}/links/subjects/{}'.format(self.id, _subjects_ids))

    def _build_subject_list(self, subjects):
        _subjects = []
        for subject in subjects:
            if not (isinstance(subject, Subject)
                    or isinstance(subject, (
                        int,
                        str,
                    ))):
                raise TypeError

            if isinstance(subject, Subject):
                _subject_id = subject.id
            else:
                _subject_id = str(subject)

            _subjects.append(_subject_id)

        return _subjects


LinkResolver.register(SubjectSet)
LinkResolver.register(SubjectSet, 'subject_set')
Esempio n. 4
0
        A dict containing metadata about the project's avatar.
        """
        return self.http_get('{}/avatar'.format(self.id))[0]

    @property
    def attached_images(self):
        return self.http_get('{}/attached_images'.format(self.id))[0]

    def add_attached_image(
        self,
        src,
        content_type='image/png',
        external_link=True,
        metadata={},
    ):
        return self.http_post(
            '{}/attached_images'.format(self.id),
            json={
                'media': {
                    'src': src,
                    'content_type': content_type,
                    'external_link': external_link,
                    'metadata': metadata,
                }
            },
        )


LinkResolver.register(Project)
LinkResolver.register(Project, 'projects')
Esempio n. 5
0
                email = [email]

            for batch in split(email, BATCH_SIZE):
                kwargs['email'] = ",".join(batch)
                for user in super(User, cls).where(**kwargs):
                    yield user

        elif login:
            if not isiterable(login):
                login = [login]

            for batch in split(login, BATCH_SIZE):
                kwargs['login'] = "******".join(batch)
                for user in super(User, cls).where(**kwargs):
                    yield user

        else:
            for user in super(User, cls).where(**kwargs):
                yield user

    @property
    def avatar(self):
        """
        A dict containing metadata about the user's avatar.
        """

        return User.http_get('{}/avatar'.format(self.id))[0]

LinkResolver.register(User)
LinkResolver.register(User, 'owner')
from __future__ import absolute_import, division, print_function

from panoptes_client.panoptes import PanoptesObject, LinkResolver


class CollectionRole(PanoptesObject):
    _api_slug = 'collection_roles'
    _link_slug = 'collection_roles'
    _edit_attributes = ()


LinkResolver.register(CollectionRole)
class ProjectPreferences(PanoptesObject):
    _api_slug = 'project_preferences'
    _link_slug = 'project_preferences'
    _edit_attributes = (
        'preferences',
    )

    @classmethod
    def find(cls, id='', user=None, project=None):
        if not id:
            if not (user and project):
                raise ValueError('Both user and project required')
            if (
                isinstance(user, User)
                and isinstance(project, Project)
            ):
                _user_id = user.id
                _project_id = project.id
            elif (
                isinstance(user, (int, str, unicode,))
                and isinstance(project, (int, str, unicode,))
            ):
                _user_id = user
                _project_id = project
            else:
                raise TypeError
            id = cls.where(user_id=_user_id, project_id=_project_id).next().id
        return super(ProjectPreferences, cls).find(id)

LinkResolver.register(ProjectPreferences)
        elif type(location) in (str, ) + _OLD_STR_TYPES:
            f = open(location, 'rb')
        else:
            f = location

        try:
            media_data = f.read()
            if MEDIA_TYPE_DETECTION == 'magic':
                media_type = magic.from_buffer(media_data, mime=True)
            else:
                media_type = imghdr.what(None, media_data)
                if not media_type:
                    raise UnknownMediaException(
                        'Could not detect file type. Please try installing '
                        'libmagic: https://panoptes-python-client.readthedocs.'
                        'io/en/latest/user_guide.html#uploading-non-image-'
                        'media-types')
                media_type = 'image/{}'.format(media_type)
            self.locations.append(media_type)
            self._media_files.append(media_data)
        finally:
            f.close()


class UnknownMediaException(Exception):
    pass


LinkResolver.register(Subject)
LinkResolver.register(Subject, 'subject')
from __future__ import absolute_import, division, print_function

from panoptes_client.panoptes import PanoptesObject, LinkResolver


class CollectionRole(PanoptesObject):
    _api_slug = 'collection_roles'
    _link_slug = 'collection_roles'
    _edit_attributes = (
        'roles',
        {
            'links': (
                'collection',
                'user',
            ),
        },
    )


LinkResolver.register(CollectionRole)
from __future__ import absolute_import, division, print_function

from panoptes_client.panoptes import PanoptesObject, LinkResolver


class ProjectRole(PanoptesObject):
    _api_slug = 'project_roles'
    _link_slug = 'project_roles'
    _edit_attributes = ()

LinkResolver.register(ProjectRole)
Esempio n. 11
0
from panoptes_client.panoptes import (
    Panoptes,
    PanoptesObject,
    LinkResolver,
)
from panoptes_client.project import Project


class ProjectAvatar(PanoptesObject):
    _api_slug = 'avatar'
    _link_slug = 'avatars'
    _edit_attributes = ()

    @classmethod
    def avatar_get(cls, path, params={}, headers={}):
        project = params.pop('project')

        avatar_response = Panoptes.client().get(
            Project.url(project.id) + cls.url(path),
            params,
            headers,
        )
        return avatar_response


LinkResolver.register(ProjectAvatar)
LinkResolver.register(ProjectAvatar, 'avatar')
from panoptes_client.panoptes import PanoptesObject, LinkResolver


class SetMemberSubject(PanoptesObject):
    _api_slug = 'set_member_subjects'
    _link_slug = 'set_member_subjects'
    _edit_attributes = ()

LinkResolver.register(SetMemberSubject)
Esempio n. 13
0
from panoptes_client.panoptes import PanoptesObject, LinkResolver


class SetMemberSubject(PanoptesObject):
    _api_slug = 'set_member_subjects'
    _link_slug = 'set_member_subjects'
    _edit_attributes = ()

LinkResolver.register(SetMemberSubject)
LinkResolver.register(SetMemberSubject, 'set_member_subject')
from panoptes_client.panoptes import PanoptesObject, LinkResolver


class ProjectRole(PanoptesObject):
    _api_slug = 'project_roles'
    _link_slug = 'project_roles'
    _edit_attributes = ()


LinkResolver.register(ProjectRole)
Esempio n. 15
0
    def add_workflows(self, workflows):
        """
        Links the given workflows to this project. New workflows are
        created as copies of the given workflows.

        - **workflows** can be a list of :py:class:`.Workflow` instances,
          a list of workflow IDs, a single :py:class:`.Workflow`
          instance, or a single workflow ID.

        Examples::

            project.add_workflows(1234)
            project.add_workflows([1,2,3,4])
            project.add_workflows(Workflow(1234))
            project.add_workflows([Workflow(12), Workflow(34)])
        """
        return self._add_links(
            workflows,
            'workflows',
        )

    @property
    def avatar(self):
        """
        A dict containing metadata about the project's avatar.
        """
        return self.http_get('{}/avatar'.format(self.id))[0]

LinkResolver.register(Project)
LinkResolver.register(Project, 'projects')
        if (isinstance(settings, dict)):
            _to_update = settings
            if (
                isinstance(user, User)
                and isinstance(project, Project)
            ):
                _user_id = user.id
                _project_id = project.id
            elif (
                isinstance(user, (int, str, unicode,))
                and isinstance(project, (int, str, unicode,))
            ):
                _user_id = user
                _project_id = project
            else:
                raise TypeError
            cls.http_post(
                'update_settings',
                json={
                    'project_preferences': {
                        'user_id': _user_id,
                        'project_id': _project_id,
                        'settings': _to_update,
                    }
                }
            )
        else:
            raise TypeError

LinkResolver.register(ProjectPreferences)
        'display_name',
        {
            'links': (
                'project',
            ),
            'metadata': (
                'category',
            )
        },
    )

    def subjects(self):
        return Subject.where(subject_set_id=self.id)

    def add_subjects(self, subjects):
        if not type(subjects) in (tuple, list):
            subjects = [subjects]

        _subjects = []
        for subject in subjects:
            if not isinstance(subject, Subject):
                raise TypeError
            _subjects.append(subject.id)

        self.post(
            '{0}/links/subjects'.format(self.id),
            json={'subjects': _subjects}
        )

LinkResolver.register(SubjectSet)
Esempio n. 18
0
                                raise
                            else:
                                time.sleep(attempt * RETRY_BACKOFF_INTERVAL)
            finally:
                image_file.close()

    def add_location(self, location):
        if type(location) is dict:
            self.locations.append(location)
            self._image_files.append(None)
            return
        elif type(location) in (str, unicode):
            f = open(location, 'rb')
        else:
            f = location

        image_type = imghdr.what(f)
        self.locations.append(
            'image/{}'.format(image_type)
        )
        self._image_files.append(f)

    def subject_sets(self):
        return [
            sms.links.subject_set
            for sms in SetMemberSubject.where(subject_id=self.id)
        ]

LinkResolver.register(Subject)
LinkResolver.register(Subject, 'subject')
Esempio n. 19
0
            export_description = self.describe_classifications_export()
            if export_description:
                export_metadata = export_description['media'][0]['metadata']
                if export_metadata.get('state', '') == 'ready':
                    success = True
                    break
            time.sleep(2)

        if not success:
            raise PanoptesAPIException(
                'classifications_export not ready within {} seconds'.format(
                    timeout
                )
            )

        return export_description

    def generate_classifications_export(self):
        return Project.post(
            self._classifications_export_path(),
            json = {"media":{"content_type":"text/csv"}}
        )[0]

    def describe_classifications_export(self):
        return Project.get(self._classifications_export_path())[0]

    def _classifications_export_path(self):
        return '{}/classifications_export'.format(self.id)

LinkResolver.register(Project)
Esempio n. 20
0
    _api_slug = 'projects'
    _link_slug = 'project'
    _edit_attributes = (
        'display_name',
        'description',
        'tags',
        'introduction',
        'private',
        'primary_language',
    )

    @classmethod
    def find(cls, id='', slug=None):
        if not id and not slug:
            return None
        try:
            return cls.where(id=id, slug=slug).next()
        except StopIteration:
            raise PanoptesAPIException(
                "Could not find project with slug='{}'".format(slug)
            )

    def collaborators(self, *roles):
        return [
            r.links.owner for r in ProjectRole.where(project_id=self.id)
            if len(roles) == 0 or len(set(roles) & set(r.roles)) > 0
        ]


LinkResolver.register(Project)
    def add(self, projects):
        """
        A wrapper around :py:meth:`.LinkCollection.add`. Equivalent to::

            organization.links.add(projects)
        """

        return self.links.projects.add(projects)

    def remove(self, projects):
        """
        A wrapper around :py:meth:`.LinkCollection.remove`. Equivalent to::

            organization.links.remove(projects)
        """

        return self.links.projects.remove(projects)

    def __contains__(self, project):
        """
        A wrapper around :py:meth:`.LinkCollection.__contains__`. Equivalent
        to::

            project in organization.links.project
        """

        return project in self


LinkResolver.register(Organization)
Esempio n. 22
0
from __future__ import absolute_import, division, print_function

from panoptes_client.panoptes import LinkResolver, PanoptesObject


class Classification(PanoptesObject):
    _api_slug = 'classifications'
    _link_slug = 'classification'
    _edit_attributes = ()

    @classmethod
    def where(cls, **kwargs):
        scope = kwargs.pop('scope', None)
        if not scope:
            return super(Classification, cls).where(**kwargs)
        return cls.paginated_results(*cls.http_get(scope, params=kwargs))


LinkResolver.register(Classification)
        subject set of the given workflow

        Examples::

            for status in workflow.subject_workflow_statuses(1234):
                print(status.retirement_reason)
        """
        subject_ids = []
        for sms in SetMemberSubject.where(subject_set_id=subject_set_id):
            subject_ids.append(sms.links.subject.id)

        subject_ids = ','.join(map(str, subject_ids))
        for status in SubjectWorkflowStatus.where(subject_ids=subject_ids,
                                                  workflow_id=self.id):
            yield status

    @property
    def versions(self):
        """
        A generator which yields all :py:class:`.WorkflowVersion` instances for
        this workflow.
        """

        return WorkflowVersion.where(workflow=self)


LinkResolver.register(Workflow)
LinkResolver.register(Workflow, 'active_workflows', readonly=True)

from panoptes_client.workflow_version import WorkflowVersion
    def _build_subject_set_list(self, subject_sets):
        _subject_sets = []
        for subject_set in subject_sets:
            if not (
                isinstance(subject_set, SubjectSet)
                or isinstance(subject_set, (int, str,))
            ):
                raise TypeError

            if isinstance(subject_set, SubjectSet):
                _subject_set_id = subject_set.id
            else:
                _subject_set_id = str(subject_set)

            _subject_sets.append(_subject_set_id)

        return _subject_sets

    @property
    def versions(self):
        """
        A generator which yields all :py:class:`.WorkflowVersion` instances for
        this workflow.
        """

        return WorkflowVersion.where(workflow=self)

LinkResolver.register(Workflow)

from panoptes_client.workflow_version import WorkflowVersion
        _subjects_ids = ",".join(_subjects)

        self.delete(
            '{}/links/subjects/{}'.format(self.id, _subjects_ids)
        )

    def _build_subject_list(self, subjects):
        if not type(subjects) in (tuple, list):
            subjects = [subjects]

        _subjects = []
        for subject in subjects:
            if not (
                isinstance(subject, Subject)
                or isinstance(subject, (int, str,
            unicode,))
            ):
                raise TypeError

            if isinstance(subject, Subject):
                _subject_id = subject.id
            else:
                _subject_id = str(subject)

            _subjects.append(_subject_id)

        return _subjects

LinkResolver.register(SubjectSet)
LinkResolver.register(SubjectSet, 'subject_set')
from __future__ import absolute_import, division, print_function

from panoptes_client.panoptes import PanoptesObject, LinkResolver


class User(PanoptesObject):
    _api_slug = 'users'
    _link_slug = 'users'
    _edit_attributes = ()

    @property
    def avatar(self):
        """
        A dict containing metadata about the user's avatar.
        """

        return User.http_get('{}/avatar'.format(self.id))[0]

LinkResolver.register(User)
LinkResolver.register(User, 'owner')
Esempio n. 27
0
from panoptes_client.panoptes import PanoptesObject, LinkResolver
from panoptes_client.subject import Subject

class Workflow(PanoptesObject):
    _api_slug = 'workflows'
    _link_slug = 'workflows'
    _edit_attributes = []

    def retire_subjects(self, subjects, reason='other'):
        if type(subjects) not in (list, tuple):
            subjects = [ subjects ]
        subjects = [ s.id if isinstance(s, Subject) else s for s in subjects ]

        return Workflow.post(
            '{}/retired_subjects'.format(self.id),
            json={
                'subject_ids': subjects,
                'retirement_reason': reason
            }
        )

LinkResolver.register(Workflow)