Ejemplo n.º 1
0
"""
ASGI config for home project.

It exposes the ASGI callable as a module-level variable named ``application``.

For more information on this file, see
https://docs.djangoproject.com/en/3.0/howto/deployment/asgi/
"""

import os
import socketio

from django.core.asgi import get_asgi_application

os.environ.setdefault('DJANGO_SETTINGS_MODULE', 'home.settings')

sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*')
application = socketio.ASGIApp(sio, get_asgi_application())
Ejemplo n.º 2
0
#!/usr/bin/env python
import asyncio

import uvicorn
from uvicorn.loops.auto import auto_loop_setup

import socketio

sio = socketio.AsyncServer(async_mode='asgi')
app = socketio.ASGIApp(sio,
                       static_files={
                           '/': {
                               'content_type': 'text/html',
                               'filename': 'app.html'
                           },
                       })


async def background_task():
    """Example of how to send server generated events to clients."""
    count = 0
    while True:
        await sio.sleep(10)
        count += 1
        await sio.emit('my response', {'data': 'Server generated event'},
                       namespace='/test')


@sio.on('my event', namespace='/test')
async def test_message(sid, message):
    await sio.emit('my response', {'data': message['data']},
Ejemplo n.º 3
0
origins = [
    'http://localhost:3000',
    # "*",
]

app = FastAPI(
    # title=config.PROJECT_NAME,
    # description=config.PROJECT_NAME,
    # version=config.PROJECT_VERSION,
    debug=True)

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["GET", "POST"],
    allow_headers=["*"],
)

app.include_router(games.router, prefix='/v1')

app.include_router(chats.router, prefix='/v1')

app.include_router(users.router, prefix='/v1')

# without prefix for testing purposes
app.include_router(authentication.router)

# create socket.io app
sio_app = socketio.ASGIApp(socketio_server=sio, other_asgi_app=app)
Ejemplo n.º 4
0
    async def process_packet(self, packet: PacketModel):
        # some processing on packet
        # store in db
        # stream processing
        # upload chunks
        # etc
        pass


mgr = socketio.AsyncRedisManager(
    "redis://localhost/0"
)  # Message Queue is for working with distributed applications
sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*")
sio.register_namespace(
    GreyRookNameSpace("/GreyRook"))  # register the namespace
asgi = socketio.ASGIApp(sio)

app.mount("/ws", asgi)  # mount Socket.Io to FastApi with /ws path


class SampleResponseModel(BaseModel):
    message: str


class Sample400ResponseModel(BaseModel):
    detail: str


