2020-04-06 11:52:18 +02:00
|
|
|
# Copyright © 2020 Interplanetary Database Association e.V.,
|
|
|
|
# BigchainDB and IPDB software contributors.
|
2018-08-16 12:31:32 +02:00
|
|
|
# SPDX-License-Identifier: (Apache-2.0 AND CC-BY-4.0)
|
|
|
|
# Code is Apache-2.0 and docs are CC-BY-4.0
|
|
|
|
|
2016-03-22 18:42:50 +01:00
|
|
|
"""This module contains basic functions to instantiate the BigchainDB API.
|
|
|
|
|
|
|
|
The application is implemented in Flask and runs using Gunicorn.
|
|
|
|
"""
|
2017-05-12 14:31:58 +02:00
|
|
|
|
2016-03-22 18:42:50 +01:00
|
|
|
import copy
|
|
|
|
import multiprocessing
|
2016-03-01 17:55:37 +01:00
|
|
|
|
2016-02-23 03:37:33 +01:00
|
|
|
from flask import Flask
|
2017-03-20 21:35:47 +01:00
|
|
|
from flask_cors import CORS
|
2016-04-13 16:47:18 +02:00
|
|
|
import gunicorn.app.base
|
2016-02-23 03:37:33 +01:00
|
|
|
|
2016-12-22 17:39:39 +01:00
|
|
|
from bigchaindb import utils
|
Refactor tendermint directory to project root (#2401)
* Problem: core.py contains an unused class, `Bigchain`
Solution: Remove core.py. Refactor BigchainDB Class to remove inheritance from Bigchain.
* Problem: core.py contains an unused class, `Bigchain`
Solution: Remove core.py. Refactor BigchainDB Class to remove inheritance from Bigchain.
* Fixed flake8 complaint about too many blank lines
* Attempting to fix Sphinx docs. This may result in some redundant commits, as I don't know what I'm doing, and I can't experiment without running the CI...
Sorry in advance!
* Attempting to fix Sphinx docs. This may result in some redundant commits, as I don't know what I'm doing, and I can't experiment without running the CI...
Sorry in advance!
* Updating from master changed BigchainDB.process_post_response to a private method, so I had to align with that.
* Fixed a couple stale references to bigchaindb.Bigchain in docstrings
* Missed a reference to `Bigchain` in a patch call...
* Problem: BigchainDB class should be part of project root
Solution: Removed the /tendermint directory and moved its contents to project root
* Problem: Flake8 complained that imports were not at the top of the file
Solution: Had to play around with the order of imports to avoid cyclic dependencies, but its working and style compliant now
* Problem: Stale reference to /tendermint directory in the index
Solution: Removed the references to /tendermint
* Problem: Flake8 complaining of unused import in __init__.py
Solution: The import is there so I can import App directly from bigchaindb, rather than from bigchaindb.core (which I think improves code readability. I added a # noqa to silence Flake8.
* Problem: Stale references to `bigchaindb.tendermint.BigchainDB` in the rst files cause Sphinx to fail
Solution: Updated the autodoc files to use `bigchaindb.BigchainDB` instead
* Problem: Stale reference to the `tendermint` directory in an @patch in a disabled test
Solution: Updated the @patch for completeness
* Problem: BigchainDB class should be part of project root
Solution: Removed the /tendermint directory and moved its contents to project root
* Problem: Flake8 complained that imports were not at the top of the file
Solution: Had to play around with the order of imports to avoid cyclic dependencies, but its working and style compliant now
* Problem: Stale reference to /tendermint directory in the index
Solution: Removed the references to /tendermint
* Problem: Flake8 complaining of unused import in __init__.py
Solution: The import is there so I can import App directly from bigchaindb, rather than from bigchaindb.core (which I think improves code readability. I added a # noqa to silence Flake8.
* Problem: Stale references to `bigchaindb.tendermint.BigchainDB` in the rst files cause Sphinx to fail
Solution: Updated the autodoc files to use `bigchaindb.BigchainDB` instead
* Problem: Stale reference to the `tendermint` directory in an @patch in a disabled test
Solution: Updated the @patch for completeness
2018-07-25 16:59:25 +02:00
|
|
|
from bigchaindb import BigchainDB
|
2017-01-05 13:31:05 +01:00
|
|
|
from bigchaindb.web.routes import add_routes
|
2017-07-04 12:22:28 +02:00
|
|
|
from bigchaindb.web.strip_content_type_middleware import StripContentTypeMiddleware
|
2016-08-19 13:56:08 +02:00
|
|
|
|
2016-03-22 18:42:50 +01:00
|
|
|
|
2016-11-15 11:40:41 +01:00
|
|
|
# TODO: Figure out if we do we need all this boilerplate.
|
2016-03-22 18:42:50 +01:00
|
|
|
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
|
|
|
|
"""
|
|
|
|
|
2017-04-06 15:58:41 +02:00
|
|
|
def __init__(self, app, *, options=None):
|
2017-11-30 15:04:14 +01:00
|
|
|
"""Initialize a new standalone application.
|
2016-03-22 18:42:50 +01:00
|
|
|
|
|
|
|
Args:
|
|
|
|
app: A wsgi Python application.
|
|
|
|
options (dict): the configuration.
|
|
|
|
|
2017-11-30 15:04:14 +01:00
|
|
|
"""
|
2016-03-22 18:42:50 +01:00
|
|
|
self.options = options or {}
|
|
|
|
self.application = app
|
2017-04-06 16:01:42 +02:00
|
|
|
super().__init__()
|
2016-03-22 18:42:50 +01:00
|
|
|
|
|
|
|
def load_config(self):
|
2017-10-23 05:47:58 +02:00
|
|
|
# find a better way to pass this such that
|
|
|
|
# the custom logger class can access it.
|
|
|
|
custom_log_config = self.options.get('custom_log_config')
|
|
|
|
self.cfg.env_orig['custom_log_config'] = custom_log_config
|
|
|
|
|
2016-03-22 18:42:50 +01:00
|
|
|
config = dict((key, value) for key, value in self.options.items()
|
|
|
|
if key in self.cfg.settings and value is not None)
|
|
|
|
|
2018-06-18 14:15:24 +02:00
|
|
|
config['default_proc_name'] = 'bigchaindb_gunicorn'
|
2016-03-22 18:42:50 +01:00
|
|
|
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
|
2016-02-23 03:37:33 +01:00
|
|
|
|
|
|
|
|
2017-11-11 02:26:50 +01:00
|
|
|
def create_app(*, debug=False, threads=1, bigchaindb_factory=None):
|
2016-03-01 17:55:37 +01:00
|
|
|
"""Return an instance of the Flask application.
|
|
|
|
|
|
|
|
Args:
|
2016-03-22 18:42:50 +01:00
|
|
|
debug (bool): a flag to activate the debug mode for the app
|
|
|
|
(default: False).
|
2016-11-15 17:41:35 +01:00
|
|
|
threads (int): number of threads to use
|
|
|
|
Return:
|
|
|
|
an instance of the Flask application.
|
2016-03-01 17:55:37 +01:00
|
|
|
"""
|
|
|
|
|
2017-11-11 02:26:50 +01:00
|
|
|
if not bigchaindb_factory:
|
2018-07-10 17:34:51 +02:00
|
|
|
bigchaindb_factory = BigchainDB
|
2017-11-11 02:26:50 +01:00
|
|
|
|
2016-02-23 03:37:33 +01:00
|
|
|
app = Flask(__name__)
|
2017-07-04 12:22:28 +02:00
|
|
|
app.wsgi_app = StripContentTypeMiddleware(app.wsgi_app)
|
2016-04-15 16:21:14 +02:00
|
|
|
|
2017-05-18 11:40:39 +02:00
|
|
|
CORS(app)
|
2017-03-20 21:35:47 +01:00
|
|
|
|
2016-11-15 17:41:35 +01:00
|
|
|
app.debug = debug
|
2016-04-15 16:21:14 +02:00
|
|
|
|
2017-11-11 02:26:50 +01:00
|
|
|
app.config['bigchain_pool'] = utils.pool(bigchaindb_factory, size=threads)
|
2016-04-15 16:21:14 +02:00
|
|
|
|
2017-01-05 13:31:05 +01:00
|
|
|
add_routes(app)
|
|
|
|
|
2016-02-23 03:37:33 +01:00
|
|
|
return app
|
2016-03-22 18:42:50 +01:00
|
|
|
|
|
|
|
|
2017-11-11 02:26:50 +01:00
|
|
|
def create_server(settings, log_config=None, bigchaindb_factory=None):
|
2016-03-22 18:42:50 +01:00
|
|
|
"""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
|
|
|
|
|
2016-04-07 14:15:29 +02:00
|
|
|
if not settings.get('threads'):
|
2017-05-19 14:05:28 +02:00
|
|
|
# Note: Threading is not recommended currently, as the frontend workload
|
|
|
|
# is largely CPU bound and parallisation across Python threads makes it
|
|
|
|
# slower.
|
|
|
|
settings['threads'] = 1
|
2016-04-07 14:15:29 +02:00
|
|
|
|
2017-10-23 05:47:58 +02:00
|
|
|
settings['custom_log_config'] = log_config
|
2016-11-15 17:41:35 +01:00
|
|
|
app = create_app(debug=settings.get('debug', False),
|
2017-11-11 02:26:50 +01:00
|
|
|
threads=settings['threads'],
|
|
|
|
bigchaindb_factory=bigchaindb_factory)
|
2017-04-06 15:58:41 +02:00
|
|
|
standalone = StandaloneApplication(app, options=settings)
|
2016-03-22 18:42:50 +01:00
|
|
|
return standalone
|