Beispiel #1
0
tasks = [{
    'id': 1,
    'title': u'Buy groceries',
    'description': u'Milk, Cheese, Pizza, Fruit, Tylenol',
    'done': False
}, {
    'id': 2,
    'title': u'Learn Python',
    'description': u'Need to find a good Python tutorial on the web',
    'done': False
}]

#Authentication function
from flask.ext.httpauth import HTTPBasicAuth
auth = HTTPBasicAuth()


@auth.get_password
def get_password(username):
    if username == 'chintan':
        return 'python'
    return None


@auth.error_handler
def unauthorized():
    return make_response(jsonify({'error': 'Unauthorized access'}), 401)


#to show all tasks WITHOUT PROPER url
    def setUp(self):
        app = Flask(__name__)
        app.config['SECRET_KEY'] = 'my secret'

        basic_auth = HTTPBasicAuth()
        basic_auth_my_realm = HTTPBasicAuth()
        basic_auth_my_realm.realm = 'My Realm'
        basic_custom_auth = HTTPBasicAuth()
        basic_verify_auth = HTTPBasicAuth()
        digest_auth = HTTPDigestAuth()
        digest_auth_my_realm = HTTPDigestAuth()
        digest_auth_my_realm.realm = 'My Realm'

        @basic_auth.get_password
        def get_basic_password(username):
            if username == 'john':
                return 'hello'
            elif username == 'susan':
                return 'bye'
            else:
                return None

        @basic_auth_my_realm.get_password
        def get_basic_password_2(username):
            if username == 'john':
                return 'johnhello'
            elif username == 'susan':
                return 'susanbye'
            else:
                return None

        @basic_auth_my_realm.hash_password
        def basic_auth_my_realm_hash_password(username, password):
            return username + password

        @basic_auth_my_realm.error_handler
        def basic_auth_my_realm_error():
            return 'custom error'

        @basic_custom_auth.get_password
        def get_basic_custom_auth_get_password(username):
            if username == 'john':
                return md5('hello').hexdigest()
            elif username == 'susan':
                return md5('bye').hexdigest()
            else:
                return None

        @basic_custom_auth.hash_password
        def basic_custom_auth_hash_password(password):
            return md5(password).hexdigest()

        @basic_verify_auth.verify_password
        def basic_verify_auth_verify_password(username, password):
            g.anon = False
            if username == 'john':
                return password == 'hello'
            elif username == 'susan':
                return password == 'bye'
            elif username == '':
                g.anon = True
                return True
            return False

        @digest_auth.get_password
        def get_digest_password(username):
            if username == 'susan':
                return 'hello'
            elif username == 'john':
                return 'bye'
            else:
                return None

        @digest_auth_my_realm.get_password
        def get_digest_password_2(username):
            if username == 'susan':
                return 'hello'
            elif username == 'john':
                return 'bye'
            else:
                return None

        @app.route('/')
        def index():
            return 'index'

        @app.route('/basic')
        @basic_auth.login_required
        def basic_auth_route():
            return 'basic_auth:' + basic_auth.username()

        @app.route('/basic-with-realm')
        @basic_auth_my_realm.login_required
        def basic_auth_my_realm_route():
            return 'basic_auth_my_realm:' + basic_auth_my_realm.username()

        @app.route('/basic-custom')
        @basic_custom_auth.login_required
        def basic_custom_auth_route():
            return 'basic_custom_auth:' + basic_custom_auth.username()

        @app.route('/basic-verify')
        @basic_verify_auth.login_required
        def basic_verify_auth_route():
            return 'basic_verify_auth:' + basic_verify_auth.username() + \
                ' anon:' + str(g.anon)

        @app.route('/digest')
        @digest_auth.login_required
        def digest_auth_route():
            return 'digest_auth:' + digest_auth.username()

        @app.route('/digest-with-realm')
        @digest_auth_my_realm.login_required
        def digest_auth_my_realm_route():
            return 'digest_auth_my_realm:' + digest_auth_my_realm.username()

        self.app = app
        self.basic_auth = basic_auth
        self.basic_auth_my_realm = basic_auth_my_realm
        self.basic_custom_auth = basic_custom_auth
        self.basic_verify_auth = basic_verify_auth
        self.digest_auth = digest_auth
        self.client = app.test_client()
