1 new changeset in galaxy-central:
http://bitbucket.org/galaxy/galaxy-central/changeset/ca6db8f67477/
changeset: ca6db8f67477
user: natefoo
date: 2011-09-14 20:36:38
summary: New API features:
* The @web.require_admin decorator can now be used on API methods
* When using model.model_class.get_api_value(), api_*_visible_keys can now
be mapper attributes to other model classes (get_api_value() recursion)
* Monkeypatch the route mapper to contain a resource_with_deleted() method.
This works just like the existing mapper.resource() method but adds extra
routes.
The following is a supplement to the Routes RESTful services
documentation at:
https://routes.groovie.org/restful.html
Using:
mapper.resources_with_deleted( "message", "items" )
Would result in the same routes as in the use of resource(), with the
addition of:
map.connect("deleted_messages", "/messages/deleted",
controller=messages, action="index", deleted=True,
conditions=dict(method=["GET"])
map.connect("deleted_message", "/messages/deleted/{id}",
controller=messages, action="show", deleted=True,
conditions=dict(method=["GET"])
map.connect("undelete_deleted_message",
"/messages/deleted/{id}/undelete",
controller=messages, action="index",
conditions=dict(method=["POST"])
Which adds to the convention:
GET /messages/deleted => messages.index(deleted=True)
=> url("deleted_messages")
GET /messages/deleted/1 => messages.show(id, deleted=True)
=> url("deleted_message", id=1)
POST /messages/deleted/1/undelete => messages.undelete(id)
=> url("undelete_deleted_message", id=1)
affected #: 3 files (1.7 KB)
--- a/lib/galaxy/model/item_attrs.py Tue Sep 13 16:55:17 2011 -0400
+++ b/lib/galaxy/model/item_attrs.py Wed Sep 14 14:36:38 2011 -0400
@@ -1,4 +1,5 @@
from sqlalchemy.sql.expression import func
+from sqlalchemy.orm.collections import InstrumentedList
# Cannot import galaxy.model b/c it creates a circular import graph.
import galaxy
import logging
@@ -156,6 +157,13 @@
#api_collection_visible_keys = ( 'id' )
#api_element_visible_keys = ( 'id' )
def get_api_value( self, view='collection', value_mapper = None ):
+ def get_value( key, item ):
+ try:
+ return item.get_api_value( view=view, value_mapper=value_mapper )
+ except:
+ if key in value_mapper:
+ return value_mapper.get( key )( item )
+ return item
if value_mapper is None:
value_mapper = {}
rval = {}
@@ -165,9 +173,13 @@
raise Exception( 'Unknown API view: %s' % view )
for key in visible_keys:
try:
- rval[key] = self.__getattribute__( key )
- if key in value_mapper:
- rval[key] = value_mapper.get( key )( rval[key] )
+ item = self.__getattribute__( key )
+ if type( item ) == InstrumentedList:
+ rval[key] = []
+ for i in item:
+ rval[key].append( get_value( key, i ) )
+ else:
+ rval[key] = get_value( key, item )
except AttributeError:
rval[key] = None
return rval
--- a/lib/galaxy/web/framework/__init__.py Tue Sep 13 16:55:17 2011 -0400
+++ b/lib/galaxy/web/framework/__init__.py Wed Sep 14 14:36:38 2011 -0400
@@ -117,7 +117,7 @@
return error
trans.response.set_content_type( "application/json" )
trans.set_user( provided_key.user )
-# Perform api_run_as processing, possibly changing identity
+ # Perform api_run_as processing, possibly changing identity
if 'run_as' in kwargs:
if not trans.user_can_do_run_as():
error_message = 'User does not have permissions to run jobs as
another user'
@@ -147,13 +147,18 @@
def require_admin( func ):
def decorator( self, trans, *args, **kwargs ):
if not trans.user_is_admin():
+ msg = "You must be an administrator to access this feature."
admin_users = trans.app.config.get( "admin_users", ""
).split( "," )
+ user = trans.get_user()
if not admin_users:
- return trans.show_error_message( "You must be logged in as an
administrator to access this feature, but no administrators are set in the Galaxy
configuration." )
- user = trans.get_user()
- if not user:
- return trans.show_error_message( "You must be logged in as an
administrator to access this feature." )
- return trans.show_error_message( "You must be an administrator to access
this feature." )
+ msg = "You must be logged in as an administrator to access this
feature, but no administrators are set in the Galaxy configuration."
+ elif not user:
+ msg = "You must be logged in as an administrator to access this
feature."
+ trans.response.status = 403
+ if trans.response.get_content_type() == 'application/json':
+ return msg
+ else:
+ return trans.show_error_message( msg )
return func( self, trans, *args, **kwargs )
return decorator
--- a/lib/galaxy/web/framework/base.py Tue Sep 13 16:55:17 2011 -0400
+++ b/lib/galaxy/web/framework/base.py Wed Sep 14 14:36:38 2011 -0400
@@ -29,6 +29,21 @@
log = logging.getLogger( __name__ )
+def __resource_with_deleted( self, member_name, collection_name, **kwargs ):
+ """
+ Method to monkeypatch on to routes.mapper.Mapper which does the same thing
+ as resource() with the addition of standardized routes for handling
+ elements in Galaxy's "deleted but not really deleted" fashion.
+ """
+ collection_path = kwargs.get( 'path_prefix', '' ) + '/' +
collection_name + '/deleted'
+ member_path = collection_path + '/:id'
+ self.connect( 'deleted_' + collection_name, collection_path,
controller=collection_name, action='index', deleted=True )
+ self.connect( 'deleted_' + member_name, member_path,
controller=collection_name, action='show', deleted=True )
+ self.connect( 'undelete_deleted_' + member_name, member_path +
'/undelete', controller=collection_name, action='undelete',
+ conditions=dict( method=['POST'] ) )
+ self.resource( member_name, collection_name, **kwargs )
+routes.Mapper.resource_with_deleted = __resource_with_deleted
+
class WebApplication( object ):
"""
A simple web application which maps requests to objects using routes,
@@ -320,6 +335,8 @@
Sets the Content-Type header
"""
self.headers[ "content-type" ] = type
+ def get_content_type( self ):
+ return self.headers[ "content-type" ]
def send_redirect( self, url ):
"""
Send an HTTP redirect response to (target `url`)
Repository URL:
https://bitbucket.org/galaxy/galaxy-central/
--
This is a commit notification from
bitbucket.org. You are receiving
this because you have the service enabled, addressing the recipient of
this email.