import asyncio from aiohttp import web import aiohttp_session import aiohttp_security import aiomysql from pymysql.err import OperationalError import datetime import simplejson from dateutil.relativedelta import relativedelta import urllib.parse import psutil # Local import files import apps import security async def mysql_engine(app): print("Connecting to database... ", end='') try: pool = await aiomysql.create_pool(autocommit=True, **app['config']['database']) app['con'] = await pool.acquire() app['cur'] = await app['con'].cursor() #aiomysql.DictCursor except OperationalError as e: print(e) print("Done.") yield # Keep the cleanup context open until shutdown print("Disconnecting from database... ", end='') pool.close() await pool.wait_closed() print("Done.") async def main(): # Start tracking CPU usage _ = psutil.cpu_percent(percpu=True) root = web.Application() root['config'] = files.Config() root['templates'] = files.Templates() routes = web.RouteTableDef() @routes.get('/') async def home(request): return web.Response(text=request.config_dict['templates']['home.html'].template, content_type="text/html") aiohttp_session.setup(root, security.get_cookie_storage()) aiohttp_security.setup(root, security.LocalSessionIdentityPolicy(), security.SimplePasswordAuthPolicy()) root.add_routes(routes) # Should be served by reverse proxy in production root.router.add_static('/static/', path='./static', name='static') account = web.Application() account['prefix'] = '/log/' account['templates'] = files.Templates('apps/account/templates') apps.account.init_app(account) root.router.add_static('/log/static/', path='./apps/account/static', name='acc_static') root.add_subapp('/log', account) calendar = web.Application() calendar.middlewares.append(security.redirect_to_login) calendar['prefix'] = '/calendar/' calendar['templates'] = files.Templates('apps/calendar/templates') calendar['config'] = files.Config('apps/calendar/config', root['config'].config) calendar.cleanup_ctx.append(mysql_engine) apps.calendar.init_app(calendar) root.router.add_static('/calendar/static/', path='./apps/calendar/static', name='cal_static') root.add_subapp('/calendar', calendar) reporter = web.Application() reporter.middlewares.append(security.redirect_to_login) reporter['prefix'] = '/reporter/' reporter['templates'] = files.Templates('apps/reporter/templates') reporter['config'] = files.Config('apps/reporter/config', root['config'].config) reporter.cleanup_ctx.append(mysql_engine) apps.reporter.init_app(reporter) root.router.add_static('/reporter/static/', path='./apps/reporter/static', name='rep_static') root.add_subapp('/reporter', reporter) waiter = asyncio.Event() runner = web.AppRunner(root) # Hang on to these references so we can initiate a graceful shutdown from inside a coroutine root['waiter'] = waiter root['runner'] = runner await runner.setup() web_config = root['config']['web'] site = web.TCPSite(runner, **web_config) await site.start() print(f"Listening on {web_config['host']}:{web_config['port']}.") # Wait for the Event to be .set() by the graceful shutdown procedure await waiter.wait() print("Goodbye!") if __name__ == "__main__": asyncio.run(main())