app.py 5.4 KB

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