added a simple data bootstrapper, to create a development environment

This commit is contained in:
fawce
2012-01-09 15:29:39 -05:00
parent d39604847d
commit 12454f2c8c
4 changed files with 84 additions and 15 deletions
+29 -4
View File
@@ -1,5 +1,25 @@
# qbt - Quantopian Backtesting Services
##Development Quickstart
Navigate to your mongodb installation and start your db server:
./bin/mongodb
Install the necessary python libraries:
easy_install tornado pymongo
Create a development database with sample data, will create one qbt user:
python qbt_data_bootstrap.py --user_email=... --password=...
To run the qbt against a local mongodb instance, navigate to the source dir and run
python qbt_server.py --mongodb_dbname=qbt
To see all the available options:
python qbt_server.py --help
or
python qbt_data_bootstrap.py --help
qbt uses tornado to accept synchronous requests for backtesting sessions.
The client of a backtesting session first invokes the _backtest_ endpoint:
http://serverip/backtest?startdate=<>&enddate=<>...
@@ -13,17 +33,22 @@ A backtesting session is comprised of:
- an event stream delivered via zeromq
## Pre-requisites
You need to have the tornado and pymongo eggs installed:
easy_install tornado pymongo
### MongoDB Server ###
You need to have mongodb installed and running. Find your system at http://www.mongodb.org/downloads and set it up.
### Database and Collections expected in MongoDB ###
QBT requires a running mongodb instance with a few collections:
- user collection. See handlers.BaseHandler for code using this collection. Documents must have:
- user collection. See handlers.BaseHandler and handlers.LoginHandler for code using this collection. Documents must have:
- email - standard email address
- encrypted_password - an sha2 hex digest of the password
- salt - a secret other than the password, which can be set in a secure cookie to maintain a session. if unset, will be set to sha2 hex of datetime.utcnow()--password
- salt - sha256 hex of: datetime.utcnow()--password
- encrypted_password - an sha256 hex digest of: salt--password
- _id - standard issue mongodb primary key
## Authenticating
## Requesting a Backtest
+29
View File
@@ -0,0 +1,29 @@
import tornado.auth
import tornado.httpserver
import tornado.ioloop
from tornado.options import define, options
import tornado.web
import pymongo
import bson
import hashlib
import base64
import uuid
import os
import logging
import qbt_server
define("user_email", default="qbt@quantopian.com", help="email address for qbt user")
define("password", default="foobar", help="password for qbt user")
def db_main():
tornado.options.parse_command_line()
connection, db = qbt_server.connect_db()
#create a user for testing
salt, encrypted_password = qbt_server.encrypt_password(None, options.password)
db.users.insert({'email':options.user_email, 'encrypted_password':encrypted_password, 'salt':salt})
if __name__ == "__main__":
db_main()
+26 -11
View File
@@ -10,19 +10,38 @@ import base64
import uuid
import os
import logging
import datetime
logging.getLogger('qbt').setLevel(logging.DEBUG)
logger = logging.getLogger('qbt')
logging.getLogger().setLevel(logging.DEBUG)
logger = logging.getLogger()
define("port", default=8888, help="run the qbt on the given port", type=int)
define("mongodb_host", default="127.0.0.1", help="mongodb host address")
define("mongodb_port", default=27017, help="connect to the mongodb on the given port", type=int)
define("mongodb_dbname", default="blog", help="database name")
define("mongodb_user", default="blog", help="database user")
define("mongodb_password", default="blog", help="database password")
define("mongodb_dbname", default="qbt", help="database name")
define("mongodb_user", default="qbt", help="database user")
define("mongodb_password", default="qbt", help="database password")
HASH_ALGO = 'sha256'
def connect_db():
connection = pymongo.Connection(options.mongodb_host, options.mongodb_port)
db = connection[options.mongodb_dbname]
db.authenticate(options.mongodb_user, options.mongodb_password)
return connection, db
def encrypt_password(salt, password):
if(salt == None):
h1 = hashlib.new(HASH_ALGO)
h1.update(str(datetime.datetime.utcnow())+"--"+password)
salt = h1.hexdigest()
h2 = hashlib.new(HASH_ALGO)
h2.update(salt+"--"+password)
encrypted_password = h2.hexdigest()
return salt, encrypted_password
class Application(tornado.web.Application):
def __init__(self):
handlers = [
@@ -41,9 +60,7 @@ class Application(tornado.web.Application):
tornado.web.Application.__init__(self, handlers, **settings)
# Have one global connection to the blog DB across all handlers
self.connection = pymongo.Connection(options.mongodb_host, options.mongodb_port)
self.db = self.connection[options.mongodb_dbname]
self.db.authenticate(options.mongodb_user, options.mongodb_password)
self.connection, self.db = connect_db()
class BaseHandler(tornado.web.RequestHandler):
@@ -90,9 +107,7 @@ class LoginHandler(BaseHandler):
#calculate password hash
h.update(user_record['salt']+"--"+password)
encrypted_password = h.hexdigest()
logger.debug("checking {password} as {encrypted_password} against {record}".format(password=password, encrypted_password=encrypted_password, record=user_record['encrypted_password']))
salt, encrypted_password = encrypt_password(user_record['salt'], password)
if (user_record['encrypted_password'] == encrypted_password):
#we have a match, so set the secure cookie to the salt
logger.debug("setting user_id cookie to {id}".format(id=user_record['_id']))
BIN
View File
Binary file not shown.