Beispiel #3
0
    def run(self):
        db = util.connect_to_db(flags='SQLITE_OPEN_READONLY')
        app = flask.Flask(__name__)
        auth = HTTPBasicAuth()

        @auth.get_password
        def get_pw(username):
            if username == config.RPC_USER:
                return config.RPC_PASSWORD
            return None        

        ######################
        #READ API

        # Generate dynamically get_{table} methods
        def generate_get_method(table):
            def get_method(**kwargs):
                return get_rows(db, table=table, **kwargs)
            return get_method

        for table in API_TABLES:
            new_method = generate_get_method(table)
            new_method.__name__ = 'get_{}'.format(table)
            dispatcher.add_method(new_method)

        @dispatcher.add_method
        def sql(query, bindings=[]):
            return db_query(db, query, tuple(bindings))


        ######################
        #WRITE/ACTION API

        # Generate dynamically create_{transaction} and do_{transaction} methods
        def generate_create_method(transaction):

            def split_params(**kwargs):
                transaction_args = {}
                common_args = {}
                private_key_wif = None
                for key in kwargs:
                    if key in COMMONS_ARGS:
                        common_args[key] = kwargs[key]
                    elif key == 'privkey':
                        private_key_wif = kwargs[key]
                    else:
                        transaction_args[key] = kwargs[key]
                return transaction_args, common_args, private_key_wif

            def create_method(**kwargs):
                transaction_args, common_args, private_key_wif = split_params(**kwargs)
                return compose_transaction(db, name=transaction, params=transaction_args, **common_args)

            def do_method(**kwargs):
                transaction_args, common_args, private_key_wif = split_params(**kwargs)
                return do_transaction(db, name=transaction, params=transaction_args, private_key_wif=private_key_wif, **common_args)

            return create_method, do_method

        for transaction in API_TRANSACTIONS:
            create_method, do_method = generate_create_method(transaction)
            create_method.__name__ = 'create_{}'.format(transaction)
            do_method.__name__ = 'do_{}'.format(transaction)
            dispatcher.add_method(create_method)
            dispatcher.add_method(do_method)

        @dispatcher.add_method
        def sign_tx(unsigned_tx_hex, privkey=None):
            return sign_transaction(unsigned_tx_hex, private_key_wif=privkey)

        @dispatcher.add_method
        def broadcast_tx(signed_tx_hex):
            return broadcast_transaction(signed_tx_hex)

        @dispatcher.add_method
        def get_messages(block_index):
            if not isinstance(block_index, int):
                raise Exception("block_index must be an integer.")

            cursor = db.cursor()
            cursor.execute('select * from messages where block_index = ? order by message_index asc', (block_index,))
            messages = cursor.fetchall()
            cursor.close()
            return messages

        @dispatcher.add_method
        def get_messages_by_index(message_indexes):
            """Get specific messages from the feed, based on the message_index.

            @param message_index: A single index, or a list of one or more message indexes to retrieve.
            """
            if not isinstance(message_indexes, list):
                message_indexes = [message_indexes,]
            for idx in message_indexes:  #make sure the data is clean
                if not isinstance(idx, int):
                    raise Exception("All items in message_indexes are not integers")

            cursor = db.cursor()
            cursor.execute('SELECT * FROM messages WHERE message_index IN (%s) ORDER BY message_index ASC'
                % (','.join([str(x) for x in message_indexes]),))
            messages = cursor.fetchall()
            cursor.close()
            return messages

        @dispatcher.add_method
        def get_xcp_supply():
            return util.xcp_supply(db)

        @dispatcher.add_method
        def get_asset_info(assets):
            if not isinstance(assets, list):
                raise Exception("assets must be a list of asset names, even if it just contains one entry")
            assetsInfo = []
            for asset in assets:

                # BTC and XCP.
                if asset in [config.BTC, config.XCP]:
                    if asset == config.BTC:
                        supply = bitcoin.get_btc_supply(normalize=False)
                    else:
                        supply = util.xcp_supply(db)

                    assetsInfo.append({
                        'asset': asset,
                        'owner': None,
                        'divisible': True,
                        'locked': False,
                        'supply': supply,
                        'callable': False,
                        'call_date': None,
                        'call_price': None,
                        'description': '',
                        'issuer': None
                    })
                    continue

                # User‐created asset.
                cursor = db.cursor()
                issuances = list(cursor.execute('''SELECT * FROM issuances WHERE (status = ? AND asset = ?) ORDER BY block_index ASC''', ('valid', asset)))
                cursor.close()
                if not issuances: break #asset not found, most likely
                else: last_issuance = issuances[-1]
                supply = 0
                locked = False
                for e in issuances:
                    if e['locked']: locked = True
                    supply += e['quantity']
                assetsInfo.append({
                    'asset': asset,
                    'owner': last_issuance['issuer'],
                    'divisible': bool(last_issuance['divisible']),
                    'locked': locked,
                    'supply': supply,
                    'callable': bool(last_issuance['callable']),
                    'call_date': last_issuance['call_date'],
                    'call_price': last_issuance['call_price'],
                    'description': last_issuance['description'],
                    'issuer': last_issuance['issuer']})
            return assetsInfo

        @dispatcher.add_method
        def get_block_info(block_index):
            assert isinstance(block_index, int)
            cursor = db.cursor()
            cursor.execute('''SELECT * FROM blocks WHERE block_index = ?''', (block_index,))
            try:
                blocks = list(cursor)
                assert len(blocks) == 1
                block = blocks[0]
            except IndexError:
                raise exceptions.DatabaseError('No blocks found.')
            cursor.close()
            return block
        
        @dispatcher.add_method
        def get_blocks(block_indexes):
            """fetches block info and messages for the specified block indexes"""
            if not isinstance(block_indexes, (list, tuple)):
                raise Exception("block_indexes must be a list of integers.")
            if len(block_indexes) >= 250:
                raise Exception("can only specify up to 250 indexes at a time.")

            block_indexes_str = ','.join([str(x) for x in block_indexes])
            cursor = db.cursor()
            
            cursor.execute('SELECT * FROM blocks WHERE block_index IN (%s) ORDER BY block_index ASC'
                % (block_indexes_str,))
            blocks = cursor.fetchall()
                
            cursor.execute('SELECT * FROM messages WHERE block_index IN (%s) ORDER BY block_index ASC, message_index ASC'
                % (block_indexes_str,))
            messages = collections.deque(cursor.fetchall())
            
            for block in blocks:
                messages_in_block = []
                block['_messages'] = []
                while len(messages) and messages[0]['block_index'] == block['block_index']:
                    block['_messages'].append(messages.popleft())
            
            cursor.close()
            return blocks

        @dispatcher.add_method
        def get_running_info():
            latestBlockIndex = bitcoin.get_block_count()

            try:
                util.database_check(db, latestBlockIndex)
            except exceptions.DatabaseError as e:
                caught_up = False
            else:
                caught_up = True

            try:
                last_block = util.last_block(db)
            except:
                last_block = {'block_index': None, 'block_hash': None, 'block_time': None}

            try:
                last_message = util.last_message(db)
            except:
                last_message = None

            return {
                'db_caught_up': caught_up,
                'bitcoin_block_count': latestBlockIndex,
                'last_block': last_block,
                'last_message_index': last_message['message_index'] if last_message else -1,
                'running_testnet': config.TESTNET,
                'running_testcoin': config.TESTCOIN,
                'version_major': config.VERSION_MAJOR,
                'version_minor': config.VERSION_MINOR,
                'version_revision': config.VERSION_REVISION
            }

        @dispatcher.add_method
        def get_element_counts():
            counts = {}
            cursor = db.cursor()
            for element in ['transactions', 'blocks', 'debits', 'credits', 'balances', 'sends', 'orders',
                'order_matches', 'btcpays', 'issuances', 'broadcasts', 'bets', 'bet_matches', 'dividends',
                'burns', 'cancels', 'callbacks', 'order_expirations', 'bet_expirations', 'order_match_expirations',
                'bet_match_expirations', 'messages']:
                cursor.execute("SELECT COUNT(*) AS count FROM %s" % element)
                count_list = cursor.fetchall()
                assert len(count_list) == 1
                counts[element] = count_list[0]['count']
            cursor.close()
            return counts

        @dispatcher.add_method
        def get_asset_names():
            cursor = db.cursor()
            names = [row['asset'] for row in cursor.execute("SELECT DISTINCT asset FROM issuances WHERE status = 'valid' ORDER BY asset ASC")]
            cursor.close()
            return names

        def _set_cors_headers(response):
            if config.RPC_ALLOW_CORS:
                response.headers['Access-Control-Allow-Origin'] = '*'
                response.headers['Access-Control-Allow-Methods'] = 'GET, POST, OPTIONS'
                response.headers['Access-Control-Allow-Headers'] = 'DNT,X-Mx-ReqToken,Keep-Alive,User-Agent,X-Requested-With,If-Modified-Since,Cache-Control,Content-Type';
    
        @app.route('/', methods=["OPTIONS",])
        @app.route('/api/', methods=["OPTIONS",])
        def handle_options():
            response = flask.Response('', 204)
            _set_cors_headers(response)
            return response

        @app.route('/', methods=["POST",])
        @app.route('/api/', methods=["POST",])
        @auth.login_required
        def handle_post():
            try:
                request_json = flask.request.get_data().decode('utf-8')
                request_data = json.loads(request_json)
                assert 'id' in request_data and request_data['jsonrpc'] == "2.0" and request_data['method']
                # params may be omitted 
            except:
                obj_error = jsonrpc.exceptions.JSONRPCInvalidRequest(data="Invalid JSON-RPC 2.0 request format")
                return flask.Response(obj_error.json.encode(), 200, mimetype='application/json')
            
            #only arguments passed as a dict are supported
            if request_data.get('params', None) and not isinstance(request_data['params'], dict):
                obj_error = jsonrpc.exceptions.JSONRPCInvalidRequest(
                    data='Arguments must be passed as a JSON object (list of unnamed arguments not supported)')
                return flask.Response(obj_error.json.encode(), 200, mimetype='application/json')
            
            #return an error if API fails checks
            if not config.FORCE and current_api_status_code:
                return flask.Response(current_api_status_response_json, 200, mimetype='application/json')

            jsonrpc_response = jsonrpc.JSONRPCResponseManager.handle(request_json, dispatcher)
            response = flask.Response(jsonrpc_response.json.encode(), 200, mimetype='application/json')
            _set_cors_headers(response)
            return response

        if not config.UNITTEST:  #skip setting up logs when for the test suite
            api_logger = logging.getLogger("tornado")
            h = logging_handlers.RotatingFileHandler(os.path.join(config.DATA_DIR, "api.access.log"), 'a', API_MAX_LOG_SIZE, API_MAX_LOG_COUNT)
            api_logger.setLevel(logging.INFO)
            api_logger.addHandler(h)
            api_logger.propagate = False

        http_server = HTTPServer(WSGIContainer(app), xheaders=True)
        try:
            http_server.listen(config.RPC_PORT, address=config.RPC_HOST)
            IOLoop.instance().start()        
        except OSError:
            raise Exception("Cannot start the API subsystem. Is {} already running, or is something else listening on port {}?".format(config.XCP_CLIENT, config.RPC_PORT))
