panoptes_client package

As a convenience, the following classes can be imported directly from the root of the panoptes_client package:

For example:

from panoptes_client import Panoptes, Project

Panoptes.connect(username='example', password='example')

new_project = Project()
new_project.display_name = 'My new project'
new_project.description = 'A great new project!'
new_project.primary_language = 'en'
new_project.private = True
new_project.save()

panoptes_client.panoptes module

class panoptes_client.panoptes.LinkCollection(cls, slug, parent, linked_objects)[source]

Bases: object

A collection of PanoptesObject of one class which are linked to a parent PanoptesObject.

Allows indexing, iteration, and membership testing:

project = Project(1234)

print(project.links.workflows[2].display_name)

for workflow in project.links.workflows:
    print(workflow.id)

if Workflow(5678) in project.links.workflows:
    print('Workflow found')

# Integers, strings, and PanoptesObjects are all OK
if 9012 not in project.links.workflows:
    print('Workflow not found')
add(objs)[source]

Adds the given objs to this LinkCollection.

Examples:

organization.links.projects.add(1234)
organization.links.projects.add(Project(1234))
workflow.links.subject_sets.add([1,2,3,4])
workflow.links.subject_sets.add([Project(12), Project(34)])
remove(objs)[source]

Removes the given objs from this LinkCollection.

Examples:

organization.links.projects.remove(1234)
organization.links.projects.remove(Project(1234))
workflow.links.subject_sets.remove([1,2,3,4])
workflow.links.subject_sets.remove([Project(12), Project(34)])
exception panoptes_client.panoptes.ObjectNotSavedException[source]

Bases: Exception

Raised if an attempt is made to perform an operation on an unsaved PanoptesObject which requires the object to be saved first.

class panoptes_client.panoptes.Panoptes(endpoint=None, client_id=None, client_secret=None, redirect_url=None, username=None, password=None, login=None, admin=False)[source]

Bases: object

The low-level Panoptes HTTP client class. Use this class to log into the API. In most cases you can just call Panoptes.connect() once and all subsequent API requests will be authenticated.

If you want to configure multiple clients, e.g. to perform operations as multiple users, you should initialise the client as a context manager, using the with statement instead of using Panoptes.connect(). In this example, we modify a project by authenticating as the project owner, then log in as a regular user to add a subject to a collection, then switch back to the project owner’s account to retire some subjects:

owner_client = Panoptes(username='example-project-owner', password='')

with owner_client:
    project = Project(1234)
    project.display_name = 'New name'
    project.save()

with Panoptes(username='example-user', password=''):
    Collection(1234).add(Subject(1234))

with owner_client:
    Workflow(1234).retire_subjects([1234, 5678, 9012])

Using the with statement in this way ensures it is clear which user will be used for each action.

classmethod connect(username=None, password=None, endpoint=None, admin=False)[source]

Configures the Panoptes client for use.

Note that there is no need to call this unless you need to pass one or more of the below arguments. By default, the client will connect to the public Zooniverse.org API as an anonymous user.

All arguments are optional:

  • username is your Zooniverse.org username.
  • password is your Zooniverse.org password.
  • endpoint is the HTTP API endpoint you’d like to connect to. Defaults to https://www.zooniverse.org. Should not include a trailing slash.
  • admin is a boolean, switching on admin mode if True. Has no effect if the given username is not a Zooniverse.org administrator.

Examples:

Panoptes.connect(username='example', password='example')
Panoptes.connect(endpoint='https://panoptes.example.com')
exception panoptes_client.panoptes.PanoptesAPIException[source]

Bases: Exception

Raised whenever the API returns an error. The exception will contain the raw error message from the API.

class panoptes_client.panoptes.PanoptesObject(raw={}, etag=None)[source]

Bases: object

The base class of all Panoptes model classes. You should never need to create instances of this class, but the methods defined here are common to all the model subclasses.

`PanoptesObject`s support lazy loading of attributes, where data is loaded from the API only when it is first accessed. You can do this by passing an object ID to the contructor:

project = Project(1234)
print(project.display_name)

This will not make any HTTP requests until the print statement.

delete()[source]

Deletes the object. Returns without doing anything if the object is new.

classmethod find(_id)[source]

Returns the individual instance with the given ID, if it exists. Raises PanoptesAPIException if the object with that ID is not found.

reload()[source]

Re-fetches the object from the API, discarding any local changes. Returns without doing anything if the object is new.

save()[source]

Saves the object. If the object has not been saved before (i.e. it’s new), then a new object is created. Otherwise, any changes are submitted to the API.

classmethod where(**kwargs)[source]

Returns a generator which yields instances matching the given query arguments.

For example, this would yield all Project:

Project.where()

And this would yield all launch approved Project:

Project.where(launch_approved=True)
exception panoptes_client.panoptes.ReadOnlyAttributeException[source]

Bases: Exception

Raised if an attempt is made to modify an attribute of a PanoptesObject which the API does not allow to be modified.

panoptes_client.classification module

