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')
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')
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)
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)
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)
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)
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')
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)
_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)
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')
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)