Beispiel #4
0
from flask import Flask, url_for, jsonify, request, g, Blueprint, current_app
from flask.ext.sqlalchemy import SQLAlchemy
from flask.ext.httpauth import HTTPBasicAuth
from utils import split_url

basedir = os.path.abspath(os.path.dirname(__file__))
db_path = os.path.join(basedir, '../data.sqlite')

app = Flask(__name__)
api = Blueprint('api', __name__)
app.config['SECRET_KEY'] = 'top-secret!'
app.config['SQLALCHEMY_DATABASE_URI'] = os.environ.get('DATABASE_URL') or \
                                        'sqlite:///' + db_path

db = SQLAlchemy(app)
auth = HTTPBasicAuth()
auth_token = HTTPBasicAuth()


class ValidationError(ValueError):
    pass


@app.errorhandler(ValidationError)
def bad_request(e):
    response = jsonify({
        'status': 400,
        'error': 'bad request',
        'message': e.args[0]
    })
    response.status_code = 400
Beispiel #5
0
from ..models import User
from flask import g, make_response, request
from flask.ext.httpauth import HTTPBasicAuth

http_auth = HTTPBasicAuth()


@http_auth.error_handler
def unauthorized():
    response = make_response()
    response.status_code = 401
    response.headers['WWW-Authenticate'] = 'xBasic realm="{0}"'.format(
        'Authentication Required')
    return response