@app.get("/",
         description="some description",
         responses={
Ejemplo n.º 5
0
        return r
    if self.http_compression and \
            len(r['response']) >= self.compression_threshold:
        encodings = [
            e.split(';')[0].strip()
            for e in environ.get('HTTP_ACCEPT_ENCODING', '').split(',')
        ]
        for encoding in encodings:
            if encoding in self.compression_methods:
                r['response'] = \
                    getattr(self, '_' + encoding)(r['response'])
                r['headers'] += [('Content-Encoding', encoding)]
                break
    cors_headers = self._cors_headers(environ)
    make_response = self._async['make_response']
    if asyncio.iscoroutinefunction(make_response):
        response = await make_response(r['status'],
                                       r['headers'] + cors_headers,
                                       r['response'], environ)
    else:
        response = make_response(r['status'], r['headers'] + cors_headers,
                                 r['response'], environ)
    return response


sio = socketio.AsyncServer(async_mode='asgi')
ns_terminal = TerminalNamespace('/', sio)
sio.register_namespace(ns_terminal)
socket = socketio.ASGIApp(sio)
sio.eio._handle_connect = types.MethodType(_handle_connect, sio.eio)
sio.eio.handle_request = types.MethodType(handle_request, sio.eio)
Ejemplo n.º 6
0
"""
第7章/asgi_socketio/server.py
"""

import socketio, os

SERVER_ROOT = os.path.dirname(__file__)

# 创建一个 AsyncServer 实例
sio = socketio.AsyncServer()

app = socketio.ASGIApp(sio, static_files={
    # 配置静态文件目录为服务器应用目录下的 static 目录,这
    # 样可以使用 Socket.IO 内置的静态文件服务器处理静态请求
    "/static": os.path.join(SERVER_ROOT, "static")
})
Ejemplo n.º 7
0
# cf : https://pypi.org/project/fastapi-socketio/
# socket_manager = SocketManager(
#   app=app,
#   mount_location = "/ws",
#   socketio_path = "socket.io",
#   cors_allowed_origins=origins
# )
# print("\nmain.py > socket_manager : ", socket_manager.__dict__)

sio = socketio.AsyncServer(
    # async_mode='asgi',
    # cors_allowed_origins='*'
    async_mode='asgi',
    cors_allowed_origins=[])
subapi = socketio.ASGIApp(socketio_server=sio,
                          other_asgi_app=app,
                          socketio_path='/socket.io')
app.mount("/ws", subapi)

### ROUTERS

from .routers.routers import api_router

app.include_router(api_router, prefix=settings.API_V1_STR)

from .websockets.routers_websockets import *

### OPENAPI


def custom_openapi():
import socketio
import uvicorn

sio = socketio.AsyncServer(async_mode="asgi",
                           cors_allowed_origins="*",
                           logger=True,
                           engineio_logger=True)
app = socketio.ASGIApp(
    sio,
    static_files={
        "/": "app.html",
    },
)


@sio.on("connect")
async def connect(sid, environ):
    print(f"Client {sid} connected")


@sio.on("disconnect")
def disconnect(sid):
    print(f"Client {sid} disconnected")


@sio.on("set_features")
async def set_features(sid, features):
    await sio.emit("subscribe_features", {"features": features})


if __name__ == "__main__":
Ejemplo n.º 9
0
    vizzy_relay_coro = vizzy_relay(app.vizzy_queue)
    RUNNING_TASKS.add(loop.create_task(vizzy_relay_coro))


async def cancel_tasks():
    await app.indi.stop()
    for task in RUNNING_TASKS:
        task.cancel()


from starlette.routing import Route, Mount
from . import video

app = Starlette(
    debug=True,
    routes=[
        Route('/', endpoint=index),
        Route('/indi', endpoint=indi),
        Route('/demo', endpoint=demo),
        Mount('/video', routes=video.ROUTES),
        Route('/{path:path}', endpoint=catch_all),
    ],
    on_startup=[spawn_tasks],
    on_shutdown=[cancel_tasks],
)

composite_app = socketio.ASGIApp(sio, app)

if __name__ == '__main__':
    console_entrypoint()
Ejemplo n.º 10
0
from fastapi.staticfiles import StaticFiles

from pydantic import BaseModel, Field

NAME = 'Test API'
VERSION = '0.1'

app = FastAPI(title=NAME, version=VERSION)
path = os.path.dirname(__file__)
app.mount("/static",
          StaticFiles(directory=os.path.join(path, "static")),
          name="static")

sio = socketio.AsyncServer(async_mode='asgi')
# socketio adds automatically /socket.io/ to the URL.
app.mount('/sio', socketio.ASGIApp(sio))


@sio.on('connect')
def sio_connect(sid, environ):  # pylint: disable=unused-argument
    """Track user connection"""
    print('A user connected')


@sio.on('disconnect')
def sio_disconnect(sid):  # pylint: disable=unused-argument
    """Track user disconnection"""
    print('User disconnected')


@sio.on('chat message')
Ejemplo n.º 11
0
import socketio
import uvicorn

sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins=[])
app = socketio.ASGIApp(sio, static_files={'/': 'index.html'})


@sio.on('connect')
def connect(sid, environ):
    print('connect ', sid)


@sio.on('msg')
async def message(sid, data):
    print('message ', data)
    await sio.emit('msg', "ur gayyy")


@sio.on('disconnect')
def disconnect(sid):
    print('disconnect ', sid)


if __name__ == '__main__':
    uvicorn.run(app, host="localhost", port=5000)
    # asgi_thread = Thread(target=run)
    # asgi_thread.daemon = True
    # asgi_thread.start()
Ejemplo n.º 12
0
                Route("/", CommunityOwnerAPI),
                Route("/matches/", CommunityOwnerMatchesAPI),
                Route("/update/", CommunityUpdateAPI),
                Mount("/payments", routes=[
                    Route("/", CommunityPaymentAPI),
                    Route("/card/", CommunityCardAPI)
                ])
            ]),
            Route("/public/", PublicCommunityAPI),
            Route("/", CommunityCreateAPI),
        ]),
        Mount("/communities", routes=[
            Route("/", CommunitiesAPI),
            Route("/matches/", CommunityMatchesAPI),
            Route("/all/", MatchesCommunitiesAPI)
        ]),
        Mount("/admin", routes=[
            Route("/communities/", CommunitiesAdminAPI),
            Route("/", AdminAPI)
        ]),
        Route("/schema/", SchemaAPI, include_in_schema=False)
    ]),
    Mount("/ws/", socketio.ASGIApp(Sessions.websocket)),
    Mount("/webhook", routes=[
        Mount("/payment", routes=[
            Route("/fail/", PaymentFailedWebhook),
            Route("/success/", PaymentSuccessWebhook)
        ])
    ])
]
Ejemplo n.º 13
0
import asyncio
import socketio
import uvicorn
import json
import settings
import sys

