Mercurial > piecrust2
diff piecrust/serving/wrappers.py @ 917:33a89139c284
serve: Add `--admin` option to run the administration panel.
- Removed the `admin run` command.
- Cleaned up middlewares a bit.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Fri, 29 Sep 2017 08:42:38 -0700 |
parents | 1bb0d973dc69 |
children | 7ecb946bfafd |
line wrap: on
line diff
--- a/piecrust/serving/wrappers.py Wed Sep 27 19:07:55 2017 -0700 +++ b/piecrust/serving/wrappers.py Fri Sep 29 08:42:38 2017 -0700 @@ -6,8 +6,41 @@ logger = logging.getLogger(__name__) -def run_werkzeug_server(appfactory, host, port, - use_debugger=False, use_reloader=False): +def run_piecrust_server(wsgi, appfactory, host, port, + is_cmdline_mode=False, + serve_admin=False, + use_debugger=False, + use_reloader=False): + + if wsgi == 'werkzeug': + _run_werkzeug_server(appfactory, host, port, + is_cmdline_mode=is_cmdline_mode, + serve_admin=serve_admin, + use_debugger=use_debugger, + use_reloader=use_reloader) + + elif wsgi == 'gunicorn': + options = { + 'bind': '%s:%s' % (host, port), + 'accesslog': '-', # print access log to stderr + } + if use_debugger: + options['loglevel'] = 'debug' + if use_reloader: + options['reload'] = True + _run_gunicorn_server(appfactory, + is_cmdline_mode=is_cmdline_mode, + gunicorn_options=options) + + else: + raise Exception("Unknown WSGI server: %s" % wsgi) + + +def _run_werkzeug_server(appfactory, host, port, *, + is_cmdline_mode=False, + serve_admin=False, + use_debugger=False, + use_reloader=False): from werkzeug.serving import run_simple def _run_sse_check(): @@ -21,6 +54,9 @@ os.environ.get('WERKZEUG_RUN_MAIN') == 'true') app = _get_piecrust_server(appfactory, + is_cmdline_mode=is_cmdline_mode, + serve_site=True, + serve_admin=serve_admin, run_sse_check=_run_sse_check) # We need to do a few things to get Werkzeug to properly shutdown or @@ -45,6 +81,10 @@ from piecrust.serving import procloop procloop.server_shutdown = True + if serve_admin: + from piecrust.admin import pubutil + pubutil.server_shutdown = True + def _shutdown_server_and_raise_sigint(): if not use_reloader or os.environ.get('WERKZEUG_RUN_MAIN') == 'true': # We only need to shutdown the SSE requests for the process @@ -75,7 +115,9 @@ raise -def run_gunicorn_server(appfactory, gunicorn_options=None): +def _run_gunicorn_server(appfactory, + is_cmdline_mode=False, + gunicorn_options=None): from gunicorn.app.base import BaseApplication class PieCrustGunicornApplication(BaseApplication): @@ -92,20 +134,72 @@ def load(self): return self.app - app = _get_piecrust_server(appfactory) + app = _get_piecrust_server(appfactory, + is_cmdline_mode=is_cmdline_mode) gunicorn_options = gunicorn_options or {} app_wrapper = PieCrustGunicornApplication(app, gunicorn_options) app_wrapper.run() -def _get_piecrust_server(appfactory, run_sse_check=None): - from piecrust.serving.middlewares import ( - StaticResourcesMiddleware, PieCrustDebugMiddleware) - from piecrust.serving.server import WsgiServer - app = WsgiServer(appfactory) - app = StaticResourcesMiddleware(app) - app = PieCrustDebugMiddleware( - app, appfactory, run_sse_check=run_sse_check) +def _get_piecrust_server(appfactory, *, + serve_site=True, + serve_admin=False, + is_cmdline_mode=False, + run_sse_check=None): + app = None + + if serve_site: + from piecrust.serving.middlewares import ( + PieCrustStaticResourcesMiddleware, PieCrustDebugMiddleware) + from piecrust.serving.server import PieCrustServer + + app = PieCrustServer(appfactory) + app = PieCrustStaticResourcesMiddleware(app) + + if is_cmdline_mode: + app = PieCrustDebugMiddleware( + app, appfactory, run_sse_check=run_sse_check) + + if serve_admin: + from piecrust.admin.web import create_foodtruck_app + + admin_root_url = '/pc-admin' + es = { + 'FOODTRUCK_CMDLINE_MODE': is_cmdline_mode, + 'FOODTRUCK_ROOT': appfactory.root_dir, + 'FOODTRUCK_URL_PREFIX': admin_root_url, + 'DEBUG': appfactory.debug} + if is_cmdline_mode: + es.update({ + 'SECRET_KEY': os.urandom(22), + 'LOGIN_DISABLED': True}) + + if appfactory.debug and is_cmdline_mode: + # Disable PIN protection with Werkzeug's debugger. + os.environ['WERKZEUG_DEBUG_PIN'] = 'off' + + admin_app = create_foodtruck_app(es) + admin_app.wsgi_app = _PieCrustSiteOrAdminMiddleware( + app, admin_app.wsgi_app, admin_root_url) + app = admin_app + return app + +class _PieCrustSiteOrAdminMiddleware: + def __init__(self, main_app, admin_app, admin_root_url): + from werkzeug.exceptions import abort + + def _err_resp(e, sr): + abort(404) + + self.main_app = main_app + self.admin_app = admin_app or _err_resp + self.admin_root_url = admin_root_url + + def __call__(self, environ, start_response): + path_info = environ.get('PATH_INFO', '') + if path_info.startswith(self.admin_root_url): + return self.admin_app(environ, start_response) + return self.main_app(environ, start_response)