@http_auth.verify_password
def verify_password(username_or_token, password):
    if password == '':
        g.current_user = User.verify_auth_token(username_or_token)
        g.token_used = True
        return g.current_user != None
    user = User.query.filter_by(name=username_or_token).first()
    if not user:
        return False
    g.current_user = user
    g.token_used = False
    return user.verify_password(password)
from models import Base, User, Bagel
from flask import Flask, jsonify, request, url_for, abort, g
from sqlalchemy.ext.declarative import declarative_base
from sqlalchemy.orm import relationship, sessionmaker
from sqlalchemy import create_engine
from flask.ext.httpauth import HTTPBasicAuth
import pdb
authb = HTTPBasicAuth()

engine = create_engine('sqlite:///bagelShop.db')

Base.metadata.bind = engine
DBSession = sessionmaker(bind=engine)
session = DBSession()
app = Flask(__name__)


#ADD @auth.verify_password here
@authb.verify_password
def verify_password(username, password):
    print("Looking for user {0} with password {1}".format(username, password))
    user = session.query(User).filter_by(username=username).first()

    if not user or not user.verify_password(password):
        return False

    g.user = user
    return True


#ADD a /users route here
Beispiel #7
0
Use the following decorators to apply authentication to any route:

- `@password_auth.login_required` for password auth (only use to GET a token).
- `@token_auth.login_required` for token (for all other authenticated routes).

