mirror of
https://github.com/wassname/catalyst.git
synced 2026-07-17 11:25:55 +08:00
added a simple data bootstrapper, to create a development environment
This commit is contained in:
@@ -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
|
||||
|
||||
@@ -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
@@ -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']))
|
||||
|
||||
Binary file not shown.
Reference in New Issue
Block a user