import python_serial as ps
import time

static_file = {'/': 'index.html', '/static': './static', '/css': './css'}
sio = socketio.AsyncServer(async_mode='asgi')
app = socketio.ASGIApp(sio, static_files=static_file)


@sio.event
def my_event(sid, data):
    pass


@sio.on('message')
async def another_event(sid, data):
    # print('message_event from: ', sid)
    # print('data: ', data)
    if data['get'] == 'data':
        try:
            data = ps.read_all_filtered_out()
            # print(data)
            await send_information(sid, json.dumps(data))
        except:
            print("Unexpected error:", sys.exc_info())
Ejemplo n.º 14
0
    GameFactory, \
    SioJoinGame, \
    GameController, \
    Game, \
    SioPlayersChanged, \
    SioSession, SioRoleAssignment, PersonaComposition, Persona, DecisionOption

rest_api = FastAPI()
# Socket.IO will be mounted as a sub application to the FastAPI main app.
# See the info here: https://github.com/tiangolo/fastapi/issues/129
sio = socketio.AsyncServer(async_mode='asgi')
# Note: It is mandatory to perform all calls to the websocket API with a trailing slash /.
# Otherwise, an error is returned, see ASGIApp.__call__.
# We use a constant that we can reference for our unit tests.
SOCKETIO_PATH = '/ws'
composed_app = socketio.ASGIApp(sio, other_asgi_app=rest_api, socketio_path=SOCKETIO_PATH)

# Set up logger.
log = logging.getLogger('api')
# TODO: For productive use, adjust the level.
log.setLevel(logging.DEBUG)

# GameController manages the running games.
game_controller = GameController()


@rest_api.get("/scenario/{scenario_id}")
async def get_scenario(scenario_id: int) -> Scenario:
    return Scenario(id=scenario_id,
                    titel='Asperger Syndrome: School inclusion',
                    descr='**The scenario**\n\nMartin is an 10 year old boy with a level 2 Asperger Syndrome, ' +
Ejemplo n.º 15
0
    CORSMiddleware,
    allow_origins=["*"],
    allow_credentials=False,
    allow_methods=["*"],
    allow_headers=["*"],
)
os.makedirs(app_config.static_directory, exist_ok=True)
app.mount(
    "/static",
    StaticFiles(directory=app_config.static_directory),
    name="static",
)
sio = socketio.AsyncServer(async_mode="asgi",
                           cors_allowed_origins="*",
                           logger=logger)
sio_app = socketio.ASGIApp(sio, other_asgi_app=app)

app.include_router(
    routes.building_map_router,
    prefix="/building_map",
)
app.include_router(routes.doors_router, prefix="/doors")
app.include_router(routes.lifts_router, prefix="/lifts")
app.include_router(routes.tasks_router, prefix="/tasks")


async def load_doors():
    door_states = await ttm.DoorState.all()
    for state in door_states:
        ros.rmf_gateway.door_states.on_next(state.to_rmf())
    logger.info(f"loaded {len(door_states)} door states")
Ejemplo n.º 16
0
#!/usr/bin/env python
import uvicorn

import socketio

