app.py 3.0 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899
  1. import asyncpg
  2. import os
  3. from starlette.applications import Starlette
  4. from starlette.responses import HTMLResponse, JSONResponse, PlainTextResponse
  5. from starlette.routing import Route
  6. from starlette.templating import Jinja2Templates
  7. from random import randint, sample
  8. READ_ROW_SQL = 'SELECT "randomnumber", "id" FROM "world" WHERE id = $1'
  9. WRITE_ROW_SQL = 'UPDATE "world" SET "randomnumber"=$1 WHERE id=$2'
  10. ADDITIONAL_ROW = [0, 'Additional fortune added at request time.']
  11. async def setup_database():
  12. global connection_pool
  13. connection_pool = await asyncpg.create_pool(
  14. user=os.getenv('PGUSER', 'benchmarkdbuser'),
  15. password=os.getenv('PGPASS', 'benchmarkdbpass'),
  16. database='hello_world',
  17. host='tfb-database',
  18. port=5432
  19. )
  20. def get_num_queries(request):
  21. try:
  22. query_count = int(request.query_params["queries"])
  23. except (KeyError, IndexError, ValueError):
  24. return 1
  25. if query_count < 1:
  26. return 1
  27. if query_count > 500:
  28. return 500
  29. return query_count
  30. connection_pool = None
  31. templates = Jinja2Templates(directory="templates")
  32. async def single_database_query(request):
  33. row_id = randint(1, 10000)
  34. async with connection_pool.acquire() as connection:
  35. number = await connection.fetchval(READ_ROW_SQL, row_id)
  36. return JSONResponse({'id': row_id, 'randomNumber': number})
  37. async def multiple_database_queries(request):
  38. num_queries = get_num_queries(request)
  39. row_ids = sample(range(1, 10000), num_queries)
  40. worlds = []
  41. async with connection_pool.acquire() as connection:
  42. statement = await connection.prepare(READ_ROW_SQL)
  43. for row_id in row_ids:
  44. number = await statement.fetchval(row_id)
  45. worlds.append({'id': row_id, 'randomNumber': number})
  46. return JSONResponse(worlds)
  47. async def fortunes(request):
  48. async with connection_pool.acquire() as connection:
  49. fortunes = await connection.fetch('SELECT * FROM Fortune')
  50. fortunes.append(ADDITIONAL_ROW)
  51. fortunes.sort(key=lambda row: row[1])
  52. return templates.TemplateResponse("fortune.html", {"fortunes": fortunes, "request": request})
  53. async def database_updates(request):
  54. num_queries = get_num_queries(request)
  55. updates = [(row_id, randint(1, 10000)) for row_id in sample(range(1, 10000), num_queries)]
  56. worlds = [{'id': row_id, 'randomNumber': number} for row_id, number in updates]
  57. async with connection_pool.acquire() as connection:
  58. statement = await connection.prepare(READ_ROW_SQL)
  59. for row_id, number in updates:
  60. await statement.fetchval(row_id)
  61. await connection.executemany(WRITE_ROW_SQL, updates)
  62. return JSONResponse(worlds)
  63. routes = [
  64. Route('/json', JSONResponse({'message': 'Hello, world!'})),
  65. Route('/db', single_database_query),
  66. Route('/queries', multiple_database_queries),
  67. Route('/fortunes', fortunes),
  68. Route('/updates', database_updates),
  69. Route('/plaintext', PlainTextResponse(b'Hello, world!')),
  70. ]
  71. app = Starlette(routes=routes, on_startup=[setup_database])