Copyright 2016 AURA/LSST.
Copyright 2014 Miguel Grinberg.
"""

from functools import wraps
from flask import jsonify, g, current_app
from flask.ext.httpauth import HTTPBasicAuth
from .models import User

# User+Password-based auth (only allowed for getting a token)
password_auth = HTTPBasicAuth()

# Token-based auth (used for all requests)
token_auth = HTTPBasicAuth()


@password_auth.verify_password
def verify_password(username, password):
    g.user = User.query.filter_by(username=username).first()
    if g.user is None:
        return False
    return g.user.verify_password(password)


@password_auth.error_handler
def unauthorized():
Beispiel #8
0
from flask.ext.httpauth import HTTPBasicAuth
from flask import g

from app.models import User
from app.rest import make_response, CODES

from datetime import datetime, timedelta

auth = HTTPBasicAuth()
login = HTTPBasicAuth()
refresh = HTTPBasicAuth()


@login.verify_password
def verify_password(email, password):
    user = User.query.filter_by(email=email).first()
    if not user or not user.verify_password(password):
        return False
    g.user = user
    return True


@auth.verify_password
def verify_token(token, passw=None):
    user = User.verify_auth_token(token)
    if not user:
        return False
    g.user = user
    return True

Beispiel #9
0
from datetime import datetime
import json
from flask import render_template, redirect, url_for, abort, flash, request,\
    current_app, make_response, jsonify
from flask.ext.sqlalchemy import get_debug_queries
from flask.ext.httpauth import HTTPBasicAuth
from . import main
from .forms import TodoForm
from .. import db
from ..models import Todo
from app.exceptions import ValidationError

# will be used for restfull authentication
auth = HTTPBasicAuth()
@main.route('/', methods=['GET'])
@main.route('/todos/', methods=['GET'])
def index():
    ''' index is the home page of the Todo Application '''
    todos = Todo.query.order_by(Todo.publication_date.desc()).all()
    return render_template('index.html', todos=todos)

@main.route('/todos/<int:todo_id>', methods = ['GET' , 'POST'])
def show_or_update(todo_id):
    '''
     as the name indicates, it either shows or updates the todo item.
     :param todo_id: the identifer
    '''
    todo_item = Todo.query.get_or_404(todo_id)
    # if it is GET, so we only need to redirect to the todo page
    if request.method == 'GET':
Beispiel #10
0
from flask import (
    Blueprint,
    g,
)
from flask.ext.httpauth import HTTPBasicAuth

from .models import User
from .errors import unauthorized
from .decorators import no_cache, json

token = Blueprint('token', __name__)
token_auth = HTTPBasicAuth()


@token_auth.verify_password
def verify_password(username_or_token, password):
    g.user = User.query.filter_by(username=username_or_token).first()
    if not g.user:
        return False
    return g.user.verify_password(password)


@token_auth.error_handler
def unauthorized_error():
    return unauthorized('Please authenticate to access this API')


@token.route('/request-token')
@no_cache
@token_auth.login_required
@json
Beispiel #11
0
from flask.ext.httpauth import HTTPBasicAuth

from goalboost.model.auth_models import User
from flask.ext.login import current_user, login_user

httpBasicAuth = HTTPBasicAuth()


@httpBasicAuth.verify_password
def verify_password(username, password):
    global current_user
    user = User.verify_auth_token(password)
    if not user:
        return False
    # The next two lines set the current user correctly for the token case, on a
    # per-request basis,  Tthe user still needs to re-authenticate with each
    # request, so the RESTful statelessness is implemented correctly.
    user.authenticated = True
    login_user(user, remember=True)
    return True
Beispiel #12
0
import Queue
from flask import Flask
from flask.ext import restful
from flask.ext.httpauth import HTTPBasicAuth

flaskapp = Flask(__name__)
flaskapi = restful.Api(flaskapp)
flaskauth = HTTPBasicAuth()

ANSIBLE_QUEUE = Queue.Queue()
Beispiel #13
0
cfg_file = open('server.cfg')
cfg = json.load(cfg_file)
cfg_file.close()

admin_datastore = AdminDatastore()
client_datastore = ClientDatastore()
iterated_client_datastore = IteratedClientDatastore()

from flask import Flask, jsonify, abort, request, make_response, url_for, render_template
from flask.ext.httpauth import HTTPBasicAuth

app = Flask(__name__, static_url_path="")
# Note: We don't need to call run() since our application is embedded within
# the App Engine WSGI application server.
auth = HTTPBasicAuth()
dashauth = HTTPBasicAuth()

#######################################################################################
#######################################################################################
#
# ADMINISTRATOR API
#
#######################################################################################
#######################################################################################

# # Upload a Json file that contains the complete experiment with participants and stimuli
# @app.route('/psycloud/admin/api/experiments/upload_all_data',
# 	methods=['POST'])
# @auth.login_required
# def upload_experiment_data():
Beispiel #14
0
    def _run(self, payment_handler):
        app = flask.Flask(__name__)
        auth = HTTPBasicAuth()

        @dispatcher.add_method
        def is_ready():
            try:
                payment_handler.checkBlockchainService()
                payment_handler.checkPriceInfo()
            except:
                return False
            return True

        @dispatcher.add_method
        def create_order(amount,
                         currency=config.DEFAULT_CURRENCY,
                         item_number=None,
                         order_id=None,
                         gen_new=None,
                         qr_code=False):
            if gen_new is None:
                gen_new = config.GEN_NEW
            ret = payment_handler.createOrder(amount, currency, item_number,
                                              order_id, gen_new)
            if ret.get('error'):
                return ret
            ret.update({
                'qr_image':
                (qr.bitcoinqr(ret['receiving_address']) if qr_code else None)
            })
            return ret

        # @dispatcher.add_method
        # def check_order_status(order_id=None, special_digits=None, timestamp=None, payment_address=None):
        #     return payment_handler.CheckPaymentsFor(order_id=order_id, special_digits=special_digits, payment_address=payment_address, timestamp=timestamp)

        @dispatcher.add_method
        def get_payments(bindings={}):
            return payment_handler.db.getPayments(bindings)

        @dispatcher.add_method
        def poll_payments(bindings={}):
            return payment_handler.pollPayments(bindings)

        @dispatcher.add_method
        def get_orders(bindings={}):
            return payment_handler.db.getOrders(bindings)

        @dispatcher.add_method
        def get_address(bindings={}):
            return payment_handler.db.getAddresses(bindings)

        @dispatcher.add_method
        def get_unfilled_orders(timestamp=None):
            statement = "select * from orders where filled = 0 and created_at > ?"
            return payment_handler.db.rquery(statement, (timestamp or 0, ))

        @dispatcher.add_method
        def get_filled_orders(timestamp=None):
            statement = "select * from orders where filled != 0 and created_at > ?"
            return payment_handler.db.rquery(statement, (timestamp or 0, ))

        @dispatcher.add_method
        def query(statement, bindings=()):
            return payment_handler.db.rquery(statement, bindings)

        @auth.get_password
        def get_pw(username):
            if username == config.RPC_USER:
                return config.RPC_PASSWORD
            return None

        @app.route('/', methods=[
            "POST",
        ])
        @app.route('/api', methods=[
            "POST",
        ])
        def handle_post():
            # Dispatcher is a dictionary {<method_name>: callable}
            try:
                request_json = flask.request.get_data().decode('utf-8')
                request_data = json.loads(request_json)
                assert ('id' in request_data
                        and request_data['jsonrpc'] == "2.0"
                        and request_data['method'])
            except:
                obj_error = jsonrpc.exceptions.JSONRPCInvalidRequest(
                    data="Invalid JSON-RPC 2.0 request format")
                return flask.Response(obj_error.json.encode(),
                                      200,
                                      mimetype='application/json')
            jsonrpc_response = jsonrpc.JSONRPCResponseManager.handle(
                request_json, dispatcher)
            response = flask.Response(jsonrpc_response.json.encode(),
                                      200,
                                      mimetype='application/json')
            return response

        if config.AUTH_REQUIRED:
            auth.login_required(handle_post)
        d = wsgiserver.WSGIPathInfoDispatcher({'/': app.wsgi_app})
        self.server = wsgiserver.CherryPyWSGIServer(
            (config.RPC_HOST, config.RPC_PORT), d)
        logging.info("API Started on %s" %
                     (config.RPC_HOST + ':' + str(config.RPC_PORT)))
        self.server.start()