web-app-demos/main.py
2025-03-17 16:11:01 -06:00

100 lines
No EOL
3.2 KiB
Python

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())