app.py 5.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205
  1. #!/usr/bin/env python
  2. from functools import partial
  3. import json
  4. from operator import attrgetter
  5. import os
  6. from random import randint
  7. import sys
  8. import flask
  9. from flask import Flask, request, render_template, make_response, jsonify
  10. from flask.ext.sqlalchemy import SQLAlchemy
  11. from sqlalchemy import create_engine
  12. from sqlalchemy.ext import baked
  13. if sys.version_info[0] == 3:
  14. xrange = range
  15. DBHOST = os.environ.get('DBHOST', 'localhost')
  16. try:
  17. import MySQLdb
  18. mysql_schema = "mysql:"
  19. except ImportError:
  20. mysql_schema = "mysql+pymysql:"
  21. # setup
  22. app = Flask(__name__)
  23. app.config['SQLALCHEMY_DATABASE_URI'] = mysql_schema + '//benchmarkdbuser:benchmarkdbpass@%s:3306/hello_world?charset=utf8' % DBHOST
  24. app.config['JSONIFY_PRETTYPRINT_REGULAR'] = False
  25. db = SQLAlchemy(app)
  26. dbraw_engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'], connect_args={'autocommit': True}, pool_reset_on_return=None)
  27. bakery = baked.bakery()
  28. # models
  29. class World(db.Model):
  30. __tablename__ = "World"
  31. id = db.Column(db.Integer, primary_key=True)
  32. randomNumber = db.Column(db.Integer)
  33. # http://stackoverflow.com/questions/7102754/jsonify-a-sqlalchemy-result-set-in-flask
  34. @property
  35. def serialize(self):
  36. """Return object data in easily serializeable format"""
  37. return {
  38. 'id' : self.id,
  39. 'randomNumber': self.randomNumber
  40. }
  41. @staticmethod
  42. def get(ident):
  43. baked_query = bakery(lambda s: s.query(World))
  44. return baked_query(db.session()).get(ident)
  45. class Fortune(db.Model):
  46. __tablename__ = "Fortune"
  47. id = db.Column(db.Integer, primary_key=True)
  48. message = db.Column(db.String)
  49. # views
  50. # flask.jsonify doesn't allow array at top level for security concern.
  51. # So we should have oriiginal one.
  52. def json_response(obj):
  53. res = make_response(json.dumps(obj))
  54. res.mimetype = "application/json"
  55. return res
  56. @app.route("/json")
  57. def hello():
  58. return jsonify(message='Hello, World!')
  59. @app.route("/db")
  60. def get_random_world():
  61. num_queries = request.args.get("queries", 1, type=int)
  62. if num_queries < 1:
  63. num_queries = 1
  64. if num_queries > 500:
  65. num_queries = 500
  66. worlds = [World.get(randint(1, 10000)).serialize
  67. for _ in xrange(num_queries)]
  68. return json_response(worlds)
  69. @app.route("/dbs")
  70. def get_random_world_single():
  71. wid = randint(1, 10000)
  72. worlds = World.get(wid).serialize
  73. return json_response(worlds)
  74. @app.route("/dbraw")
  75. def get_random_world_raw():
  76. connection = dbraw_engine.connect()
  77. num_queries = request.args.get("queries", 1, type=int)
  78. if num_queries < 1:
  79. num_queries = 1
  80. if num_queries > 500:
  81. num_queries = 500
  82. worlds = []
  83. for i in xrange(num_queries):
  84. wid = randint(1, 10000)
  85. result = connection.execute("SELECT * FROM World WHERE id = " + str(wid)).fetchone()
  86. worlds.append({'id': result[0], 'randomNumber': result[1]})
  87. connection.close()
  88. return json_response(worlds)
  89. @app.route("/dbsraw")
  90. def get_random_world_single_raw():
  91. connection = dbraw_engine.connect()
  92. wid = randint(1, 10000)
  93. result = connection.execute("SELECT * FROM World WHERE id = " + str(wid)).fetchone()
  94. worlds = {'id': result[0], 'randomNumber': result[1]}
  95. connection.close()
  96. return json_response(worlds)
  97. @app.route("/fortunes")
  98. def get_fortunes():
  99. fortunes = list(Fortune.query.all())
  100. fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
  101. fortunes.sort(key=attrgetter('message'))
  102. return render_template('fortunes.html', fortunes=fortunes)
  103. @app.route("/fortunesraw")
  104. def get_forutens_raw():
  105. res = dbraw_engine.execute("SELECT * FROM Fortune")
  106. fortunes = res.fetchall()
  107. res.close()
  108. fortunes.append(Fortune(id=0, message="Additional fortune added at request time."))
  109. fortunes.sort(key=attrgetter('message'))
  110. return render_template('fortunes.html', fortunes=fortunes)
  111. @app.route("/updates")
  112. def updates():
  113. """Test 5: Database Updates"""
  114. num_queries = request.args.get('queries', 1, type=int)
  115. if num_queries < 1:
  116. num_queries = 1
  117. if num_queries > 500:
  118. num_queries = 500
  119. worlds = []
  120. rp = partial(randint, 1, 10000)
  121. ids = [rp() for _ in xrange(num_queries)]
  122. ids.sort() # To avoid deadlock
  123. for id in ids:
  124. world = World.get(id)
  125. world.randomNumber = rp()
  126. worlds.append(world.serialize)
  127. res = json_response(worlds)
  128. db.session.commit()
  129. return res
  130. @app.route("/raw-updates")
  131. def raw_updates():
  132. """Test 5: Database Updates"""
  133. connection = dbraw_engine.connect()
  134. try:
  135. num_queries = request.args.get('queries', 1, type=int)
  136. if num_queries < 1:
  137. num_queries = 1
  138. if num_queries > 500:
  139. num_queries = 500
  140. worlds = []
  141. rp = partial(randint, 1, 10000)
  142. for i in xrange(num_queries):
  143. world = connection.execute("SELECT * FROM World WHERE id=%s", (rp(),)).fetchone()
  144. randomNumber = rp()
  145. worlds.append({'id': world['id'], 'randomNumber': randomNumber})
  146. connection.execute("UPDATE World SET randomNumber=%s WHERE id=%s", (randomNumber, world['id']))
  147. return json_response(worlds)
  148. finally:
  149. connection.close()
  150. @app.route('/plaintext')
  151. def plaintext():
  152. """Test 6: Plaintext"""
  153. response = make_response(b'Hello, World!')
  154. response.content_type = 'text/plain'
  155. return response
  156. try:
  157. import meinheld
  158. meinheld.server.set_access_logger(None)
  159. meinheld.set_keepalive(120)
  160. except ImportError:
  161. pass
  162. # entry point for debugging
  163. if __name__ == "__main__":
  164. app.run(debug=True)