class panoptes_client.classification.Classification(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject

classmethod where(scope=None, **kwargs)[source]

Like PanoptesObject.where(), but also allows setting the query scope.

Examples:

my_classifications = Classification.where()
my_proj_123_classifications = Classification.where(project_id=123)

all_proj_123_classifications = Classification.where(
    scope='project',
    project_id=123,
)

panoptes_client.collection module

class panoptes_client.collection.Collection(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject

add(subjects)[source]

A wrapper around LinkCollection.add(). Equivalent to:

collection.links.add(subjects)
classmethod find(id='', slug=None)[source]

Similar to PanoptesObject.find(), but allows lookup by slug as well as ID.

Examples:

collection_1234 = Collection.find(1234)
my_collection = Collection.find(slug="example/my-collection")
remove(subjects)[source]

A wrapper around LinkCollection.remove(). Equivalent to:

collection.links.remove(subjects)
set_default_subject(subject)[source]

Sets the subject’s location media URL as a link. It displays as the default subject on PFE.

  • subject can be a single Subject instance or a single subject ID.

Examples:

collection.set_default_subject(1234)
collection.set_default_subject(Subject(1234))
subjects

A generator which yields each Subject in this collection.

panoptes_client.exportable module

class panoptes_client.exportable.Exportable[source]

Bases: object

Abstract class containing methods for generating and downloading data exports.

describe_export(export_type)[source]

Fetch metadata for an export.

  • export_type is a string specifying which type of export to look up.

Returns a dict containing metadata for the export.

generate_export(export_type)[source]

Start a new export.

  • export_type is a string specifying which type of export to start.

Returns a dict containing metadata for the new export.

get_export(export_type, generate=False, wait=False, wait_timeout=None)[source]

Downloads a data export over HTTP. Returns a Requests Response object containing the content of the export.

  • export_type is a string specifying which type of export should be downloaded.
  • generate is a boolean specifying whether to generate a new export and wait for it to be ready, or to just download the latest export.
  • wait is a boolean specifying whether to wait for an in-progress export to finish, if there is one. Has no effect if generate is True.
  • wait_timeout is the number of seconds to wait if wait is True. Has no effect if wait is False or if generate is True.

The returned Response object has two additional attributes as a convenience for working with the CSV content; csv_reader and csv_dictreader, which are wrappers for csv.reader() and csv.DictReader respectively. These wrappers take care of correctly decoding the export content for the CSV parser.

Example:

classification_export = Project(1234).get_export('classifications')
for row in classification_export.csv_reader():
    print(row)

classification_export = Project(1234).get_export('classifications')
for row in classification_export.csv_dictreader():
    print(row)
wait_export(export_type, timeout=None)[source]

Blocks until an in-progress export is ready.

  • export_type is a string specifying which type of export to wait for.
  • timeout is the maximum number of seconds to wait.

If timeout is given and the export is not ready by the time limit, PanoptesAPIException is raised.

panoptes_client.project module

class panoptes_client.project.Project(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject, panoptes_client.exportable.Exportable

add_subject_sets(subject_sets)[source]

Links the given subject sets to this project. New subject sets are created as copies of the given sets.

  • subject_sets can be a list of SubjectSet instances, a list of subject set IDs, a single SubjectSet instance, or a single subject set ID.

Examples:

project.add_subject_sets(1234)
project.add_subject_sets([1,2,3,4])
project.add_subject_sets(SubjectSet(1234))
project.add_subject_sets([SubjectSet(12), SubjectSet(34)])
add_workflows(workflows)[source]

Links the given workflows to this project. New workflows are created as copies of the given workflows.

  • workflows can be a list of Workflow instances, a list of workflow IDs, a single 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)])
avatar

A dict containing metadata about the project’s avatar.

collaborators(*roles)[source]

Returns a list of User who are collaborators on this project.

Zero or more role arguments can be passed as strings to narrow down the results. If any roles are given, users who possess at least one of the given roles are returned.

Examples:

all_collabs = project.collaborators()
moderators = project.collaborators("moderators")
moderators_and_translators = project.collaborators(
    "moderators",
    "translators",
)
classmethod find(id='', slug=None)[source]

Similar to PanoptesObject.find(), but allows lookup by slug as well as ID.

Examples:

project_1234 = Project.find(1234)
galaxy_zoo = Project.find(slug="zooniverse/galaxy-zoo")
class panoptes_client.project.ProjectLinkCollection(cls, slug, parent, linked_objects)[source]

Bases: panoptes_client.panoptes.LinkCollection

add(objs)[source]

Adds the given objs to this LinkCollection.

Examples:

organization.links.projects.add(1234)
organization.links.projects.add(Project(1234))
workflow.links.subject_sets.add([1,2,3,4])
workflow.links.subject_sets.add([Project(12), Project(34)])

panoptes_client.project_preferences module