sio = socketio.AsyncServer(async_mode='asgi')
app = socketio.ASGIApp(sio, static_files={
    '/': 'latency.html',
    '/static': 'static',
})


@sio.event
async def ping_from_client(sid):
    await sio.emit('pong_from_server', room=sid)


if __name__ == '__main__':
    uvicorn.run(app, host='0.0.0.0', port=8000)
Ejemplo n.º 17
0
import socketio
import uvicorn
from starlette.applications import Starlette

ROOM = 'room'

sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins='*')
star_app = Starlette(debug=True)
app = socketio.ASGIApp(sio, star_app)


@sio.event
async def connect(sid, environ):
    await sio.emit('ready', {'sid': sid}, room=ROOM, skip_sid=sid)
    sio.enter_room(sid, ROOM)


@sio.event
async def data(sid, data):
    peerToSend = None
    if 'sid' in data:
        peerToSend = data['sid']
    data['sid'] = sid
    await sio.emit('data',
                   data,
                   room=peerToSend if peerToSend else ROOM,
                   skip_sid=sid)


@sio.event
async def disconnect(sid):
Ejemplo n.º 18
0
#!/usr/bin/env python
import uvicorn

import socketio

sio = socketio.AsyncServer(async_mode='asgi')
app = socketio.ASGIApp(sio,
                       static_files={
                           '/': {
                               'content_type': 'text/html',
                               'filename': 'latency.html'
                           },
                           '/static/style.css': {
                               'content_type': 'text/css',
                               'filename': 'static/style.css'
                           },
                       })


@sio.on('ping_from_client')
async def ping(sid):
    await sio.emit('pong_from_server', room=sid)


if __name__ == '__main__':
    uvicorn.run(app, '127.0.0.1', 5000)
Ejemplo n.º 19
0
import socketio


sio = socketio.AsyncServer(async_mode='asgi', cors_allowed_origins=[])
socket_app = socketio.ASGIApp(sio)

@sio.event
def connect(sid, env):
    print('connect', sid)


@sio.event
def disconnect(sid):
    print('disconnect', sid)
Ejemplo n.º 20
0
#!/usr/bin/env python
import uvicorn

import socketio

sio = socketio.AsyncServer(async_mode='asgi')
app = socketio.ASGIApp(sio,
                       static_files={
                           '/': 'fiddle.html',
                           '/static': 'static',
                       })


@sio.event
async def connect(sid, environ):
    print('connected', sid)
    await sio.emit('hello', (1, 2, {'hello': 'you'}), to=sid)


@sio.event
def disconnect(sid):
    print('disconnected', sid)


if __name__ == '__main__':
    uvicorn.run(app, host='127.0.0.1', port=5000)
Ejemplo n.º 21
0

async def home(request):
    return templates.TemplateResponse('home.html', {'request': request})


async def chat(request):
    return templates.TemplateResponse('chat.html', {'request': request})


routes = [
    Route("/", home),
    Route("/chat/", chat),
    Mount('/static', StaticFiles(directory=appdir / 'static'), name='static')
]

sio = socketio.AsyncServer(async_mode='asgi')
sapp = Starlette(routes=routes)

app = socketio.ASGIApp(sio, sapp)


def messageReceived(methods=['GET', 'POST']):
    print('message was received!!!')


@sio.on('my event')
async def handle_my_custom_event(sid, json, methods=['GET', 'POST']):
    print('received my event: ' + str(sid), json)
    await sio.emit('my response', json, callback=messageReceived)
Ejemplo n.º 22
0
 def ready(self) -> socketio.ASGIApp:
     return socketio.ASGIApp(self.sio, self)
Ejemplo n.º 23
0
#!/usr/bin/env python3
# -*- coding: utf-8 -*-

import importlib
from asyncio import Queue

import socketio
from nonebot import get_driver
from nonebot.log import logger
# from socketio.exceptions import ConnectionRefusedError

from nonebot_plugin_test.view import WebSocket, handle_ws_reverse
from nonebot_plugin_test.utils import WEBSOCKET_CLOSE

sio = socketio.AsyncServer(async_mode="asgi", cors_allowed_origins="*")
socket_app = socketio.ASGIApp(sio, socketio_path="socket")


