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

https://bitbucket.org/cistrome/cistrome-harvard/ · Python · 141 lines · 122 code · 4 blank · 15 comment · 29 complexity · acd958252b158a0430290a36c965fefe MD5 · raw file

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