PageRenderTime 442ms CodeModel.GetById 424ms RepoModel.GetById 0ms app.codeStats 0ms

/lib/galaxy/webapps/demo_sequencer/buildapp.py

https://bitbucket.org/cistrome/cistrome-harvard/
Python | 171 lines | 144 code | 8 blank | 19 comment | 6 complexity | e1de7c4f0f371604753c226626b4deaa MD5 | raw file
  1. """
  2. Provides factory methods to assemble the Galaxy web application
  3. """
  4. import logging, atexit
  5. import os, os.path, sys
  6. from inspect import isclass
  7. from paste.request import parse_formvars
  8. from paste.util import import_string
  9. from paste import httpexceptions
  10. from galaxy.util import asbool
  11. import pkg_resources
  12. log = logging.getLogger( __name__ )
  13. import config
  14. import galaxy.webapps.demo_sequencer.framework
  15. def add_ui_controllers( webapp, app ):
  16. """
  17. Search for controllers in the 'galaxy.webapps.demo_sequencer.controllers'
  18. directory and add them to the webapp.
  19. """
  20. from galaxy.web.base.controller import BaseUIController
  21. from galaxy.web.base.controller import ControllerUnavailable
  22. import galaxy.webapps.demo_sequencer.controllers
  23. controller_dir = galaxy.webapps.demo_sequencer.controllers.__path__[0]
  24. for fname in os.listdir( controller_dir ):
  25. if not fname.startswith( "_" ) and fname.endswith( ".py" ):
  26. name = fname[:-3]
  27. module_name = "galaxy.webapps.demo_sequencer.controllers." + name
  28. module = __import__( module_name )
  29. for comp in module_name.split( "." )[1:]:
  30. module = getattr( module, comp )
  31. # Look for a controller inside the modules
  32. for key in dir( module ):
  33. T = getattr( module, key )
  34. if isclass( T ) and T is not BaseUIController and issubclass( T, BaseUIController ):
  35. webapp.add_ui_controller( name, T( app ) )
  36. def app_factory( global_conf, **kwargs ):
  37. """Return a wsgi application serving the root object"""
  38. # Create the Galaxy application unless passed in
  39. if 'app' in kwargs:
  40. app = kwargs.pop( 'app' )
  41. else:
  42. try:
  43. from galaxy.webapps.demo_sequencer.app import UniverseApplication
  44. app = UniverseApplication( global_conf = global_conf, **kwargs )
  45. except:
  46. import traceback, sys
  47. traceback.print_exc()
  48. sys.exit( 1 )
  49. atexit.register( app.shutdown )
  50. # Create the universe WSGI application
  51. webapp = galaxy.webapps.demo_sequencer.framework.WebApplication( app, session_cookie='galaxydemo_sequencersession', name="demo_sequencer" )
  52. add_ui_controllers( webapp, app )
  53. # These two routes handle our simple needs at the moment
  54. webapp.add_route( '/:controller/:action', action='index' )
  55. webapp.add_route( '/:action', controller='common', action='index' )
  56. webapp.finalize_config()
  57. # Wrap the webapp in some useful middleware
  58. if kwargs.get( 'middleware', True ):
  59. webapp = wrap_in_middleware( webapp, global_conf, **kwargs )
  60. if kwargs.get( 'static_enabled', True ):
  61. webapp = wrap_in_static( webapp, global_conf, **kwargs )
  62. # Return
  63. return webapp
  64. def wrap_in_middleware( app, global_conf, **local_conf ):
  65. """Based on the configuration wrap `app` in a set of common and useful middleware."""
  66. # Merge the global and local configurations
  67. conf = global_conf.copy()
  68. conf.update(local_conf)
  69. debug = asbool( conf.get( 'debug', False ) )
  70. # First put into place httpexceptions, which must be most closely
  71. # wrapped around the application (it can interact poorly with
  72. # other middleware):
  73. app = httpexceptions.make_middleware( app, conf )
  74. log.debug( "Enabling 'httpexceptions' middleware" )
  75. # The recursive middleware allows for including requests in other
  76. # requests or forwarding of requests, all on the server side.
  77. if asbool(conf.get('use_recursive', True)):
  78. from paste import recursive
  79. app = recursive.RecursiveMiddleware( app, conf )
  80. log.debug( "Enabling 'recursive' middleware" )
  81. # Various debug middleware that can only be turned on if the debug
  82. # flag is set, either because they are insecure or greatly hurt
  83. # performance
  84. if debug:
  85. # Middleware to check for WSGI compliance
  86. if asbool( conf.get( 'use_lint', True ) ):
  87. from paste import lint
  88. app = lint.make_middleware( app, conf )
  89. log.debug( "Enabling 'lint' middleware" )
  90. # Middleware to run the python profiler on each request
  91. if asbool( conf.get( 'use_profile', False ) ):
  92. import profile
  93. app = profile.ProfileMiddleware( app, conf )
  94. log.debug( "Enabling 'profile' middleware" )
  95. # Middleware that intercepts print statements and shows them on the
  96. # returned page
  97. if asbool( conf.get( 'use_printdebug', True ) ):
  98. from paste.debug import prints
  99. app = prints.PrintDebugMiddleware( app, conf )
  100. log.debug( "Enabling 'print debug' middleware" )
  101. if debug and asbool( conf.get( 'use_interactive', False ) ):
  102. # Interactive exception debugging, scary dangerous if publicly
  103. # accessible, if not enabled we'll use the regular error printing
  104. # middleware.
  105. pkg_resources.require( "WebError" )
  106. from weberror import evalexception
  107. app = evalexception.EvalException( app, conf,
  108. templating_formatters=build_template_error_formatters() )
  109. log.debug( "Enabling 'eval exceptions' middleware" )
  110. else:
  111. # Not in interactive debug mode, just use the regular error middleware
  112. from paste.exceptions import errormiddleware
  113. app = errormiddleware.ErrorMiddleware( app, conf )
  114. log.debug( "Enabling 'error' middleware" )
  115. # Transaction logging (apache access.log style)
  116. if asbool( conf.get( 'use_translogger', True ) ):
  117. from paste.translogger import TransLogger
  118. app = TransLogger( app )
  119. log.debug( "Enabling 'trans logger' middleware" )
  120. # X-Forwarded-Host handling
  121. from galaxy.web.framework.middleware.xforwardedhost import XForwardedHostMiddleware
  122. app = XForwardedHostMiddleware( app )
  123. log.debug( "Enabling 'x-forwarded-host' middleware" )
  124. return app
  125. def wrap_in_static( app, global_conf, **local_conf ):
  126. from paste.urlmap import URLMap
  127. from galaxy.web.framework.middleware.static import CacheableStaticURLParser as Static
  128. urlmap = URLMap()
  129. # Merge the global and local configurations
  130. conf = global_conf.copy()
  131. conf.update(local_conf)
  132. # Get cache time in seconds
  133. cache_time = conf.get( "static_cache_time", None )
  134. if cache_time is not None:
  135. cache_time = int( cache_time )
  136. # Send to dynamic app by default
  137. urlmap["/"] = app
  138. # Define static mappings from config
  139. urlmap["/static"] = Static( conf.get( "static_dir" ), cache_time )
  140. urlmap["/images"] = Static( conf.get( "static_images_dir" ), cache_time )
  141. urlmap["/static/scripts"] = Static( conf.get( "static_scripts_dir" ), cache_time )
  142. urlmap["/static/style"] = Static( conf.get( "static_style_dir" ), cache_time )
  143. urlmap["/favicon.ico"] = Static( conf.get( "static_favicon_dir" ), cache_time )
  144. # URL mapper becomes the root webapp
  145. return urlmap
  146. def build_template_error_formatters():
  147. """
  148. Build a list of template error formatters for WebError. When an error
  149. occurs, WebError pass the exception to each function in this list until
  150. one returns a value, which will be displayed on the error page.
  151. """
  152. formatters = []
  153. # Formatter for mako
  154. import mako.exceptions
  155. def mako_html_data( exc_value ):
  156. if isinstance( exc_value, ( mako.exceptions.CompileException, mako.exceptions.SyntaxException ) ):
  157. return mako.exceptions.html_error_template().render( full=False, css=False )
  158. if isinstance( exc_value, AttributeError ) and exc_value.args[0].startswith( "'Undefined' object has no attribute" ):
  159. return mako.exceptions.html_error_template().render( full=False, css=False )
  160. formatters.append( mako_html_data )
  161. return formatters