Skip to content

Commit

Permalink
API, datasets: create a way to get or create a converted datasets for…
Browse files Browse the repository at this point in the history
… a particular format: api/datasets/:id/converted/:format_ext, and a way to return all existing conversions in a dictionary: api/datasets/:id/converted
  • Loading branch information
carlfeberhard committed Aug 4, 2015
1 parent 253ce7b commit 0b7b0b4
Show file tree
Hide file tree
Showing 3 changed files with 73 additions and 1 deletion.
15 changes: 14 additions & 1 deletion lib/galaxy/managers/datasets.py
Expand Up @@ -367,7 +367,7 @@ def add_serializers( self ):
# derived (not mapped) attributes
'data_type' : lambda i, k, **c: i.datatype.__class__.__module__ + '.' + i.datatype.__class__.__name__,

# TODO: conversions
'converted' : self.serialize_converted_datasets,
# TODO: metadata/extra files
})
# this an abstract superclass, so no views created
Expand Down Expand Up @@ -418,6 +418,19 @@ def serialize_metadata( self, dataset_assoc, key, excluded=None, **context ):

return metadata

def serialize_converted_datasets( self, dataset_assoc, key, **context ):
"""
Return a file extension -> converted dataset encoded id map with all
the existing converted datasets associated with this instance.
This filters out deleted associations.
"""
id_map = {}
for converted in dataset_assoc.implicitly_converted_datasets:
if not converted.deleted and converted.dataset:
id_map[ converted.type ] = self.serialize_id( converted.dataset, 'id' )
return id_map


class DatasetAssociationSerializer( _UnflattenedMetadataDatasetAssociationSerializer ):
# TODO: remove this class - metadata should be a sub-object instead as in the superclass
Expand Down
55 changes: 55 additions & 0 deletions lib/galaxy/webapps/galaxy/api/datasets.py
@@ -1,6 +1,8 @@
"""
API operations on the contents of a history dataset.
"""
from galaxy import model
from galaxy import exceptions as galaxy_exceptions
from galaxy import web
from galaxy.web.framework.helpers import is_true
from galaxy import util
Expand All @@ -25,6 +27,13 @@ def __init__( self, app ):
self.hda_manager = managers.hdas.HDAManager( app )
self.hda_serializer = managers.hdas.HDASerializer( self.app )

def _parse_serialization_params( self, kwd, default_view ):
view = kwd.get( 'view', None )
keys = kwd.get( 'keys' )
if isinstance( keys, basestring ):
keys = keys.split( ',' )
return dict( view=view, keys=keys, default_view=default_view )

@web.expose_api
def index( self, trans, **kwd ):
"""
Expand Down Expand Up @@ -304,3 +313,49 @@ def display( self, trans, history_content_id, history_id,
rval = ( "Could not get display data for dataset: " + str( exception ) )

return rval

@web._future_expose_api_anonymous
def converted( self, trans, dataset_id, ext, **kwargs ):
"""
converted( self, trans, dataset_id, ext, **kwargs )
* GET /api/datasets/{dataset_id}/converted/{ext}
return information about datasets made by converting this dataset
to a new format
:type dataset_id: str
:param dataset_id: the encoded id of the original HDA to check
:type ext: str
:param ext: file extension of the target format or None.
If there is no existing converted dataset for the format in `ext`,
one will be created.
If `ext` is None, a dictionary will be returned of the form
{ <converted extension> : <converted id>, ... } containing all the
*existing* converted datasets.
..note: `view` and `keys` are also available to control the serialization
of individual datasets. They have no effect when `ext` is None.
:rtype: dict
:returns: dictionary containing detailed HDA information
or (if `ext` is None) an extension->dataset_id map
"""
decoded_id = self.decode_id( dataset_id )
hda = self.hda_manager.get_accessible( decoded_id, trans.user )
if ext:
converted = self._get_or_create_converted( trans, hda, ext, **kwargs )
return self.hda_serializer.serialize_to_view( converted,
user=trans.user, trans=trans, **self._parse_serialization_params( kwargs, 'detailed' ) )

return self.hda_serializer.serialize_converted_datasets( hda, 'converted' )

def _get_or_create_converted( self, trans, original, target_ext, **kwargs ):
try:
original.get_converted_dataset( trans, target_ext )
converted = original.get_converted_files_by_type( target_ext )
return converted

except model.NoConverterException:
exc_data = dict( source=original.ext, target=target_ext, available=original.get_converter_types().keys() )
raise galaxy_exceptions.RequestParameterInvalidException( 'Conversion not possible', **exc_data )
4 changes: 4 additions & 0 deletions lib/galaxy/webapps/galaxy/buildapp.py
Expand Up @@ -320,6 +320,10 @@ def populate_api_routes( webapp, app ):
action='import_shared_workflow_deprecated',
conditions=dict( method=['POST'] ) )

# route for creating/getting converted datasets
webapp.mapper.connect( '/api/datasets/:dataset_id/converted', controller='datasets', action='converted', ext=None )
webapp.mapper.connect( '/api/datasets/:dataset_id/converted/:ext', controller='datasets', action='converted' )

# API refers to usages and invocations - these mean the same thing but the
# usage routes should be considered deprecated.
invoke_names = {
Expand Down

0 comments on commit 0b7b0b4

Please sign in to comment.