class panoptes_client.project_preferences.ProjectPreferences(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject

Contains the settings for a User on a Project.

classmethod find(id='', user=None, project=None)[source]

Like PanoptesObject.find() but can also query by user and project.

  • user and project can be either a User and Project instance respectively, or they can be given as IDs. If either argument is given, the other is also required.
classmethod save_settings(project=None, user=None, settings=None)[source]

Save settings for a user without first fetching their preferences.

  • user and project can be either a User and Project instance respectively, or they can be given as IDs. If either argument is given, the other is also required.
  • settings is a dict containing the settings to be saved.

panoptes_client.subject module

class panoptes_client.subject.Subject(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject

add_location(location)[source]

Add a media location to this subject.

  • location can be an open file object, a path to a local file, or a dict containing MIME types and URLs for remote media.

Examples:

subject.add_location(my_file)
subject.add_location('/data/image.jpg')
subject.add_location({'image/png': 'https://example.com/image.png'})
async_save_result

Retrieves the result of this subject’s asynchronous save.

  • Returns True if the subject was saved successfully.
  • Raises concurrent.futures.CancelledError if the save was cancelled.
  • If the save failed, raises the relevant exception.
  • Returns False if the subject hasn’t finished saving or if the subject has not been queued for asynchronous save.
classmethod async_saves()[source]

Returns a context manager to allow asynchronously creating subjects. Using this context manager will create a pool of threads which will create multiple subjects at once and upload any local files simultaneously.

The recommended way to use this is with the with statement:

with Subject.async_saves():
    local_files = [...]
    for filename in local_files:
        s = Subject()
        s.links.project = 1234
        s.add_location(filename)
        s.save()

Alternatively, you can manually shut down the thread pool:

pool = Subject.async_saves()
local_files = [...]
try:
    for filename in local_files:
        s = Subject()
        s.links.project = 1234
        s.add_location(filename)
        s.save()
finally:
    pool.shutdown()
save(client=None)[source]

Like PanoptesObject.save(), but also uploads any local files which have previosly been added to the subject with add_location(). Automatically retries uploads on error.

If multiple local files are to be uploaded, several files will be uploaded simultaneously to save time.

set_raw(raw, etag=None, loaded=True)[source]
exception panoptes_client.subject.UnknownMediaException[source]

Bases: Exception

panoptes_client.subject_set module

class panoptes_client.subject_set.SubjectSet(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject

add(subjects)[source]

A wrapper around LinkCollection.add(). Equivalent to:

subject_set.links.add(subjects)
remove(subjects)[source]

A wrapper around LinkCollection.remove(). Equivalent to:

subject_set.links.remove(subjects)
set_raw(raw, etag=None, loaded=True)[source]
subjects

A generator which yields Subject objects which are in this subject set.

Examples:

for subject in subject_set.subjects:
    print(subject.id)
class panoptes_client.subject_set.SubjectSetLinkCollection(cls, slug, parent, linked_objects)[source]

Bases: panoptes_client.panoptes.LinkCollection

add(objs)[source]

Adds the given objs to this LinkCollection.

Examples:

organization.links.projects.add(1234)
organization.links.projects.add(Project(1234))
workflow.links.subject_sets.add([1,2,3,4])
workflow.links.subject_sets.add([Project(12), Project(34)])
remove(objs)[source]

Removes the given objs from this LinkCollection.

Examples:

organization.links.projects.remove(1234)
organization.links.projects.remove(Project(1234))
workflow.links.subject_sets.remove([1,2,3,4])
workflow.links.subject_sets.remove([Project(12), Project(34)])

panoptes_client.user module

class panoptes_client.user.User(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject

avatar

A dict containing metadata about the user’s avatar.

classmethod where(**kwargs)[source]

Returns a generator which yields instances matching the given query arguments.

For example, this would yield all Project:

Project.where()

And this would yield all launch approved Project:

Project.where(launch_approved=True)

panoptes_client.workflow module

class panoptes_client.workflow.Workflow(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject, panoptes_client.exportable.Exportable

add_subject_sets(subject_sets)[source]

A wrapper around LinkCollection.add(). Equivalent to:

workflow.links.subject_sets.add(subject_sets)
remove_subject_sets(subject_sets)[source]

A wrapper around LinkCollection.remove(). Equivalent to:

workflow.links.subject_sets.remove(subject_sets)
retire_subjects(subjects, reason='other')[source]

Retires subjects in this workflow.

  • subjects can be a list of Subject instances, a list of subject IDs, a single Subject instance, or a single subject ID.
  • reason gives the reason the Subject has been retired. Defaults to other.

Examples:

workflow.retire_subjects(1234)
workflow.retire_subjects([1,2,3,4])
workflow.retire_subjects(Subject(1234))
workflow.retire_subjects([Subject(12), Subject(34)])
versions

A generator which yields all WorkflowVersion instances for this workflow.

panoptes_client.workflow_version module

class panoptes_client.workflow_version.WorkflowVersion(raw={}, etag=None)[source]

Bases: panoptes_client.panoptes.PanoptesObject

classmethod find(_id, workflow)[source]

Like PanoptesObject.find() but also allows lookup by workflow.

save()[source]

Not implemented for this class. It is not possible to modify workflow versions once they are created.

workflow

The Workflow to which this version refers.