# HG changeset patch -- Bitbucket.org # Project galaxy-dist # URL http://bitbucket.org/galaxy/galaxy-dist/overview # User rc # Date 1288122647 14400 # Node ID 49c7938d582799125a89f0d6ba38be0ddc6f4b4f # Parent d73fa5f14b013333b2e49bfbf775db8dd0197e2b sample tracking web api cleaned up - added a samples controller --- /dev/null +++ b/lib/galaxy/web/api/samples.py @@ -0,0 +1,44 @@ +""" +API operations on a sample tracking system. +""" +import logging, os, string, shutil, urllib, re, socket +from cgi import escape, FieldStorage +from galaxy import util, datatypes, jobs, web, util +from galaxy.web.base.controller import * +from galaxy.util.sanitize_html import sanitize_html +from galaxy.model.orm import * +from galaxy.util.bunch import Bunch + +log = logging.getLogger( __name__ ) + +class SamplesController( BaseController ): + + @web.expose_api + def index( self, trans, **kwd ): + """ + GET /api/requests/{encoded_request_id}/samples + Displays a collection (list) of sample of a sequencing request. + """ + try: + request_id = trans.security.decode_id( kwd[ 'request_id' ] ) + except TypeError: + trans.response.status = 400 + return "Malformed request id ( %s ) specified, unable to decode." % str( encoded_request_id ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( request_id ) + except: + request = None + if not request or not ( trans.user_is_admin() or request.user.id == trans.user.id ): + trans.response.status = 400 + return "Invalid request id ( %s ) specified." % str( request_id ) + rval = [] + for sample in request.samples: + item = sample.get_api_value() + item['url'] = url_for( 'samples', + request_id=trans.security.encode_id( request_id ), + id=trans.security.encode_id( sample.id ) ) + item['id'] = trans.security.encode_id( item['id'] ) + rval.append( item ) + return rval + + --- a/lib/galaxy/model/__init__.py +++ b/lib/galaxy/model/__init__.py @@ -1767,6 +1767,7 @@ class RequestTypePermissions( object ): class Sample( object ): bulk_operations = Bunch( CHANGE_STATE = 'Change state', SELECT_LIBRARY = 'Select data library and folder' ) + api_collection_visible_keys = ( 'id', 'name' ) def __init__(self, name=None, desc=None, request=None, form_values=None, bar_code=None, library=None, folder=None): self.name = name self.desc = desc @@ -1818,6 +1819,18 @@ class Sample( object ): pexpect.TIMEOUT:print_ticks}, timeout=10) return output.replace(filepath, '').strip() + def get_api_value( self, view='collection' ): + rval = {} + try: + visible_keys = self.__getattribute__( 'api_' + view + '_visible_keys' ) + except AttributeError: + raise Exception( 'Unknown API view: %s' % view ) + for key in visible_keys: + try: + rval[key] = self.__getattribute__( key ) + except AttributeError: + rval[key] = None + return rval class SampleState( object ): def __init__(self, name=None, desc=None, request_type=None): --- a/lib/galaxy/web/buildapp.py +++ b/lib/galaxy/web/buildapp.py @@ -104,8 +104,15 @@ def app_factory( global_conf, **kwargs ) # If enabled, add the web API if asbool( kwargs.get( 'enable_api', False ) ): add_api_controllers( webapp, app ) - webapp.api_mapper.resource( 'content', 'contents', path_prefix='/api/libraries/:library_id', parent_resources=dict( member_name='library', collection_name='libraries' ) ) + webapp.api_mapper.resource( 'content', + 'contents', + path_prefix='/api/libraries/:library_id', + parent_resources=dict( member_name='library', collection_name='libraries' ) ) webapp.api_mapper.resource( 'library', 'libraries', path_prefix='/api' ) + webapp.api_mapper.resource( 'sample', + 'samples', + path_prefix='/api/requests/:request_id', + parent_resources=dict( member_name='request', collection_name='requests' ) ) webapp.api_mapper.resource( 'request', 'requests', path_prefix='/api' ) webapp.finalize_config() # Wrap the webapp in some useful middleware --- a/lib/galaxy/web/api/requests.py +++ b/lib/galaxy/web/api/requests.py @@ -22,23 +22,57 @@ class RequestsController( BaseController GET /api/requests Displays a collection (list) of sequencing requests. """ - query = trans.sa_session.query( trans.app.model.Request )\ - .filter( and_( trans.app.model.Request.table.c.user_id == trans.user.id \ - and trans.app.model.Request.table.c.deleted == False ) ) \ - .all() + # if admin user then return all requests + if trans.user_is_admin(): + query = trans.sa_session.query( trans.app.model.Request )\ + .filter( trans.app.model.Request.table.c.deleted == False )\ + .all() + else: + query = trans.sa_session.query( trans.app.model.Request )\ + .filter( and_( trans.app.model.Request.table.c.user_id == trans.user.id \ + and trans.app.model.Request.table.c.deleted == False ) ) \ + .all() rval = [] for request in query: item = request.get_api_value() item['url'] = url_for( 'requests', id=trans.security.encode_id( request.id ) ) item['id'] = trans.security.encode_id( item['id'] ) + if trans.user_is_admin(): + item['user'] = request.user.email rval.append( item ) return rval - + + @web.expose_api + def show( self, trans, id, **kwd ): + """ + GET /api/requests/{encoded_request_id} + Displays details of a sequencing request. + """ + try: + request_id = trans.security.decode_id( id ) + except TypeError: + trans.response.status = 400 + return "Malformed %s id ( %s ) specified, unable to decode." % ( update_type, str( id ) ) + try: + request = trans.sa_session.query( trans.app.model.Request ).get( request_id ) + except: + request = None + if not request or not ( trans.user_is_admin() or request.user.id == trans.user.id ): + trans.response.status = 400 + return "Invalid request id ( %s ) specified." % str( request_id ) + item = request.get_api_value() + item['url'] = url_for( 'requests', id=trans.security.encode_id( request.id ) ) + item['id'] = trans.security.encode_id( item['id'] ) + item['user'] = request.user.email + item['num_of_samples'] = len(request.samples) + return item + @web.expose_api def update( self, trans, id, key, payload, **kwd ): """ PUT /api/requests/{encoded_request_id} - Displays information about a sequencing request. + Updates a request state, sample state or sample dataset transfer status + depending on the update_type """ params = util.Params( kwd ) update_type = None @@ -124,7 +158,3 @@ class RequestsController( BaseController new_status=new_status, error_msg=error_msg ) return status, output - - - -