app.py 4.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164
  1. import cgi
  2. import os
  3. import sys
  4. from functools import partial
  5. from operator import attrgetter
  6. from random import randint
  7. from wheezy.http import HTTPResponse
  8. from wheezy.http import WSGIApplication
  9. from wheezy.routing import url
  10. from wheezy.web.handlers import BaseHandler
  11. from wheezy.web.middleware import bootstrap_defaults
  12. from wheezy.web.middleware import path_routing_middleware_factory
  13. from wheezy.template.engine import Engine
  14. from wheezy.template.ext.core import CoreExtension
  15. from wheezy.template.loader import FileLoader
  16. from sqlalchemy.ext.declarative import declarative_base
  17. from sqlalchemy import create_engine, Column
  18. from sqlalchemy.types import String, Integer, Unicode
  19. from sqlalchemy.orm import sessionmaker
  20. from meinheld import server
  21. DBDRIVER = 'mysql'
  22. DBHOSTNAME = os.environ.get('DBHOST', 'localhost')
  23. DATABASE_URI = '%s://benchmarkdbuser:benchmarkdbpass@%s:3306/hello_world?charset=utf8' % (DBDRIVER, DBHOSTNAME)
  24. Base = declarative_base()
  25. db_engine = create_engine(DATABASE_URI)
  26. Session = sessionmaker(bind=db_engine)
  27. db_session = Session()
  28. if sys.version_info[0] == 3:
  29. xrange = range
  30. def getQueryNum(queryString):
  31. try:
  32. int(queryString)
  33. return int(queryString)
  34. except ValueError:
  35. return 1
  36. class Fortune(Base):
  37. __tablename__ = "Fortune"
  38. id = Column(Integer, primary_key=True)
  39. message = Column(String)
  40. def serialize(self):
  41. return {
  42. 'id': self.id,
  43. 'randomNumber': self.randomNumber,
  44. }
  45. class World(Base):
  46. __tablename__ = "World"
  47. id = Column(Integer, primary_key=True)
  48. randomNumber = Column(Integer)
  49. def serialize(self):
  50. return {
  51. 'id': self.id,
  52. 'randomNumber': self.randomNumber,
  53. }
  54. class JsonHandler(BaseHandler):
  55. def get(self):
  56. response = self.json_response({"message": "Hello, World!"})
  57. response.headers = [("Content-Type", "application/json; charset=UTF-8")]
  58. return response
  59. class DbHandler(BaseHandler):
  60. def get(self):
  61. db_engine.connect()
  62. wid = randint(1, 10000)
  63. world = db_session.query(World).get(wid).serialize()
  64. return self.json_response(world)
  65. class QueriesHandler(BaseHandler):
  66. def get(self):
  67. queries = self.request.get_param("queries")
  68. num_queries = getQueryNum(queries)
  69. if num_queries < 1:
  70. num_queries = 1
  71. if num_queries > 500:
  72. num_queries = 500
  73. rp = partial(randint, 1, 10000)
  74. get = db_session.query(World).get
  75. worlds = [get(rp()).serialize() for _ in xrange(num_queries)]
  76. return self.json_response(worlds)
  77. class UpdatesHandler(BaseHandler):
  78. def get(self):
  79. queries = self.request.get_param("queries")
  80. num_queries = getQueryNum(queries)
  81. if num_queries < 1:
  82. num_queries = 1
  83. if num_queries > 500:
  84. num_queries = 500
  85. worlds = []
  86. rp = partial(randint, 1, 10000)
  87. ids = [rp() for _ in xrange(num_queries)]
  88. ids.sort() # To avoid deadlock
  89. for id in ids:
  90. world = db_session.query(World).get(id)
  91. world.randomNumber = rp()
  92. worlds.append(world.serialize())
  93. db_session.commit()
  94. return self.json_response(worlds)
  95. template_engine = Engine(loader=FileLoader(["views"]), extensions=[CoreExtension()])
  96. template_engine.global_vars['escape'] = cgi.escape
  97. class FortuneHandler(BaseHandler):
  98. def get(self):
  99. fortunes = db_session.query(Fortune).all()
  100. fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
  101. fortunes.sort(key=attrgetter("message"))
  102. template = template_engine.get_template("fortune.html")
  103. template_html = template.render({"fortunes": fortunes})
  104. response = HTTPResponse()
  105. response.write(template_html)
  106. return response
  107. def plaintext(request):
  108. response = HTTPResponse()
  109. response.headers = [("Content-Type", "text/plain; charset=UTF-8")]
  110. response.write("Hello, world!")
  111. return response
  112. def sqlalchemy_close_middleware(request, following):
  113. """Close db_session for each request"""
  114. try:
  115. return following(request)
  116. finally:
  117. db_session.remove()
  118. all_urls = [
  119. url("plaintext", plaintext, name="plaintext"),
  120. url("json", JsonHandler, name="json"),
  121. url("db", DbHandler, name="db"),
  122. url("queries", QueriesHandler, name="queries"),
  123. url("updates", UpdatesHandler, name="updates"),
  124. url("fortune", FortuneHandler, name="fortune")
  125. ]
  126. options = {}
  127. app = WSGIApplication(
  128. middleware = [
  129. bootstrap_defaults(url_mapping=all_urls),
  130. path_routing_middleware_factory,
  131. lambda _: sqlalchemy_close_middleware,
  132. ],
  133. options = options
  134. )
  135. if __name__ == '__main__':
  136. server.listen(("127.0.0.1", 8080))
  137. server.run(app)