Mercurial > piecrust2
annotate piecrust/serving/middlewares.py @ 553:cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
author | Ludovic Chabant <ludovic@chabant.com> |
---|---|
date | Sat, 08 Aug 2015 22:01:47 -0700 |
parents | |
children | 93b656f0af54 |
rev | line source |
---|---|
553
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
1 import os.path |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
2 from werkzeug.wrappers import Request, Response |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
3 from werkzeug.wsgi import ClosingIterator |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
4 from piecrust import RESOURCES_DIR, CACHE_DIR |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
5 from piecrust.serving.util import make_wrapped_file_response |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
6 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
7 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
8 class StaticResourcesMiddleware(object): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
9 """ WSGI middleware that serves static files from the `resources/server` |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
10 directory in the PieCrust package. |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
11 """ |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
12 def __init__(self, app): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
13 self.app = app |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
14 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
15 def __call__(self, environ, start_response): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
16 static_mount = '/__piecrust_static/' |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
17 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
18 request = Request(environ) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
19 if request.path.startswith(static_mount): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
20 rel_req_path = request.path[len(static_mount):] |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
21 mount = os.path.join(RESOURCES_DIR, 'server') |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
22 full_path = os.path.join(mount, rel_req_path) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
23 try: |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
24 response = make_wrapped_file_response( |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
25 environ, request, full_path) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
26 return response(environ, start_response) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
27 except OSError: |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
28 pass |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
29 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
30 return self.app(environ, start_response) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
31 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
32 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
33 class PieCrustDebugMiddleware(object): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
34 """ WSGI middleware that handles debugging of PieCrust stuff. |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
35 """ |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
36 def __init__(self, app, root_dir, debug=False, |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
37 sub_cache_dir=None, run_sse_check=None): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
38 self.app = app |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
39 self.root_dir = root_dir |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
40 self.debug = debug |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
41 self.run_sse_check = run_sse_check |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
42 self._proc_loop = None |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
43 self._out_dir = os.path.join(root_dir, CACHE_DIR, 'server') |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
44 if sub_cache_dir: |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
45 self._out_dir = os.path.join(sub_cache_dir, 'server') |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
46 self._handlers = { |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
47 'werkzeug_shutdown': self._shutdownWerkzeug, |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
48 'pipeline_status': self._startSSEProvider} |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
49 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
50 if not self.run_sse_check or self.run_sse_check(): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
51 # When using a server with code reloading, some implementations |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
52 # use process forking and we end up going here twice. We only want |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
53 # to start the pipeline loop in the inner process most of the |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
54 # time so we let the implementation tell us if this is OK. |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
55 from piecrust.serving.procloop import ProcessingLoop |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
56 self._proc_loop = ProcessingLoop(root_dir, self._out_dir, |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
57 sub_cache_dir=sub_cache_dir, |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
58 debug=debug) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
59 self._proc_loop.start() |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
60 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
61 def __call__(self, environ, start_response): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
62 debug_mount = '/__piecrust_debug/' |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
63 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
64 request = Request(environ) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
65 if request.path.startswith(debug_mount): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
66 rel_req_path = request.path[len(debug_mount):] |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
67 handler = self._handlers.get(rel_req_path) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
68 if handler is not None: |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
69 return handler(request, start_response) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
70 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
71 return self.app(environ, start_response) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
72 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
73 def _shutdownWerkzeug(self, request, start_response): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
74 shutdown_func = request.environ.get('werkzeug.server.shutdown') |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
75 if shutdown_func is None: |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
76 raise RuntimeError('Not running with the Werkzeug Server') |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
77 shutdown_func() |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
78 response = Response("Server shutting down...") |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
79 return response(request.environ, start_response) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
80 |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
81 def _startSSEProvider(self, request, start_response): |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
82 from piecrust.serving.procloop import ( |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
83 PipelineStatusServerSentEventProducer) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
84 provider = PipelineStatusServerSentEventProducer( |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
85 self._proc_loop) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
86 it = provider.run() |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
87 response = Response(it, mimetype='text/event-stream') |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
88 response.headers['Cache-Control'] = 'no-cache' |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
89 response.headers['Last-Event-ID'] = \ |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
90 self._proc_loop.last_status_id |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
91 return ClosingIterator( |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
92 response(request.environ, start_response), |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
93 [provider.close]) |
cc6f3dbe3048
serve: Extract some of the server's functionality into WSGI middlewares.
Ludovic Chabant <ludovic@chabant.com>
parents:
diff
changeset
|
94 |