Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Subapps #1301

Merged
merged 20 commits into from
Oct 27, 2016
Merged

Subapps #1301

Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Support nested subapp middlewares
asvetlov committed Oct 27, 2016
commit 51bec50311a31a4ee7d8959eaa5f207f952f5157
5 changes: 2 additions & 3 deletions aiohttp/web.py
Original file line number Diff line number Diff line change
@@ -39,7 +39,6 @@ def __init__(self, manager, app, router, *,
self._manager = manager
self._app = app
self._router = router
self._middlewares = app.middlewares
self._secure_proxy_ssl_header = secure_proxy_ssl_header

def __repr__(self):
@@ -85,7 +84,7 @@ def handle_request(self, message, payload):

if resp is None:
handler = match_info.handler
for factory in reversed(self._middlewares):
for factory in match_info.middlewares:
handler = yield from factory(app, handler)
resp = yield from handler(request)

@@ -289,7 +288,7 @@ def __call__(self):
return self

def __repr__(self):
return "<Application>"
return "<Application 0x{:x}>".format(id(self))


def run_app(app, *, host='0.0.0.0', port=None,
12 changes: 12 additions & 0 deletions aiohttp/web_urldispatcher.py
Original file line number Diff line number Diff line change
@@ -189,6 +189,13 @@ def get_info(self):
def apps(self):
return tuple(self._apps)

@property
def middlewares(self):
middlewares = []
for app in self._apps:
middlewares.extend(reversed(app.middlewares))
return middlewares

def add_app(self, app):
if self._frozen:
raise RuntimeError("Cannot change apps stack after .freeze() call")
@@ -523,6 +530,11 @@ def __init__(self, prefix, app):
for resource in app.router.resources():
resource.add_prefix(prefix)

def add_prefix(self, prefix):
super().add_prefix(prefix)
for resource in self._app.router.resources():
resource.add_prefix(prefix)

def url_for(self, *args, **kwargs):
raise RuntimeError(".url_for() is not supported "
"by sub-application root")
3 changes: 2 additions & 1 deletion tests/test_urldispatch.py
Original file line number Diff line number Diff line change
@@ -926,7 +926,8 @@ def test_subapp_url_for(router, loop):
def test_subapp_repr(router, loop):
subapp = web.Application(loop=loop)
resource = router.add_subapp('/pre', subapp)
assert repr(resource) == '<PrefixedSubAppResource /pre/ -> <Application>>'
assert repr(resource).startswith(
'<PrefixedSubAppResource /pre/ -> <Application')


def test_subapp_len(router, loop):
36 changes: 35 additions & 1 deletion tests/test_web_functional.py
Original file line number Diff line number Diff line change
@@ -385,7 +385,7 @@ def handler(request):

def test_repr_for_application(loop):
app = web.Application(loop=loop)
assert "<Application>" == repr(app)
assert "<Application 0x{:x}>".format(id(app)) == repr(app)


@asyncio.coroutine
@@ -1037,3 +1037,37 @@ def handler(request):
client = yield from test_client(app)
resp = yield from client.get('/path/to')
assert resp.status == 500


@asyncio.coroutine
def test_subapp_middlewares(loop, test_client):
order = []

@asyncio.coroutine
def handler(request):
return web.HTTPOk(text='OK')

@asyncio.coroutine
def middleware_factory(app, handler):

@asyncio.coroutine
def middleware(request):
order.append((1, app))
resp = yield from handler(request)
assert 200 == resp.status
order.append((2, app))
return resp
return middleware

app = web.Application(loop=loop, middlewares=[middleware_factory])
subapp1 = web.Application(loop=loop, middlewares=[middleware_factory])
subapp2 = web.Application(loop=loop, middlewares=[middleware_factory])
subapp2.router.add_get('/to', handler)
subapp1.router.add_subapp('/b/', subapp2)
app.router.add_subapp('/a/', subapp1)

client = yield from test_client(app)
resp = yield from client.get('/a/b/to')
assert resp.status == 200
assert [(1, app), (1, subapp1), (1, subapp2),
(2, subapp2), (2, subapp1), (2, app)] == order