def wrap_in_middleware(app, global_conf, application_stack, **local_conf): """Based on the configuration wrap `app` in a set of common and useful middleware.""" stack = application_stack # Merge the global and local configurations conf = global_conf.copy() conf.update(local_conf) debug = asbool(conf.get('debug', False)) # First put into place httpexceptions, which must be most closely # wrapped around the application (it can interact poorly with # other middleware): app = wrap_if_allowed(app, stack, httpexceptions.make_middleware, name='paste.httpexceptions', args=(conf,)) # The recursive middleware allows for including requests in other # requests or forwarding of requests, all on the server side. if asbool(conf.get('use_recursive', True)): from paste import recursive app = wrap_if_allowed(app, stack, recursive.RecursiveMiddleware, args=(conf,)) # Various debug middleware that can only be turned on if the debug # flag is set, either because they are insecure or greatly hurt # performance if debug: # Middleware to check for WSGI compliance if asbool(conf.get('use_lint', True)): from paste import lint app = wrap_if_allowed(app, stack, lint.make_middleware, name='paste.lint', args=(conf,)) # Middleware to run the python profiler on each request if asbool(conf.get('use_profile', False)): import profile app = wrap_if_allowed(app, stack, profile.ProfileMiddleware, args=(conf,)) # Middleware that intercepts print statements and shows them on the # returned page if asbool(conf.get('use_printdebug', True)): from paste.debug import prints app = wrap_if_allowed(app, stack, prints.PrintDebugMiddleware, args=(conf,)) if debug and asbool(conf.get('use_interactive', False)): # Interactive exception debugging, scary dangerous if publicly # accessible, if not enabled we'll use the regular error printing # middleware. try: from weberror import evalexception app = wrap_if_allowed_or_fail(app, stack, evalexception.EvalException, args=(conf,), kwargs=dict(templating_formatters=build_template_error_formatters())) except MiddlewareWrapUnsupported as exc: log.warning(str(exc)) import galaxy.web.framework.middleware.error app = wrap_if_allowed(app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf,)) else: # Not in interactive debug mode, just use the regular error middleware import galaxy.web.framework.middleware.error app = wrap_if_allowed(app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf,)) # Transaction logging (apache access.log style) if asbool(conf.get('use_translogger', True)): from paste.translogger import TransLogger app = wrap_if_allowed(app, stack, TransLogger) # X-Forwarded-Host handling from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware app = wrap_if_allowed(app, stack, XForwardedHostMiddleware) return app
def app_factory(global_conf, load_app_kwds={}, **kwargs): """Return a wsgi application serving the root object""" # Create the Galaxy application unless passed in kwargs = load_app_properties( kwds=kwargs, **load_app_kwds ) if 'app' in kwargs: app = kwargs.pop('app') else: from galaxy.webapps.reports.app import UniverseApplication app = UniverseApplication(global_conf=global_conf, **kwargs) atexit.register(app.shutdown) # Create the universe WSGI application webapp = ReportsWebApplication(app, session_cookie='galaxyreportssession', name="reports") add_ui_controllers(webapp, app) # These two routes handle our simple needs at the moment webapp.add_route('/{controller}/{action}', controller="root", action='index') webapp.add_route('/{action}', controller='root', action='index') webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get('middleware', True): webapp = wrap_in_middleware(webapp, global_conf, app.application_stack, **kwargs) if asbool(kwargs.get('static_enabled', True)): webapp = wrap_if_allowed(webapp, app.application_stack, wrap_in_static, args=(global_conf,), kwargs=kwargs) # Close any pooled database connections before forking try: galaxy.model.mapping.metadata.bind.dispose() except: log.exception("Unable to dispose of pooled galaxy model database connections.") # Return return webapp
def app_factory(global_conf, load_app_kwds=None, **kwargs): """Return a wsgi application serving the root object""" # Create the Galaxy application unless passed in load_app_kwds = load_app_kwds or {} kwargs = load_app_properties(kwds=kwargs, **load_app_kwds) if 'app' in kwargs: app = kwargs.pop('app') else: from galaxy.webapps.reports.app import UniverseApplication app = UniverseApplication(global_conf=global_conf, **kwargs) atexit.register(app.shutdown) # Create the universe WSGI application webapp = ReportsWebApplication(app, session_cookie='galaxyreportssession', name="reports") add_ui_controllers(webapp, app) # These two routes handle our simple needs at the moment webapp.add_route('/{controller}/{action}', controller="root", action='index') webapp.add_route('/{action}', controller='root', action='index') webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get('middleware', True): webapp = wrap_in_middleware(webapp, global_conf, app.application_stack, **kwargs) if asbool(kwargs.get('static_enabled', True)): webapp = wrap_if_allowed(webapp, app.application_stack, build_url_map, args=(global_conf, ), kwargs=kwargs) return webapp
def app_factory(global_conf, load_app_kwds={}, **kwargs): """Return a wsgi application serving the root object""" # Create the Galaxy application unless passed in kwargs = load_app_properties( kwds=kwargs, **load_app_kwds ) if 'app' in kwargs: app = kwargs.pop('app') else: from galaxy.webapps.reports.app import UniverseApplication app = UniverseApplication(global_conf=global_conf, **kwargs) atexit.register(app.shutdown) # Create the universe WSGI application webapp = ReportsWebApplication(app, session_cookie='galaxyreportssession', name="reports") add_ui_controllers(webapp, app) # These two routes handle our simple needs at the moment webapp.add_route('/{controller}/{action}', controller="root", action='index') webapp.add_route('/{action}', controller='root', action='index') webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get('middleware', True): webapp = wrap_in_middleware(webapp, global_conf, app.application_stack, **kwargs) if asbool(kwargs.get('static_enabled', True)): webapp = wrap_if_allowed(webapp, app.application_stack, wrap_in_static, args=(global_conf,), kwargs=kwargs) # Close any pooled database connections before forking try: galaxy.model.mapping.metadata.bind.dispose() except Exception: log.exception("Unable to dispose of pooled galaxy model database connections.") # Return return webapp
def app_factory(global_conf, load_app_kwds={}, **kwargs): """Return a wsgi application serving the root object""" # Create the Galaxy tool shed application unless passed in kwargs = load_app_properties(kwds=kwargs, config_prefix='TOOL_SHED_CONFIG_', **load_app_kwds) if 'app' in kwargs: app = kwargs.pop('app') else: try: from galaxy.webapps.tool_shed.app import UniverseApplication app = UniverseApplication(global_conf=global_conf, **kwargs) except Exception: import traceback import sys traceback.print_exc() sys.exit(1) atexit.register(app.shutdown) # Create the universe WSGI application webapp = CommunityWebApplication(app, session_cookie='galaxycommunitysession', name="tool_shed") add_ui_controllers(webapp, app) webapp.add_route('/view/{owner}', controller='repository', action='sharable_owner') webapp.add_route('/view/{owner}/{name}', controller='repository', action='sharable_repository') webapp.add_route('/view/{owner}/{name}/{changeset_revision}', controller='repository', action='sharable_repository_revision') # Handle displaying tool help images and README file images for tools contained in repositories. webapp.add_route( '/repository/static/images/{repository_id}/{image_file:.+?}', controller='repository', action='display_image_in_repository', repository_id=None, image_file=None) webapp.add_route('/{controller}/{action}', action='index') webapp.add_route('/{action}', controller='repository', action='index') # Enable 'hg clone' functionality on repos by letting hgwebapp handle the request webapp.add_route('/repos/*path_info', controller='hg', action='handle_request', path_info='/') # Add the web API. # A good resource for RESTful services - https://routes.readthedocs.io/en/latest/restful.html webapp.add_api_controllers('galaxy.webapps.tool_shed.api', app) webapp.mapper.connect('api_key_retrieval', '/api/authenticate/baseauth/', controller='authenticate', action='get_tool_shed_api_key', conditions=dict(method=["GET"])) webapp.mapper.connect('group', '/api/groups/', controller='groups', action='index', conditions=dict(method=["GET"])) webapp.mapper.connect('group', '/api/groups/', controller='groups', action='create', conditions=dict(method=["POST"])) webapp.mapper.connect('group', '/api/groups/{encoded_id}', controller='groups', action='show', conditions=dict(method=["GET"])) webapp.mapper.resource('category', 'categories', controller='categories', name_prefix='category_', path_prefix='/api', parent_resources=dict(member_name='category', collection_name='categories')) webapp.mapper.connect('repositories_in_category', '/api/categories/{category_id}/repositories', controller='categories', action='get_repositories', conditions=dict(method=["GET"])) webapp.mapper.connect('show_updates_for_repository', '/api/repositories/updates', controller='repositories', action='updates', conditions=dict(method=["GET"])) webapp.mapper.resource('repository', 'repositories', controller='repositories', collection={ 'add_repository_registry_entry': 'POST', 'get_repository_revision_install_info': 'GET', 'get_ordered_installable_revisions': 'GET', 'get_installable_revisions': 'GET', 'remove_repository_registry_entry': 'POST', 'repository_ids_for_setting_metadata': 'GET', 'reset_metadata_on_repositories': 'POST', 'reset_metadata_on_repository': 'POST' }, name_prefix='repository_', path_prefix='/api', new={'import_capsule': 'POST'}, parent_resources=dict( member_name='repository', collection_name='repositories')) webapp.mapper.resource('repository_revision', 'repository_revisions', member={ 'repository_dependencies': 'GET', 'export': 'POST' }, controller='repository_revisions', name_prefix='repository_revision_', path_prefix='/api', parent_resources=dict( member_name='repository_revision', collection_name='repository_revisions')) webapp.mapper.resource('user', 'users', controller='users', name_prefix='user_', path_prefix='/api', parent_resources=dict(member_name='user', collection_name='users')) webapp.mapper.connect('update_repository', '/api/repositories/{id}', controller='repositories', action='update', conditions=dict(method=["PATCH", "PUT"])) webapp.mapper.connect('repository_create_changeset_revision', '/api/repositories/{id}/changeset_revision', controller='repositories', action='create_changeset_revision', conditions=dict(method=["POST"])) webapp.mapper.connect('repository_get_metadata', '/api/repositories/{id}/metadata', controller='repositories', action='metadata', conditions=dict(method=["GET"])) webapp.mapper.connect('repository_show_tools', '/api/repositories/{id}/{changeset}/show_tools', controller='repositories', action='show_tools', conditions=dict(method=["GET"])) webapp.mapper.connect('create_repository', '/api/repositories', controller='repositories', action='create', conditions=dict(method=["POST"])) webapp.mapper.connect('tools', '/api/tools', controller='tools', action='index', conditions=dict(method=["GET"])) webapp.mapper.connect('json', '/api/tools/json', controller='tools', action='json', conditions=dict(method=["GET"])) webapp.mapper.connect("version", "/api/version", controller="configuration", action="version", conditions=dict(method=["GET"])) webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get('middleware', True): webapp = wrap_in_middleware(webapp, global_conf, app.application_stack, **kwargs) if asbool(kwargs.get('static_enabled', True)): webapp = wrap_if_allowed(webapp, app.application_stack, wrap_in_static, args=(global_conf, ), kwargs=kwargs) # Close any pooled database connections before forking try: galaxy.webapps.tool_shed.model.mapping.metadata.bind.dispose() except Exception: log.exception( "Unable to dispose of pooled tool_shed model database connections." ) # Return return webapp
def wrap_in_middleware(app, global_conf, application_stack, **local_conf): """Based on the configuration wrap `app` in a set of common and useful middleware.""" stack = application_stack # Merge the global and local configurations conf = global_conf.copy() conf.update(local_conf) debug = asbool(conf.get('debug', False)) interactive = asbool(conf.get('use_interactive', False)) # First put into place httpexceptions, which must be most closely # wrapped around the application (it can interact poorly with # other middleware): app = wrap_if_allowed(app, stack, httpexceptions.make_middleware, name='paste.httpexceptions', args=(conf, )) # Create a separate mapper for redirects to prevent conflicts. redirect_mapper = routes.Mapper() redirect_mapper = _map_redirects(redirect_mapper) # Load the Routes middleware which we use for redirecting app = wrap_if_allowed(app, stack, RoutesMiddleware, args=(redirect_mapper, )) # If we're using remote_user authentication, add middleware that # protects Galaxy from improperly configured authentication in the # upstream server if asbool(conf.get('use_remote_user', False)): from galaxy.webapps.tool_shed.framework.middleware.remoteuser import RemoteUser app = wrap_if_allowed( app, stack, RemoteUser, kwargs=dict( maildomain=conf.get('remote_user_maildomain', None), display_servers=util.listify(conf.get('display_servers', '')), admin_users=conf.get('admin_users', '').split(','), remote_user_header=conf.get('remote_user_header', 'HTTP_REMOTE_USER'), remote_user_secret_header=conf.get('remote_user_secret', None), normalize_remote_user_email=conf.get( 'normalize_remote_user_email', False))) # The recursive middleware allows for including requests in other # requests or forwarding of requests, all on the server side. if asbool(conf.get('use_recursive', True)): from paste import recursive app = wrap_if_allowed(app, stack, recursive.RecursiveMiddleware, args=(conf, )) # Transaction logging (apache access.log style) if asbool(conf.get('use_translogger', True)): from paste.translogger import TransLogger app = wrap_if_allowed(app, stack, TransLogger) # If sentry logging is enabled, log here before propogating up to # the error middleware # TODO sentry config is duplicated between tool_shed/galaxy, refactor this. sentry_dsn = conf.get('sentry_dsn', None) if sentry_dsn: from galaxy.web.framework.middleware.sentry import Sentry app = wrap_if_allowed(app, stack, Sentry, args=(sentry_dsn, )) # X-Forwarded-Host handling from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware app = wrap_if_allowed(app, stack, XForwardedHostMiddleware) # Various debug middleware that can only be turned on if the debug # flag is set, either because they are insecure or greatly hurt # performance. if debug: # Middleware to check for WSGI compliance if asbool(conf.get('use_lint', True)): from paste import lint app = wrap_if_allowed(app, stack, lint.make_middleware, name='paste.lint', args=(conf, )) # Middleware to run the python profiler on each request if asbool(conf.get('use_profile', False)): from paste.debug import profile app = wrap_if_allowed(app, stack, profile.ProfileMiddleware, args=(conf, )) if interactive: # Interactive exception debugging, scary dangerous if publicly # accessible, if not enabled we'll use the regular error printing # middleware. try: from weberror import evalexception app = wrap_if_allowed_or_fail( app, stack, evalexception.EvalException, args=(conf, ), kwargs=dict( templating_formatters=build_template_error_formatters( ))) except MiddlewareWrapUnsupported as exc: log.warning(util.unicodify(exc)) import galaxy.web.framework.middleware.error app = wrap_if_allowed( app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf, )) else: # Not in interactive debug mode, just use the regular error middleware import galaxy.web.framework.middleware.error app = wrap_if_allowed( app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf, )) return app
def paste_app_factory( global_conf, **kwargs ): """ Return a wsgi application serving the root object """ kwargs = load_app_properties( kwds=kwargs ) # Create the Galaxy application unless passed in if 'app' in kwargs: app = kwargs.pop( 'app' ) galaxy.app.app = app else: try: app = galaxy.app.UniverseApplication( global_conf=global_conf, **kwargs ) galaxy.app.app = app except: import traceback traceback.print_exc() sys.exit( 1 ) # Call app's shutdown method when the interpeter exits, this cleanly stops # the various Galaxy application daemon threads atexit.register( app.shutdown ) # Create the universe WSGI application webapp = GalaxyWebApplication( app, session_cookie='galaxysession', name='galaxy' ) # STANDARD CONTROLLER ROUTES webapp.add_ui_controllers( 'galaxy.webapps.galaxy.controllers', app ) # Force /history to go to view of current webapp.add_route( '/history', controller='history', action='view' ) webapp.add_route( '/history/view/{id}', controller='history', action='view' ) # THIS IS A TEMPORARY ROUTE FOR THE 17.01 RELEASE # This route supports the previous hide/delete-all-hidden functionality in a history. # It will be removed after 17.01. webapp.add_route( '/history/adjust_hidden', controller='history', action='adjust_hidden') # Force /activate to go to the controller webapp.add_route( '/activate', controller='user', action='activate' ) webapp.add_route( '/login', controller='root', action='login' ) # These two routes handle our simple needs at the moment webapp.add_route( '/async/{tool_id}/{data_id}/{data_secret}', controller='async', action='index', tool_id=None, data_id=None, data_secret=None ) webapp.add_route( '/{controller}/{action}', action='index' ) webapp.add_route( '/{action}', controller='root', action='index' ) # allow for subdirectories in extra_files_path webapp.add_route( '/datasets/{dataset_id}/display/{filename:.+?}', controller='dataset', action='display', dataset_id=None, filename=None) webapp.add_route( '/datasets/{dataset_id}/{action}/{filename}', controller='dataset', action='index', dataset_id=None, filename=None) webapp.add_route( '/display_application/{dataset_id}/{app_name}/{link_name}/{user_id}/{app_action}/{action_param}/{action_param_extra:.+?}', controller='dataset', action='display_application', dataset_id=None, user_id=None, app_name=None, link_name=None, app_action=None, action_param=None, action_param_extra=None ) webapp.add_route( '/u/{username}/d/{slug}/{filename}', controller='dataset', action='display_by_username_and_slug', filename=None ) webapp.add_route( '/u/{username}/p/{slug}', controller='page', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/h/{slug}', controller='history', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/w/{slug}', controller='workflow', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/w/{slug}/{format}', controller='workflow', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/v/{slug}', controller='visualization', action='display_by_username_and_slug' ) webapp.add_route( '/search', controller='search', action='index' ) # TODO: Refactor above routes into external method to allow testing in # isolation as well. populate_api_routes( webapp, app ) # CLIENTSIDE ROUTES # The following are routes that are handled completely on the clientside. # The following routes don't bootstrap any information, simply provide the # base analysis interface at which point the application takes over. webapp.add_client_route( '/tours' ) webapp.add_client_route( '/tours/{tour_id}' ) webapp.add_client_route( '/user' ) webapp.add_client_route( '/user/{form_id}' ) # ==== Done # Indicate that all configuration settings have been provided webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get( 'middleware', True ): webapp = wrap_in_middleware(webapp, global_conf, app.application_stack, **kwargs) if asbool( kwargs.get( 'static_enabled', True) ): webapp = wrap_if_allowed(webapp, app.application_stack, wrap_in_static, args=(global_conf,), kwargs=dict(plugin_frameworks=[app.visualizations_registry], **kwargs)) # Close any pooled database connections before forking try: galaxy.model.mapping.metadata.bind.dispose() except: log.exception("Unable to dispose of pooled galaxy model database connections.") try: # This model may not actually be bound. if galaxy.model.tool_shed_install.mapping.metadata.bind: galaxy.model.tool_shed_install.mapping.metadata.bind.dispose() except: log.exception("Unable to dispose of pooled toolshed install model database connections.") app.application_stack.register_postfork_function(postfork_setup) for th in threading.enumerate(): if th.is_alive(): log.debug("Prior to webapp return, Galaxy thread %s is alive.", th) # Return return webapp
def wrap_in_middleware( app, global_conf, application_stack, **local_conf ): """ Based on the configuration wrap `app` in a set of common and useful middleware. """ webapp = app stack = application_stack # Merge the global and local configurations conf = global_conf.copy() conf.update(local_conf) debug = asbool( conf.get( 'debug', False ) ) # First put into place httpexceptions, which must be most closely # wrapped around the application (it can interact poorly with # other middleware): app = wrap_if_allowed( app, stack, httpexceptions.make_middleware, name='paste.httpexceptions', args=(conf,) ) # Statsd request timing and profiling statsd_host = conf.get('statsd_host', None) if statsd_host: from galaxy.web.framework.middleware.statsd import StatsdMiddleware app = wrap_if_allowed( app, stack, StatsdMiddleware, args=( statsd_host, conf.get('statsd_port', 8125), conf.get('statsd_prefix', 'galaxy') ) ) log.debug( "Enabling 'statsd' middleware" ) # graphite request timing and profiling graphite_host = conf.get('graphite_host', None) if graphite_host: from galaxy.web.framework.middleware.graphite import GraphiteMiddleware app = wrap_if_allowed( app, stack, GraphiteMiddleware, args=( graphite_host, conf.get('graphite_port', 2003), conf.get('graphite_prefix', 'galaxy') ) ) log.debug( "Enabling 'graphite' middleware" ) # If we're using remote_user authentication, add middleware that # protects Galaxy from improperly configured authentication in the # upstream server single_user = conf.get( 'single_user', None ) use_remote_user = asbool(conf.get( 'use_remote_user', False )) or single_user if use_remote_user: from galaxy.web.framework.middleware.remoteuser import RemoteUser app = wrap_if_allowed( app, stack, RemoteUser, kwargs=dict( maildomain=conf.get('remote_user_maildomain', None), display_servers=util.listify( conf.get('display_servers', '')), single_user=single_user, admin_users=conf.get('admin_users', '').split(','), remote_user_header=conf.get('remote_user_header', 'HTTP_REMOTE_USER'), remote_user_secret_header=conf.get('remote_user_secret', None), normalize_remote_user_email=conf.get('normalize_remote_user_email', False)) ) # The recursive middleware allows for including requests in other # requests or forwarding of requests, all on the server side. if asbool(conf.get('use_recursive', True)): from paste import recursive app = wrap_if_allowed( app, stack, recursive.RecursiveMiddleware, args=(conf,) ) # If sentry logging is enabled, log here before propogating up to # the error middleware sentry_dsn = conf.get( 'sentry_dsn', None ) if sentry_dsn: from galaxy.web.framework.middleware.sentry import Sentry app = wrap_if_allowed( app, stack, Sentry, args=(sentry_dsn,) ) # Various debug middleware that can only be turned on if the debug # flag is set, either because they are insecure or greatly hurt # performance if debug: # Middleware to check for WSGI compliance if asbool( conf.get( 'use_lint', False ) ): from paste import lint app = wrap_if_allowed( app, stack, lint.make_middleware, name='paste.lint', args=(conf,) ) # Middleware to run the python profiler on each request if asbool( conf.get( 'use_profile', False ) ): from paste.debug import profile app = wrap_if_allowed( app, stack, profile.ProfileMiddleware, args=(conf,) ) if debug and asbool( conf.get( 'use_interactive', False ) ): # Interactive exception debugging, scary dangerous if publicly # accessible, if not enabled we'll use the regular error printing # middleware. try: from weberror import evalexception app = wrap_if_allowed_or_fail( app, stack, evalexception.EvalException, args=(conf,), kwargs=dict(templating_formatters=build_template_error_formatters()) ) except MiddlewareWrapUnsupported as exc: log.warning(str(exc)) import galaxy.web.framework.middleware.error app = wrap_if_allowed( app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf,) ) else: # Not in interactive debug mode, just use the regular error middleware import galaxy.web.framework.middleware.error app = wrap_if_allowed( app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf,) ) # Transaction logging (apache access.log style) if asbool( conf.get( 'use_translogger', True ) ): from galaxy.web.framework.middleware.translogger import TransLogger app = wrap_if_allowed( app, stack, TransLogger ) # X-Forwarded-Host handling from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware app = wrap_if_allowed( app, stack, XForwardedHostMiddleware ) # Request ID middleware from galaxy.web.framework.middleware.request_id import RequestIDMiddleware app = wrap_if_allowed( app, stack, RequestIDMiddleware ) # api batch call processing middleware from galaxy.web.framework.middleware.batch import BatchMiddleware app = wrap_if_allowed( app, stack, BatchMiddleware, args=(webapp, {}) ) return app
def paste_app_factory( global_conf, **kwargs ): """ Return a wsgi application serving the root object """ kwargs = load_app_properties( kwds=kwargs ) # Create the Galaxy application unless passed in if 'app' in kwargs: app = kwargs.pop( 'app' ) galaxy.app.app = app else: try: app = galaxy.app.UniverseApplication( global_conf=global_conf, **kwargs ) galaxy.app.app = app except: import traceback traceback.print_exc() sys.exit( 1 ) # Call app's shutdown method when the interpeter exits, this cleanly stops # the various Galaxy application daemon threads atexit.register( app.shutdown ) # Create the universe WSGI application webapp = GalaxyWebApplication( app, session_cookie='galaxysession', name='galaxy' ) # STANDARD CONTROLLER ROUTES webapp.add_ui_controllers( 'galaxy.webapps.galaxy.controllers', app ) # Force /history to go to view of current webapp.add_route( '/history', controller='history', action='view' ) webapp.add_route( '/history/view/{id}', controller='history', action='view' ) # Force /activate to go to the controller webapp.add_route( '/activate', controller='user', action='activate' ) # These two routes handle our simple needs at the moment webapp.add_route( '/async/{tool_id}/{data_id}/{data_secret}', controller='async', action='index', tool_id=None, data_id=None, data_secret=None ) webapp.add_route( '/{controller}/{action}', action='index' ) webapp.add_route( '/{action}', controller='root', action='index' ) # allow for subdirectories in extra_files_path webapp.add_route( '/datasets/{dataset_id}/display/{filename:.+?}', controller='dataset', action='display', dataset_id=None, filename=None) webapp.add_route( '/datasets/{dataset_id}/{action}/{filename}', controller='dataset', action='index', dataset_id=None, filename=None) webapp.add_route( '/display_application/{dataset_id}/{app_name}/{link_name}/{user_id}/{app_action}/{action_param}/{action_param_extra:.+?}', controller='dataset', action='display_application', dataset_id=None, user_id=None, app_name=None, link_name=None, app_action=None, action_param=None, action_param_extra=None ) webapp.add_route( '/u/{username}/d/{slug}/{filename}', controller='dataset', action='display_by_username_and_slug', filename=None ) webapp.add_route( '/u/{username}/p/{slug}', controller='page', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/h/{slug}', controller='history', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/w/{slug}', controller='workflow', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/w/{slug}/{format}', controller='workflow', action='display_by_username_and_slug' ) webapp.add_route( '/u/{username}/v/{slug}', controller='visualization', action='display_by_username_and_slug' ) # TODO: Refactor above routes into external method to allow testing in # isolation as well. populate_api_routes( webapp, app ) # CLIENTSIDE ROUTES # The following are routes that are handled completely on the clientside. # The following routes don't bootstrap any information, simply provide the # base analysis interface at which point the application takes over. webapp.add_client_route( '/tours' ) webapp.add_client_route( '/tours/{tour_id}' ) webapp.add_client_route( '/user' ) webapp.add_client_route( '/user/{form_id}' ) webapp.add_client_route( '/custom_builds' ) # ==== Done # Indicate that all configuration settings have been provided webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get( 'middleware', True ): webapp = wrap_in_middleware(webapp, global_conf, app.application_stack, **kwargs) if asbool( kwargs.get( 'static_enabled', True) ): webapp = wrap_if_allowed(webapp, app.application_stack, wrap_in_static, args=(global_conf,), kwargs=dict(plugin_frameworks=[app.visualizations_registry], **kwargs)) # Close any pooled database connections before forking try: galaxy.model.mapping.metadata.bind.dispose() except: log.exception("Unable to dispose of pooled galaxy model database connections.") try: # This model may not actually be bound. if galaxy.model.tool_shed_install.mapping.metadata.bind: galaxy.model.tool_shed_install.mapping.metadata.bind.dispose() except: log.exception("Unable to dispose of pooled toolshed install model database connections.") app.application_stack.register_postfork_function(postfork_setup) for th in threading.enumerate(): if th.is_alive(): log.debug("Prior to webapp return, Galaxy thread %s is alive.", th) # Return return webapp
def app_factory(global_conf, load_app_kwds={}, **kwargs): """Return a wsgi application serving the root object""" # Create the Galaxy tool shed application unless passed in kwargs = load_app_properties( kwds=kwargs, config_prefix='TOOL_SHED_CONFIG_', **load_app_kwds ) if 'app' in kwargs: app = kwargs.pop('app') else: try: from galaxy.webapps.tool_shed.app import UniverseApplication app = UniverseApplication(global_conf=global_conf, **kwargs) except Exception: import traceback import sys traceback.print_exc() sys.exit(1) atexit.register(app.shutdown) # Create the universe WSGI application webapp = CommunityWebApplication(app, session_cookie='galaxycommunitysession', name="tool_shed") add_ui_controllers(webapp, app) webapp.add_route('/view/{owner}', controller='repository', action='sharable_owner') webapp.add_route('/view/{owner}/{name}', controller='repository', action='sharable_repository') webapp.add_route('/view/{owner}/{name}/{changeset_revision}', controller='repository', action='sharable_repository_revision') # Handle displaying tool help images and README file images for tools contained in repositories. webapp.add_route('/repository/static/images/{repository_id}/{image_file:.+?}', controller='repository', action='display_image_in_repository', repository_id=None, image_file=None) webapp.add_route('/{controller}/{action}', action='index') webapp.add_route('/{action}', controller='repository', action='index') # Enable 'hg clone' functionality on repos by letting hgwebapp handle the request webapp.add_route('/repos/*path_info', controller='hg', action='handle_request', path_info='/') # Add the web API. # A good resource for RESTful services - http://routes.readthedocs.org/en/latest/restful.html webapp.add_api_controllers('galaxy.webapps.tool_shed.api', app) webapp.mapper.connect('api_key_retrieval', '/api/authenticate/baseauth/', controller='authenticate', action='get_tool_shed_api_key', conditions=dict(method=["GET"])) webapp.mapper.connect('group', '/api/groups/', controller='groups', action='index', conditions=dict(method=["GET"])) webapp.mapper.connect('group', '/api/groups/', controller='groups', action='create', conditions=dict(method=["POST"])) webapp.mapper.connect('group', '/api/groups/{encoded_id}', controller='groups', action='show', conditions=dict(method=["GET"])) webapp.mapper.resource('category', 'categories', controller='categories', name_prefix='category_', path_prefix='/api', parent_resources=dict(member_name='category', collection_name='categories')) webapp.mapper.connect('repositories_in_category', '/api/categories/{category_id}/repositories', controller='categories', action='get_repositories', conditions=dict(method=["GET"])) webapp.mapper.connect('show_updates_for_repository', '/api/repositories/updates', controller='repositories', action='updates', conditions=dict(method=["GET"])) webapp.mapper.resource('repository', 'repositories', controller='repositories', collection={'add_repository_registry_entry': 'POST', 'get_repository_revision_install_info': 'GET', 'get_ordered_installable_revisions': 'GET', 'get_installable_revisions': 'GET', 'remove_repository_registry_entry': 'POST', 'repository_ids_for_setting_metadata': 'GET', 'reset_metadata_on_repositories': 'POST', 'reset_metadata_on_repository': 'POST'}, name_prefix='repository_', path_prefix='/api', new={'import_capsule': 'POST'}, parent_resources=dict(member_name='repository', collection_name='repositories')) webapp.mapper.resource('repository_revision', 'repository_revisions', member={'repository_dependencies': 'GET', 'export': 'POST'}, controller='repository_revisions', name_prefix='repository_revision_', path_prefix='/api', parent_resources=dict(member_name='repository_revision', collection_name='repository_revisions')) webapp.mapper.resource('user', 'users', controller='users', name_prefix='user_', path_prefix='/api', parent_resources=dict(member_name='user', collection_name='users')) webapp.mapper.connect('update_repository', '/api/repositories/{id}', controller='repositories', action='update', conditions=dict(method=["PATCH", "PUT"])) webapp.mapper.connect('repository_create_changeset_revision', '/api/repositories/{id}/changeset_revision', controller='repositories', action='create_changeset_revision', conditions=dict(method=["POST"])) webapp.mapper.connect('repository_get_metadata', '/api/repositories/{id}/metadata', controller='repositories', action='metadata', conditions=dict(method=["GET"])) webapp.mapper.connect('repository_show_tools', '/api/repositories/{id}/{changeset}/show_tools', controller='repositories', action='show_tools', conditions=dict(method=["GET"])) webapp.mapper.connect('create_repository', '/api/repositories', controller='repositories', action='create', conditions=dict(method=["POST"])) webapp.mapper.connect('tools', '/api/tools', controller='tools', action='index', conditions=dict(method=["GET"])) webapp.mapper.connect('json', '/api/tools/json', controller='tools', action='json', conditions=dict(method=["GET"])) webapp.mapper.connect("version", "/api/version", controller="configuration", action="version", conditions=dict(method=["GET"])) webapp.finalize_config() # Wrap the webapp in some useful middleware if kwargs.get('middleware', True): webapp = wrap_in_middleware(webapp, global_conf, app.application_stack, **kwargs) if asbool(kwargs.get('static_enabled', True)): webapp = wrap_if_allowed(webapp, app.application_stack, wrap_in_static, args=(global_conf,), kwargs=kwargs) # Close any pooled database connections before forking try: galaxy.webapps.tool_shed.model.mapping.metadata.bind.dispose() except Exception: log.exception("Unable to dispose of pooled tool_shed model database connections.") # Return return webapp
def wrap_in_middleware(app, global_conf, application_stack, **local_conf): """Based on the configuration wrap `app` in a set of common and useful middleware.""" stack = application_stack # Merge the global and local configurations conf = global_conf.copy() conf.update(local_conf) debug = asbool(conf.get('debug', False)) interactive = asbool(conf.get('use_interactive', False)) # First put into place httpexceptions, which must be most closely # wrapped around the application (it can interact poorly with # other middleware): app = wrap_if_allowed(app, stack, httpexceptions.make_middleware, name='paste.httpexceptions', args=(conf,)) # Create a separate mapper for redirects to prevent conflicts. redirect_mapper = routes.Mapper() redirect_mapper = _map_redirects(redirect_mapper) # Load the Routes middleware which we use for redirecting app = wrap_if_allowed(app, stack, RoutesMiddleware, args=(redirect_mapper,)) # If we're using remote_user authentication, add middleware that # protects Galaxy from improperly configured authentication in the # upstream server if asbool(conf.get('use_remote_user', False)): from galaxy.webapps.tool_shed.framework.middleware.remoteuser import RemoteUser app = wrap_if_allowed(app, stack, RemoteUser, kwargs=dict( maildomain=conf.get('remote_user_maildomain', None), display_servers=util.listify(conf.get('display_servers', '')), admin_users=conf.get('admin_users', '').split(','), remote_user_header=conf.get('remote_user_header', 'HTTP_REMOTE_USER'), remote_user_secret_header=conf.get('remote_user_secret', None), normalize_remote_user_email=conf.get('normalize_remote_user_email', False))) # The recursive middleware allows for including requests in other # requests or forwarding of requests, all on the server side. if asbool(conf.get('use_recursive', True)): from paste import recursive app = wrap_if_allowed(app, stack, recursive.RecursiveMiddleware, args=(conf,)) # Transaction logging (apache access.log style) if asbool(conf.get('use_translogger', True)): from paste.translogger import TransLogger app = wrap_if_allowed(app, stack, TransLogger) # If sentry logging is enabled, log here before propogating up to # the error middleware # TODO sentry config is duplicated between tool_shed/galaxy, refactor this. sentry_dsn = conf.get('sentry_dsn', None) if sentry_dsn: from galaxy.web.framework.middleware.sentry import Sentry app = wrap_if_allowed(app, stack, Sentry, args=(sentry_dsn,)) # X-Forwarded-Host handling from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware app = wrap_if_allowed(app, stack, XForwardedHostMiddleware) # Various debug middleware that can only be turned on if the debug # flag is set, either because they are insecure or greatly hurt # performance. if debug: # Middleware to check for WSGI compliance if asbool(conf.get('use_lint', True)): from paste import lint app = wrap_if_allowed(app, stack, lint.make_middleware, name='paste.lint', args=(conf,)) # Middleware to run the python profiler on each request if asbool(conf.get('use_profile', False)): from paste.debug import profile app = wrap_if_allowed(app, stack, profile.ProfileMiddleware, args=(conf,)) if interactive: # Interactive exception debugging, scary dangerous if publicly # accessible, if not enabled we'll use the regular error printing # middleware. try: from weberror import evalexception app = wrap_if_allowed_or_fail(app, stack, evalexception.EvalException, args=(conf,), kwargs=dict(templating_formatters=build_template_error_formatters())) except MiddlewareWrapUnsupported as exc: log.warning(str(exc)) import galaxy.web.framework.middleware.error app = wrap_if_allowed(app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf,)) else: # Not in interactive debug mode, just use the regular error middleware import galaxy.web.framework.middleware.error app = wrap_if_allowed(app, stack, galaxy.web.framework.middleware.error.ErrorMiddleware, args=(conf,)) return app