async def test_subapp_chained_config_dict_visibility( aiohttp_client: Any) -> None: key1 = web.AppKey("key1", str) key2 = web.AppKey("key2", str) async def main_handler(request): assert request.config_dict[key1] == "val1" assert key2 not in request.config_dict return web.Response(status=200) root = web.Application() root[key1] = "val1" root.add_routes([web.get("/", main_handler)]) async def sub_handler(request): assert request.config_dict[key1] == "val1" assert request.config_dict[key2] == "val2" return web.Response(status=201) sub = web.Application() sub[key2] = "val2" sub.add_routes([web.get("/", sub_handler)]) root.add_subapp("/sub", sub) client = await aiohttp_client(root) resp = await client.get("/") assert resp.status == 200 resp = await client.get("/sub/") assert resp.status == 201
def test_app_iter() -> None: app = web.Application() b = web.AppKey("b", str) c = web.AppKey("c", str) app["a"] = "0" app[b] = "1" app[c] = "2" app["d"] = "4" assert sorted(list(app)) == [b, c, "a", "d"]
def test_appkey() -> None: key = web.AppKey("key", str) app = web.Application() app[key] = "value" assert app[key] == "value" assert len(app) == 1 del app[key] assert len(app) == 0
#!/usr/bin/env python3 import logging from typing import List from aiohttp import WSCloseCode, web websockets = web.AppKey("websockets", List[web.WebSocketResponse]) async def wshandler(request: web.Request) -> web.WebSocketResponse: ws = web.WebSocketResponse(autoclose=False) is_ws = ws.can_prepare(request) if not is_ws: raise web.HTTPBadRequest() await ws.prepare(request) request.app[websockets].append(ws) while True: msg = await ws.receive() if msg.type == web.WSMsgType.TEXT: await ws.send_str(msg.data) elif msg.type == web.WSMsgType.BINARY: await ws.send_bytes(msg.data) elif msg.type == web.WSMsgType.CLOSE: await ws.close() break else:
$ python -m aiohttp.web -H localhost -P 8080 --repeat 10 cli_app:init \ > "Hello World" Here ``--repeat`` & ``"Hello World"`` are application specific command-line arguments. `aiohttp.web` only parses & consumes the command-line arguments it needs (i.e. ``-H``, ``-P`` & ``entry-func``) and passes on any additional arguments to the `cli_app:init` function for processing. """ from argparse import ArgumentParser, Namespace from typing import Optional, Sequence from aiohttp import web args_key = web.AppKey("args_key", Namespace) async def display_message(req: web.Request) -> web.StreamResponse: args = req.app[args_key] text = "\n".join([args.message] * args.repeat) return web.Response(text=text) def init(argv: Optional[Sequence[str]]) -> web.Application: arg_parser = ArgumentParser( prog="aiohttp.web ...", description="Application CLI", add_help=False ) # Positional argument arg_parser.add_argument("message", help="message to print")
async def test_subapp_on_startup(aiohttp_client: Any) -> None: subapp = web.Application() startup = web.AppKey("startup", bool) cleanup = web.AppKey("cleanup", bool) startup_called = False async def on_startup(app): nonlocal startup_called startup_called = True app[startup] = True subapp.on_startup.append(on_startup) ctx_pre_called = False ctx_post_called = False async def cleanup_ctx(app): nonlocal ctx_pre_called, ctx_post_called ctx_pre_called = True app[cleanup] = True yield None ctx_post_called = True subapp.cleanup_ctx.append(cleanup_ctx) shutdown_called = False async def on_shutdown(app): nonlocal shutdown_called shutdown_called = True subapp.on_shutdown.append(on_shutdown) cleanup_called = False async def on_cleanup(app): nonlocal cleanup_called cleanup_called = True subapp.on_cleanup.append(on_cleanup) app = web.Application() app.add_subapp("/subapp", subapp) assert not startup_called assert not ctx_pre_called assert not ctx_post_called assert not shutdown_called assert not cleanup_called assert subapp.on_startup.frozen assert subapp.cleanup_ctx.frozen assert subapp.on_shutdown.frozen assert subapp.on_cleanup.frozen assert subapp.router.frozen client = await aiohttp_client(app) assert startup_called assert ctx_pre_called assert not ctx_post_called assert not shutdown_called assert not cleanup_called await client.close() assert startup_called assert ctx_pre_called assert ctx_post_called assert shutdown_called assert cleanup_called
def test_app_get() -> None: key = web.AppKey("key", int) app = web.Application() assert app.get(key, "foo") == "foo" app[key] = 5 assert app.get(key, "foo") == 5
def test_appkey_repr_nonconcrete() -> None: key = web.AppKey("key", Iterator[int]) assert repr(key) == "<AppKey(__main__.key, type=typing.Iterator[int])>"
def test_appkey_repr_concrete() -> None: key = web.AppKey("key", int) assert repr(key) == "<AppKey(__main__.key, type=int)>" key = web.AppKey("key", web.Request) assert repr( key) == "<AppKey(__main__.key, type=aiohttp.web_request.Request)>"
#!/usr/bin/env python3 """Example of aiohttp.web.Application.on_startup signal handler""" import asyncio from typing import List import aioredis from aiohttp import web redis_listener = web.AppKey("redis_listener", asyncio.Task[None]) websockets = web.AppKey("websockets", List[web.WebSocketResponse]) async def websocket_handler(request: web.Request) -> web.StreamResponse: ws = web.WebSocketResponse() await ws.prepare(request) request.app[websockets].append(ws) try: async for msg in ws: print(msg) await asyncio.sleep(1) finally: request.app[websockets].remove(ws) return ws async def on_shutdown(app: web.Application) -> None: for ws in app[websockets]: await ws.close(code=999, message=b"Server shutdown")