def init():
    driver = get_driver()
    try:
        _module = importlib.import_module(
            f"nonebot_plugin_test.drivers.{driver.type}")
    except ImportError:
        logger.warning(f"Driver {driver.type} not supported")
        return
    register_route = getattr(_module, "register_route")
    register_route(driver, socket_app)
    host = str(driver.config.host)
    port = driver.config.port
    if host in ["0.0.0.0", "127.0.0.1"]:
Ejemplo n.º 24
0
 def __post_init__(self):
     self.app = socketio.ASGIApp(self.sio)
     self.sio.on('rpc_call')(self.handle_rpc_call)
Ejemplo n.º 25
0
origins = [
    "http://localhost", "http://localhost:3000", "https://test.randosoru.me"
]
#

app = FastAPI(
    root_path="/api",
    title="Randosoru",
    description="API documents for guild.randosoru.me",
    version="0.5.6",
    docs_url=None,
    redoc_url="/doc",
)

sio_app = socketio.ASGIApp(sio_router.sio)

# CORS
app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)
#

app.include_router(oauth.router)
app.include_router(user.router)
app.include_router(form.router)
app.include_router(bot.router)
Ejemplo n.º 26
0
from starlette.middleware.cors import CORSMiddleware
from starlette.responses import HTMLResponse
from uvicorn.middleware.proxy_headers import ProxyHeadersMiddleware

redis = Redis(settings.REDIS_HOST)

class Broadcast(BaseModel):
    data : str

app = FastAPI()
app.add_middleware(CORSMiddleware, allow_origins=['*'], allow_methods=['GET', 'POST'])
app.add_middleware(ProxyHeadersMiddleware)

mgr = socketio.AsyncRedisManager('redis://%s' % settings.REDIS_HOST)
sio = socketio.AsyncServer(async_mode='asgi', client_manager=mgr)
app_sio = socketio.ASGIApp(sio, app)

from shared.models import Address, Transaction, Block, Utxo
from shared.settings import POOLS
from peewee import RawQuery, fn
from datetime import datetime, timedelta

@sio.on('subscribe')
async def subscribe(sid, room):
    sio.enter_room(sid, room)

def get_latest_block():
    return Block.select().order_by(Block.height.desc()).limit(1)[0]

def get_confirmations(height, block=None):
    if height is None:
Ejemplo n.º 27
0
    def __init__(self):

        self.sio = socketio.AsyncServer(async_mode='asgi')

        # wrap with ASGI application
        self.app = socketio.ASGIApp(self.sio)
        self.engine = None
        self.pending_requests = {}

        # create a Socket.IO server
        # self.sio = socketio.Server()
        #
        # # wrap with a WSGI application
        # self.app = socketio.WSGIApp(self.sio)

        @self.sio.event
        async def auth(sid, data):
            print('==========')
            print(data)
            print('==========')

            if 'username' not in data or 'password' not in data:
                return False

            user = amlink.users.get_user(data['username'])

            if user is None or not user.checkPassword(data['password']):
                return 'The username or password is incorrect'

            await self.sio.save_session(sid, {'username': data['username']})
            return True

        @self.sio.event
        async def register(sid, data):
            if amlink.config['allow_registration']:
                if 'username' in data and 'password' in data:
                    amlink.users.create_user(data['username'],
                                             data['password'])
                    await self.sio.save_session(sid,
                                                {'username': data['username']})

                    return True
                else:
                    return 'Username and password must be included'
            else:
                return 'Registration is disabled'

        @self.sio.event
        async def waifu_list(sid, data):
            session = await self.sio.get_session(sid)
            self.pending_requests[data['id']] = [
                sid, True, session['username']
            ]
            await self.engine.send_request(time.time(), 'getWaifu', {}, False)
            return True

        @self.sio.event
        async def message(sid, data):
            session = await self.sio.get_session(sid)
            self.pending_requests[data['id']] = [
                sid, True, session['username']
            ]
            await self.engine.send_request(time.time(), 'waifuPredict',
                                           data['arguments'], True)

        @self.sio.event
        async def connect(sid, environ):
            print('connected!', sid)
