Browse Source

Merge branch 'bottle' of https://github.com/seanaedmiston/FrameworkBenchmarks into seanaedmiston-bottle

Patrick Falls 12 years ago
parent
commit
c66ee2f60f
6 changed files with 145 additions and 0 deletions
  1. 25 0
      bottle/README.md
  2. 0 0
      bottle/__init__.py
  3. 72 0
      bottle/app.py
  4. 20 0
      bottle/benchmark_config
  5. 23 0
      bottle/setup.py
  6. 5 0
      installer.py

+ 25 - 0
bottle/README.md

@@ -0,0 +1,25 @@
+# Bottle Benchmark Test
+
+Single file test, [app.py](app.py)
+
+
+## Test URLs
+### JSON Encoding 
+
+http://localhost:8080/json
+
+### Single Row Random Query
+
+With ORM:
+    http://localhost:8080/dbs
+
+Without ORM (raw):
+    http://localhost:8080/dbsraw
+
+### Variable Row Query Test 
+
+With ORM:
+    http://localhost:8080/db?queries=2
+
+Without ORM (raw):
+    http://localhost:8080/dbraw?queries=2

+ 0 - 0
bottle/__init__.py


+ 72 - 0
bottle/app.py

@@ -0,0 +1,72 @@
+from bottle import Bottle, route, request, run
+from bottle.ext import sqlalchemy 
+from sqlalchemy import create_engine, Column, Integer
+from sqlalchemy.ext.declarative import declarative_base
+from random import randint
+import ujson
+
+app = Bottle()
+app.config['SQLALCHEMY_DATABASE_URI'] = 'mysql://benchmarkdbuser:benchmarkdbpass@DBHOSTNAME:3306/hello_world'
+Base = declarative_base()
+db_engine = create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
+plugin = sqlalchemy.Plugin(db_engine, keyword='db', )
+app.install(plugin)
+
+
+class World(Base):
+  __tablename__ = "World"
+  id = Column(Integer, primary_key=True)
+  randomNumber = Column(Integer)
+
+  # http://stackoverflow.com/questions/7102754/jsonify-a-sqlalchemy-result-set-in-flask
+  @property
+  def serialize(self):
+     """Return object data in easily serializeable format"""
+     return {
+         'id'         : self.id,
+         'randomNumber': self.randomNumber
+     }
+
[email protected]("/json")
+def hello():
+  resp = {"message": "Hello, World!"}
+  return ujson.dumps(resp)
+
[email protected]("/db")
+def get_random_world(db):
+  num_queries = request.query.queries or '1'
+  worlds = []
+  for i in range(int(num_queries)):
+    wid = randint(1, 10000)
+    worlds.append(db.query(World).get(wid).serialize)
+  return ujson.dumps(worlds)
+
[email protected]("/dbs")
+def get_random_world_single(db):
+  wid = randint(1, 10000)
+  worlds = [db.query(World).get(wid).serialize]
+  return ujson.dumps(worlds)
+  
[email protected]("/dbraw")
+def get_random_world_raw():
+  connection = db_engine.connect()
+  num_queries = request.query.queries or '1'
+  worlds = []
+  for i in range(int(num_queries)):
+    wid = randint(1, 10000)
+    result = connection.execute("SELECT * FROM world WHERE id = " + str(wid)).fetchone()
+    worlds.append({'id': result[0], 'randomNumber': result[1]})
+  connection.close()
+  return ujson.dumps(worlds)
+
[email protected]("/dbsraw")
+def get_random_world_single_raw():
+  connection = db_engine.connect()
+  wid = randint(1, 10000)
+  result = connection.execute("SELECT * FROM world WHERE id = " + str(wid)).fetchone()
+  worlds = [{'id': result[0], 'randomNumber': result[1]}]
+  connection.close()
+  return ujson.dumps(worlds)
+
+if __name__ == "__main__":
+    app.run()

+ 20 - 0
bottle/benchmark_config

@@ -0,0 +1,20 @@
+{
+  "framework": "bottle",
+  "tests": [{
+    "default": {
+      "setup_file": "setup",
+      "json_url": "/json",
+      "db_url": "/dbs",
+      "query_url": "/db?queries=",
+      "port": 8080,
+      "sort": 31
+    },
+    "mysql-raw": {
+      "setup_file": "setup",
+      "db_url": "/dbsraw",
+      "query_url": "/dbraw?queries=",
+      "port": 8080,
+      "sort": 82
+    }
+  }]
+}

+ 23 - 0
bottle/setup.py

@@ -0,0 +1,23 @@
+import subprocess
+import sys
+import setup_util
+import os
+
+def start(args):
+  setup_util.replace_text("bottle/app.py", "DBHOSTNAME", args.database_host)
+  subprocess.Popen("gunicorn app:app -k gevent -b 0.0.0.0:8080 -w " + str((args.max_threads * 2)) + " --preload --log-level=critical", shell=True, cwd="bottle")
+  
+  return 0
+
+def stop():
+  p = subprocess.Popen(['ps', 'aux'], stdout=subprocess.PIPE)
+  out, err = p.communicate()
+  for line in out.splitlines():
+    if 'gunicorn' in line:
+      try:
+        pid = int(line.split(None, 2)[1])
+        os.kill(pid, 9)
+      except OSError:
+        pass
+  
+  return 0

+ 5 - 0
installer.py

@@ -254,6 +254,11 @@ class Installer:
     ##############################
     ##############################
     self.__run_command("sudo pip install flask flask-sqlalchemy")
     self.__run_command("sudo pip install flask flask-sqlalchemy")
 
 
+    ##############################
+    # Bottle
+    ##############################
+    self.__run_command("sudo pip install bottle bottle-sqlalchemy")
+
     ##############################
     ##############################
     # Play 2
     # Play 2
     ##############################
     ##############################