Skip to content

Commit

Permalink
added middleware that can encapsulate a lazy loaded app
Browse files Browse the repository at this point in the history
  • Loading branch information
miguelgrinberg committed Sep 7, 2014
1 parent 4e9e1b2 commit 102c3ab
Show file tree
Hide file tree
Showing 2 changed files with 38 additions and 6 deletions.
18 changes: 12 additions & 6 deletions werkzeug/serving.py
Original file line number Diff line number Diff line change
Expand Up @@ -63,7 +63,7 @@ def _get_openssl_crypto_module():

import werkzeug
from werkzeug._internal import _log
from werkzeug._compat import reraise, wsgi_encoding_dance
from werkzeug._compat import reraise, wsgi_encoding_dance, string_types
from werkzeug.urls import url_parse, url_unquote
from werkzeug.exceptions import InternalServerError

Expand Down Expand Up @@ -555,7 +555,8 @@ def run_simple(hostname, port, application, use_reloader=False,
:param hostname: The host for the application. eg: ``'localhost'``
:param port: The port for the server. eg: ``8080``
:param application: the WSGI application to execute
:param application: the WSGI application to execute, or the dotted name from
where it can be imported.
:param use_reloader: should the server automatically restart the python
process if modules were changed?
:param use_debugger: should the werkzeug debugging system be used?
Expand Down Expand Up @@ -589,6 +590,13 @@ def run_simple(hostname, port, application, use_reloader=False,
the server should automatically create one, or ``None``
to disable SSL (which is the default).
"""
if isinstance(application, string_types):
if use_reloader:
from werkzeug.wsgi import ImportedAppMiddleware
application = ImportedAppMiddleware(application)
else:
from werkzeug.utils import import_string
application = import_string(application)
if use_debugger:
from werkzeug.debug import DebuggedApplication
application = DebuggedApplication(application, use_evalex)
Expand Down Expand Up @@ -617,7 +625,7 @@ def inner():
test_socket.bind((hostname, port))
test_socket.close()

from ._reloader import run_with_reloader
from werkzeug._reloader import run_with_reloader
run_with_reloader(inner, extra_files, reloader_interval,
reloader_type)
else:
Expand All @@ -636,7 +644,6 @@ def main():

# in contrast to argparse, this works at least under Python < 2.7
import optparse
from werkzeug.utils import import_string

parser = optparse.OptionParser(
usage='Usage: %prog [options] app_module:app_object')
Expand All @@ -660,11 +667,10 @@ def main():
if len(args) != 1:
sys.stdout.write('No application supplied, or too much. See --help\n')
sys.exit(1)
app = import_string(args[0])

run_simple(
hostname=(hostname or '127.0.0.1'), port=int(port or 5000),
application=app, use_reloader=options.use_reloader,
application=args[0], use_reloader=options.use_reloader,
use_debugger=options.use_debugger
)

Expand Down
26 changes: 26 additions & 0 deletions werkzeug/wsgi.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,6 +18,7 @@
from time import time, mktime
from datetime import datetime
from functools import partial, update_wrapper
from threading import Lock

from werkzeug._compat import iteritems, text_type, string_types, \
implements_iterator, make_literal_wrapper, to_unicode, to_bytes, \
Expand Down Expand Up @@ -647,6 +648,31 @@ def __call__(self, environ, start_response):
return app(environ, start_response)


class ImportedAppMiddleware(object):
"""Allows lazy loading of an application."""

def __init__(self, app_string):
self.app_string = app_string
self.app = None
self._lock = Lock()

def _load(self):
from werkzeug.utils import import_string
with self._lock:
if self.app is None:
self.app = import_string(self.app_string)

def __getattr__(self, name):
if self.app is None:
self._load()
return self.app.__getattribute__(name)

def __call__(self, environ, start_response):
if self.app is None:
self._load()
return self.app(environ, start_response)


@implements_iterator
class ClosingIterator(object):
"""The WSGI specification requires that all middlewares and gateways
Expand Down

0 comments on commit 102c3ab

Please sign in to comment.