1
0
mirror of https://github.com/bigchaindb/bigchaindb.git synced 2024-06-30 05:32:01 +02:00

Merge branch 'feat/116/more-solid-webserver' into develop

This commit is contained in:
vrde 2016-04-07 11:04:49 +02:00
commit aebe179840
No known key found for this signature in database
GPG Key ID: 6581C7C39B3D397D
6 changed files with 103 additions and 7 deletions

View File

@ -2,7 +2,6 @@ import os
import copy
def e(key, default=None, conv=None):
'''Get the environment variable `key`, fallback to `default`
if nothing is found.
@ -24,6 +23,9 @@ def e(key, default=None, conv=None):
config = {
'server': {
'bind': e('BIGCHAIN_SERVER_BIND', default='0.0.0.0:5000'),
},
'database': {
'host': e('BIGCHAIN_DATABASE_HOST', default='localhost'),
'port': e('BIGCHAIN_DATABASE_PORT', default=28015),
@ -49,3 +51,4 @@ config = {
# for more info.
_config = copy.deepcopy(config)
from bigchaindb.core import Bigchain # noqa

View File

@ -55,6 +55,10 @@ def run_configure(args, skip_if_exists=False):
conf['keypair']['private'], conf['keypair']['public'] = crypto.generate_key_pair()
if not args.yes:
for key in ('host', 'port'):
val = conf['server'][key]
conf['server'][key] = input('API Server {}? (default `{}`): '.format(key, val)) or val
for key in ('host', 'port', 'name'):
val = conf['database'][key]
conf['database'][key] = input('Database {}? (default `{}`): '.format(key, val)) or val

View File

@ -3,6 +3,7 @@ import multiprocessing as mp
import rethinkdb as r
import bigchaindb
from bigchaindb import Bigchain
from bigchaindb.voter import Voter
from bigchaindb.block import Block
@ -11,6 +12,18 @@ from bigchaindb.web import server
logger = logging.getLogger(__name__)
BANNER = """
****************************************************************************
* *
* Initialization complete. BigchainDB is ready and waiting for events. *
* You can send events through the API documented at: *
* - http://docs.bigchaindb.apiary.io/ *
* *
* Listening to client connections on: {:<15} *
* *
****************************************************************************
"""
class Processes(object):
@ -68,8 +81,8 @@ class Processes(object):
block = Block(self.q_new_transaction)
# start the web api
webapi = server.create_app()
p_webapi = mp.Process(name='webapi', target=webapi.run, kwargs={'host': 'localhost'})
app_server = server.create_server(bigchaindb.config['server'])
p_webapi = mp.Process(name='webapi', target=app_server.run)
p_webapi.start()
# initialize the processes
@ -92,5 +105,4 @@ class Processes(object):
# start message
block.initialized.wait()
p_voter.initialized.wait()
logger.info('Initialization complete. BigchainDB ready and waiting for events.')
logger.info('You can send events through the API documented at http://docs.bigchaindb.apiary.io/')
logger.info(BANNER.format(bigchaindb.config['server']['bind']))

View File

@ -1,16 +1,56 @@
"""This module contains basic functions to instantiate the BigchainDB API. """
"""This module contains basic functions to instantiate the BigchainDB API.
The application is implemented in Flask and runs using Gunicorn.
"""
import copy
import multiprocessing
from flask import Flask
from bigchaindb import Bigchain
from bigchaindb.web import views
import gunicorn.app.base
class StandaloneApplication(gunicorn.app.base.BaseApplication):
"""Run a **wsgi** app wrapping it in a Gunicorn Base Application.
Adapted from:
- http://docs.gunicorn.org/en/latest/custom.html
"""
def __init__(self, app, options=None):
'''Initialize a new standalone application.
Args:
app: A wsgi Python application.
options (dict): the configuration.
'''
self.options = options or {}
self.application = app
super(StandaloneApplication, self).__init__()
def load_config(self):
config = dict((key, value) for key, value in self.options.items()
if key in self.cfg.settings and value is not None)
for key, value in config.items():
# not sure if we need the `key.lower` here, will just keep
# keep it for now.
self.cfg.set(key.lower(), value)
def load(self):
return self.application
def create_app(debug=False):
"""Return an instance of the Flask application.
Args:
debug (bool): a flag to activate the debug mode for the app (default: False).
debug (bool): a flag to activate the debug mode for the app
(default: False).
"""
app = Flask(__name__)
@ -18,3 +58,26 @@ def create_app(debug=False):
app.config['bigchain'] = Bigchain()
app.register_blueprint(views.basic_views, url_prefix='/api/v1')
return app
def create_server(settings):
"""Wrap and return an application ready to be run.
Args:
settings (dict): a dictionary containing the settings, more info
here http://docs.gunicorn.org/en/latest/settings.html
Return:
an initialized instance of the application.
"""
settings = copy.deepcopy(settings)
if not settings.get('workers'):
settings['workers'] = (multiprocessing.cpu_count() * 2) + 1
debug = settings.pop('debug', False)
app = create_app(debug)
standalone = StandaloneApplication(app, settings)
return standalone

View File

@ -79,6 +79,7 @@ setup(
'bitcoin==1.1.42',
'flask==0.10.1',
'requests==2.9',
'gunicorn~=19.0',
],
setup_requires=['pytest-runner'],
tests_require=tests_require,

13
tests/web/test_server.py Normal file
View File

@ -0,0 +1,13 @@
import copy
def test_settings(monkeypatch):
import bigchaindb
from bigchaindb.web import server
s = server.create_server(bigchaindb.config['server'])
# for whatever reason the value is wrapped in a list
# needs further investigation
assert s.cfg.bind[0] == bigchaindb.config['server']['bind']