app_async.py 3.2 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117
  1. #!/usr/bin/env python
  2. from datetime import datetime
  3. import os
  4. from random import randint
  5. from alchemical.aio import Alchemical
  6. import sqlalchemy as sqla
  7. from asyncache import cached
  8. from cachetools.keys import hashkey
  9. from microdot_asgi import Microdot
  10. from microdot_jinja import render_template
  11. app = Microdot()
  12. db = Alchemical(os.environ['DATABASE_URL'])
  13. class World(db.Model):
  14. __tablename__ = "world"
  15. id = sqla.Column(sqla.Integer, primary_key=True)
  16. randomnumber = sqla.Column(sqla.Integer)
  17. def to_dict(self):
  18. return {"id": self.id, "randomNumber": self.randomnumber}
  19. class CachedWorld(db.Model):
  20. __tablename__ = "cachedworld"
  21. id = sqla.Column(sqla.Integer, primary_key=True)
  22. randomnumber = sqla.Column(sqla.Integer)
  23. def to_dict(self):
  24. return {"id": self.id, "randomNumber": self.randomnumber}
  25. class Fortune(db.Model):
  26. __tablename__ = "fortune"
  27. id = sqla.Column(sqla.Integer, primary_key=True)
  28. message = sqla.Column(sqla.String)
  29. def get_num_queries(request, name="queries"):
  30. try:
  31. num_queries = request.args.get(name, 1, type=int)
  32. except ValueError:
  33. num_queries = 1
  34. if num_queries < 1:
  35. return 1
  36. if num_queries > 500:
  37. return 500
  38. return num_queries
  39. def generate_ids(num_queries):
  40. ids = {randint(1, 10000) for _ in range(num_queries)}
  41. while len(ids) < num_queries:
  42. ids.add(randint(1, 10000))
  43. return list(ids)
  44. @app.route("/json")
  45. async def test_json(request):
  46. return {"message": "Hello, World!"}
  47. @app.route("/db")
  48. async def test_db(request):
  49. id = randint(1, 10000)
  50. async with db.Session() as session:
  51. world = await session.get(World, id)
  52. return world.to_dict()
  53. @app.route("/queries")
  54. async def test_queries(request):
  55. async with db.Session() as session:
  56. worlds = [(await session.get(World, id)).to_dict() for id in generate_ids(get_num_queries(request))]
  57. return worlds
  58. @app.route("/fortunes")
  59. async def test_fortunes(request):
  60. async with db.Session() as session:
  61. fortunes = list(await session.scalars(Fortune.select()))
  62. fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
  63. fortunes.sort(key=lambda f: f.message)
  64. return render_template("fortunes.html", fortunes=fortunes), {'Content-Type': 'text/html; charset=utf-8'}
  65. @app.route("/updates")
  66. async def test_updates(request):
  67. worlds = []
  68. ids = generate_ids(get_num_queries(request))
  69. ids.sort() # to avoid deadlocks
  70. async with db.begin() as session:
  71. for id in ids:
  72. world = await session.get(World, id)
  73. world.randomnumber = (randint(1, 9999) + world.randomnumber - 1) % 10000 + 1
  74. worlds.append(world.to_dict())
  75. return worlds
  76. @app.route("/plaintext")
  77. async def test_plaintext(request):
  78. return b"Hello, World!"
  79. @cached(cache={}, key=lambda session, id: hashkey(id))
  80. async def get_cached_world(session, id):
  81. return (await session.get(World, id)).to_dict()
  82. @app.route("/cached-queries")
  83. async def test_cached_queries(request):
  84. async with db.Session() as session:
  85. worlds = [await get_cached_world(session, id) for id in generate_ids(get_num_queries(request, 'count'))]
  86. return worlds