Ejemplo n.º 28
0
def setup_socketio_server(
    app: FastAPI,
    core_interface: CoreInterface,
    port: int,
    base_path: str = "/",
    allow_origins: Union[str, list] = "*",
    enable_server_apps: bool = False,
    enable_s3: bool = False,
    endpoint_url: str = None,
    access_key_id: str = None,
    secret_access_key: str = None,
    default_bucket: str = "imjoy-workspaces",
    **kwargs,
) -> None:
    """Set up the socketio server."""

    # pylint: disable=too-many-arguments

    def norm_url(url):
        return base_path.rstrip("/") + url

    HTTPProxy(core_interface)
    ASGIGateway(core_interface)

    @app.get(base_path)
    async def home():
        return {
            "name": "ImJoy Engine",
            "version": VERSION,
        }

    @app.get(norm_url("/stats"))
    async def stats():
        client_count = len(core_interface.get_all_users())
        return {
            "plugin_count":
            client_count,
            "workspace_count":
            len(core_interface.get_all_workspace()),
            "workspaces":
            [w.get_summary() for w in core_interface.get_all_workspace()],
        }

    if enable_server_apps:
        # pylint: disable=import-outside-toplevel
        from imjoy.apps import ServerAppController

        ServerAppController(core_interface, port=port)

    if enable_s3:
        # pylint: disable=import-outside-toplevel
        from imjoy.s3 import S3Controller

        S3Controller(
            core_interface.event_bus,
            core_interface,
            endpoint_url=endpoint_url,
            access_key_id=access_key_id,
            secret_access_key=secret_access_key,
            default_bucket=default_bucket,
        )

    @app.get(norm_url("/liveness"))
    async def liveness(req: Request) -> JSONResponse:
        try:
            await sio.emit("liveness")
        except Exception:  # pylint: disable=broad-except
            return JSONResponse({"status": "DOWN"}, status_code=503)
        return JSONResponse({"status": "OK"})

    if allow_origins == ["*"]:
        allow_origins = "*"
    sio = socketio.AsyncServer(async_mode="asgi",
                               cors_allowed_origins=allow_origins)

    _app = socketio.ASGIApp(socketio_server=sio,
                            socketio_path=norm_url("/socket.io"))

    app.mount("/", _app)
    app.sio = sio

    initialize_socketio(sio, core_interface)

    @app.on_event("startup")
    async def startup_event():
        core_interface.event_bus.emit("startup")

    @app.on_event("shutdown")
    def shutdown_event():
        core_interface.event_bus.emit("shutdown")

    return sio
Ejemplo n.º 29
0
import random
import psycopg2

connection = ''
# try:

# except (Exception, psycopg2.Error) as error :
#     print ("Error while connecting to PostgreSQL", error)
# finally:
#     if connection:
#         connection.close()
#         print("PostgreSQL connection is closed")

sio = socketio.AsyncServer(async_mode='asgi')
app = socketio.ASGIApp(sio, static_files={
    '/': 'app.html',
})
background_task_started = False

game_types = {
    '1': {
        'max_player': '2',
    },
    '2': {
        'max_player': '8',
    },
}
online_user_ids = {}
joined_room_player_ids = []
room_detail = {}
Ejemplo n.º 30
0
from bocadillo import App, Templates, static

app = App()
templates = Templates(app)

# Create a socket.io async server.
# NOTE: use the asgi driver, as described in:
# https://python-socketio.readthedocs.io/en/latest/server.html#uvicorn-daphne-and-other-asgi-servers
sio = socketio.AsyncServer(async_mode="asgi")

# Create an ASGI-compliant app out of the socket.io server,
# and mount it under the root app.
# NOTE: "socket.io" is the default for `socketio_path`. We only add it
# here for the sake of being explicit.
# As a result, the client can connect at `/sio/socket.io`.
app.mount("/sio", socketio.ASGIApp(sio, socketio_path="socket.io"))

# Server static files for the socket.io client.
# See: https://github.com/socketio/socket.io-client
# NOTE: alternatively, the socket.io client could be served from
# a CDN if you don't have npm/Node.js available in your runtime.
# If so, static files would be linked to in the HTML page, and we wouldn't
# need this line.
# See: https://socket.io/docs/#Javascript-Client
app.mount("/socket.io", static("node_modules/socket.io-client/dist"))


@app.route("/")
async def index(req, res):
    res.html = await templates.render("index.html")