Skip to content

Instantly share code, notes, and snippets.

@MeirKriheli
Last active December 17, 2015 06:08
Show Gist options
  • Save MeirKriheli/5562785 to your computer and use it in GitHub Desktop.
Save MeirKriheli/5562785 to your computer and use it in GitHub Desktop.
Tornado and Motor async connection
#!/usr/bin/env python
from tornado import ioloop, web, gen, options
import motor
import json
DEFAULT_TENANT = 'default' # If Host not found, which default service to Use
class Tenant(object):
def __init__(self, host, db, **settings):
self.host = host
self.db = db
self.settings = settings
class BaseHandler(web.RequestHandler):
# store database connections, based on host name, since this is mutable,
# it'll be shared with all instances and classes
tenants = {}
@property
def central(self):
return self.settings['db'].central
@gen.coroutine
def prepare(self):
self.tenant = yield self.get_tenant()
self.db = self.tenant.db
@gen.coroutine
def get_tenant(self):
"Get the db connection based on Host"
host = self.request.headers['Host']
tenant = self.tenants.get(host)
if tenant is not None:
raise gen.Return(tenant)
# try to get the host
data = yield motor.Op(self.central.tenants.find_one, {'name': host})
# if not found, fallback to default tenant
if data is None:
data = yield motor.Op(
self.central.tenants.find_one, {'name': DEFAULT_TENANT})
db_host = data['db'].get('host', 'localhost')
db_port = data['db'].get('host', 27017)
# TODO Replica set connections
cx = motor.MotorClient(db_host, db_port)
conn = yield motor.Op(cx.open)
tenant_db = conn[data['db']['name']]
tenant = Tenant(host, tenant_db)
self.tenants[host] = tenant
raise gen.Return(tenant)
class MainHandler(BaseHandler):
@gen.coroutine
def get(self):
cursor = self.db.items.find()
found = []
while (yield cursor.fetch_next):
doc = cursor.next_object()
doc['_id'] = str(doc['_id'])
found.append(doc)
self.set_header("Content-Type", "application/json; charset=UTF-8")
self.finish(json.dumps(found))
db = motor.MotorClient().open_sync()
app = web.Application([
(r'/', MainHandler),
], db=db, debug=True)
if __name__ == "__main__":
options.parse_command_line()
app.listen(8888)
ioloop.IOLoop.instance().start()
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment