| 123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136 | #!/usr/bin/env python3from random import randint, sampleimport osimport os.pathfrom typing import Any, Dict, List, Tuplefrom urllib.parse import parse_qsimport asyncpgimport jinja2import orjsonfrom bareasgi import Application, HttpRequest, HttpResponse, LifespanRequestfrom bareasgi_jinja2 import add_jinja2, Jinja2TemplateProviderGET_WORLD = "SELECT id, randomnumber FROM world WHERE id = $1"UPDATE_WORLD = "UPDATE world SET randomNumber = $2 WHERE id = $1"GET_FORTUNES = "SELECT * FROM fortune"ADDITIONAL_ROW = (0, "Additional fortune added at request time.")async def on_startup(_request: LifespanRequest) -> None:    app.info['db'] = await asyncpg.create_pool(        user=os.getenv("PGUSER", "benchmarkdbuser"),        password=os.getenv("PGPASS", "benchmarkdbpass"),        database="hello_world",        host="tfb-database",        port=5432,    )async def on_shutdown(_request: LifespanRequest) -> None:    await app.info['db'].close()async def handle_json_request(_request: HttpRequest) -> HttpResponse:    return HttpResponse.from_json(        {"message": "Hello, World!"},        encode_bytes=orjson.dumps    )async def handle_plaintext_request(_request: HttpRequest) -> HttpResponse:    return HttpResponse.from_text("Hello, World!")async def handle_db_request(_request: HttpRequest) -> HttpResponse:    key = randint(1, 10000)    async with app.info['db'].acquire() as conn:        number = await conn.fetchval(GET_WORLD, key)    return HttpResponse.from_json(        {"id": key, "randomNumber": number},        encode_bytes=orjson.dumps    )def get_query_count(request: HttpRequest):    try:        qs = parse_qs(request.scope["query_string"])        num_queries = int(qs.get(b'queries', (1, ))[0])    except ValueError:        num_queries = 1    if num_queries < 1:        return 1    if num_queries > 500:        return 500            return num_queriesasync def handle_queries_request(request: HttpRequest) -> HttpResponse:    queries = get_query_count(request)    worlds: List[Dict[str, Any]] = []    async with app.info['db'].acquire() as conn:        pst = await conn.prepare(GET_WORLD)        for key in sample(range(1, 10000), queries):            number = await pst.fetchval(key)            worlds.append({"id": key, "randomNumber": number})    return HttpResponse.from_json(        worlds,        encode_bytes=orjson.dumps    )async def handle_updates_request(request: HttpRequest) -> HttpResponse:    queries = get_query_count(request)    updates = [(row_id, randint(1, 10000)) for row_id in sample(range(1, 10000), queries)]    updates.sort()    worlds = [{'id': row_id, 'randomNumber': number} for row_id, number in updates]    async with app.info['db'].acquire() as connection:        statement = await connection.prepare(GET_WORLD)        for row_id, number in updates:            await statement.fetchval(row_id)        await connection.executemany(UPDATE_WORLD, updates)    return HttpResponse.from_json(        worlds,        encode_bytes=orjson.dumps    )async def handle_fortunes_request(request: HttpRequest) -> HttpResponse:    async with app.info['db'].acquire() as conn:        rows = await conn.fetch(GET_FORTUNES)    rows.append(ADDITIONAL_ROW)    rows.sort(key=lambda row: row[1])    return await Jinja2TemplateProvider.apply(        request,        "fortune.html",        { "fortunes": rows }    )app = Application(    startup_handlers=[on_startup],    shutdown_handlers=[on_shutdown])here = os.path.abspath(os.path.dirname(__file__))env = jinja2.Environment(    loader=jinja2.FileSystemLoader(os.path.join(here, 'templates')),    autoescape=jinja2.select_autoescape(['html', 'xml']),    enable_async=True)add_jinja2(app, env)app.http_router.add({"GET"}, "/json", handle_json_request)app.http_router.add({"GET"}, "/plaintext", handle_plaintext_request)app.http_router.add({"GET"}, "/db", handle_db_request)app.http_router.add({"GET"}, "/queries", handle_queries_request)app.http_router.add({"GET"}, "/updates", handle_updates_request)app.http_router.add({"GET"}, "/fortunes", handle_fortunes_request)
 |