PageRenderTime 25ms CodeModel.GetById 9ms app.highlight 13ms RepoModel.GetById 1ms app.codeStats 0ms

/lib/galaxy/web/api/samples.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 141 lines | 125 code | 3 blank | 13 comment | 26 complexity | acd958252b158a0430290a36c965fefe MD5 | raw file
  1"""
  2API operations for samples in the Galaxy sample tracking system.
  3"""
  4import logging
  5from galaxy import util
  6from galaxy.web.base.controller import *
  7from galaxy.model.orm import *
  8from galaxy.util.bunch import Bunch
  9
 10log = logging.getLogger( __name__ )
 11
 12class SamplesAPIController( BaseAPIController ):
 13    update_types = Bunch( SAMPLE = [ 'sample_state', 'run_details' ],
 14                          SAMPLE_DATASET = [ 'sample_dataset_transfer_status' ] )
 15    update_type_values = []
 16    for k, v in update_types.items():
 17        update_type_values.extend( v )
 18    @web.expose_api
 19    def index( self, trans, **kwd ):
 20        """
 21        GET /api/requests/{encoded_request_id}/samples
 22        Displays a collection (list) of sample of a sequencing request.
 23        """
 24        try:
 25            request_id = trans.security.decode_id( kwd[ 'request_id' ] )
 26        except TypeError:
 27            trans.response.status = 400
 28            return "Malformed  request id ( %s ) specified, unable to decode." % str( encoded_request_id )
 29        try:
 30            request = trans.sa_session.query( trans.app.model.Request ).get( request_id )
 31        except:
 32            request = None
 33        if not request or not ( trans.user_is_admin() or request.user.id == trans.user.id ):
 34            trans.response.status = 400
 35            return "Invalid request id ( %s ) specified." % str( request_id )
 36        rval = []
 37        for sample in request.samples:
 38            item = sample.get_api_value()
 39            item['url'] = url_for( 'samples', 
 40                                   request_id=trans.security.encode_id( request_id ), 
 41                                   id=trans.security.encode_id( sample.id ) )
 42            item['id'] = trans.security.encode_id( item['id'] )
 43            rval.append( item )
 44        return rval
 45    @web.expose_api
 46    def update( self, trans, id, payload, **kwd ):
 47        """
 48        PUT /api/samples/{encoded_sample_id}
 49        Updates a sample or objects related ( mapped ) to a sample.
 50        """
 51        update_type = None
 52        if 'update_type' not in payload:
 53            trans.response.status = 400
 54            return "Missing required 'update_type' parameter, consult the API documentation for help."
 55        else:
 56            update_type = payload.pop( 'update_type' )
 57        if update_type not in self.update_type_values:
 58            trans.response.status = 400
 59            return "Invalid value for 'update_type' parameter (%s) specified, consult the API documentation for help." % update_type
 60        sample_id = util.restore_text( id )
 61        try:
 62            decoded_sample_id = trans.security.decode_id( sample_id )
 63        except TypeError:
 64            trans.response.status = 400
 65            return "Malformed sample_id (%s) specified, unable to decode." % str( sample_id )
 66        try:
 67            sample = trans.sa_session.query( trans.app.model.Sample ).get( decoded_sample_id )
 68        except:
 69            sample = None
 70        if not sample:
 71            trans.response.status = 400
 72            return "Invalid sample id ( %s ) specified." % str( sample_id )
 73        if not trans.user_is_admin():
 74            trans.response.status = 403
 75            return "You are not authorized to update samples."
 76        requests_admin_controller = trans.webapp.controllers[ 'requests_admin' ]
 77        if update_type == 'run_details':
 78            deferred_plugin = payload.pop( 'deferred_plugin', None )
 79            if deferred_plugin:
 80                try:
 81                    trans.app.job_manager.deferred_job_queue.plugins[deferred_plugin].create_job( trans, sample=sample, **payload )
 82                except:
 83                    log.exception( 'update() called with a deferred job plugin (%s) but creating the deferred job failed:' % deferred_plugin )
 84            status, output = requests_admin_controller.edit_template_info( trans,
 85                                                                           cntrller='api',
 86                                                                           item_type='sample',
 87                                                                           form_type=trans.model.FormDefinition.types.RUN_DETAILS_TEMPLATE,
 88                                                                           sample_id=sample_id,
 89                                                                           **payload )
 90            return status, output
 91        elif update_type == 'sample_state': 
 92            return self.__update_sample_state( trans, sample, sample_id, **payload )
 93        elif update_type == 'sample_dataset_transfer_status': 
 94            # update sample_dataset transfer status
 95            return self.__update_sample_dataset_status( trans, **payload )
 96
 97    def __update_sample_state( self, trans, sample, encoded_sample_id, **payload ):
 98        # only admin user may update sample state in Galaxy sample tracking
 99        if not trans.user_is_admin():
100            trans.response.status = 403
101            return "only an admin user may update sample state in Galaxy sample tracking."
102        if 'new_state' not in payload:
103            trans.response.status = 400
104            return "Missing required parameter: 'new_state'."
105        new_state_name = payload.pop( 'new_state' )
106        comment = payload.get( 'comment', '' )
107        # check if the new state is a valid sample state
108        possible_states = sample.request.type.states
109        new_state = None
110        for state in possible_states:
111            if state.name == new_state_name:
112                new_state = state
113        if not new_state:
114            trans.response.status = 400
115            return "Invalid sample state requested ( %s )." % new_state_name
116        requests_common_cntrller = trans.webapp.controllers[ 'requests_common' ]
117        status, output = requests_common_cntrller.update_sample_state( trans=trans, 
118                                                                       cntrller='api', 
119                                                                       sample_ids=[ encoded_sample_id ],
120                                                                       new_state=new_state,
121                                                                       comment=comment )
122        return status, output
123    def __update_sample_dataset_status( self, trans, **payload ):
124        # only admin user may transfer sample datasets in Galaxy sample tracking
125        if not trans.user_is_admin():
126            trans.response.status = 403
127            return "Only an admin user may transfer sample datasets in Galaxy sample tracking and thus update transfer status."
128        if 'sample_dataset_ids' not in payload or 'new_status' not in payload:
129            trans.response.status = 400
130            return "Missing one or more required parameters: 'sample_dataset_ids' and 'new_status'."
131        sample_dataset_ids = payload.pop( 'sample_dataset_ids' )
132        new_status = payload.pop( 'new_status' )
133        error_msg = payload.get( 'error_msg', '' )
134        requests_admin_cntrller = trans.webapp.controllers[ 'requests_admin' ]
135        status, output = requests_admin_cntrller.update_sample_dataset_status( trans=trans, 
136                                                                               cntrller='api', 
137                                                                               sample_dataset_ids=sample_dataset_ids,
138                                                                               new_status=new_status,
139                                                                               error_msg=error_msg )
140        return status, output
141