Changeset View
Changeset View
Standalone View
Standalone View
swh/storage/api/server.py
# Copyright (C) 2015-2017 The Software Heritage developers | # Copyright (C) 2015-2019 The Software Heritage developers | ||||
# See the AUTHORS file at the top-level directory of this distribution | # See the AUTHORS file at the top-level directory of this distribution | ||||
# License: GNU General Public License version 3, or any later version | # License: GNU General Public License version 3, or any later version | ||||
# See top-level LICENSE file for more information | # See top-level LICENSE file for more information | ||||
import os | |||||
import json | import json | ||||
import logging | import logging | ||||
import click | |||||
from flask import request | from flask import request | ||||
from swh.core import config | from swh.core import config | ||||
from swh.storage import get_storage as get_swhstorage | from swh.storage import get_storage as get_swhstorage | ||||
from swh.core.api import (SWHServerAPIApp, decode_request, | from swh.core.api import (SWHServerAPIApp, decode_request, | ||||
error_handler, | error_handler, | ||||
encode_data_server as encode_data) | encode_data_server as encode_data) | ||||
DEFAULT_CONFIG_PATH = 'storage/storage' | |||||
DEFAULT_CONFIG = { | |||||
'storage': ('dict', { | |||||
'cls': 'local', | |||||
'args': { | |||||
'db': 'dbname=softwareheritage-dev', | |||||
'objstorage': { | |||||
'cls': 'pathslicing', | |||||
'args': { | |||||
'root': '/srv/softwareheritage/objects', | |||||
'slicing': '0:2/2:4/4:6', | |||||
}, | |||||
}, | |||||
}, | |||||
}) | |||||
} | |||||
app = SWHServerAPIApp(__name__) | app = SWHServerAPIApp(__name__) | ||||
storage = None | storage = None | ||||
@app.errorhandler(Exception) | @app.errorhandler(Exception) | ||||
def my_error_handler(exception): | def my_error_handler(exception): | ||||
return error_handler(exception, encode_data) | return error_handler(exception, encode_data) | ||||
▲ Show 20 Lines • Show All 337 Lines • ▼ Show 20 Lines | |||||
@app.route('/algos/diff_revision', methods=['POST']) | @app.route('/algos/diff_revision', methods=['POST']) | ||||
def diff_revision(): | def diff_revision(): | ||||
return encode_data(get_storage().diff_revision(**decode_request(request))) | return encode_data(get_storage().diff_revision(**decode_request(request))) | ||||
api_cfg = None | api_cfg = None | ||||
def run_from_webserver(environ, start_response, | def load_and_check_config(config_file, type='local'): | ||||
config_path=DEFAULT_CONFIG_PATH): | """Check the minimal configuration is set to run the api or raise an | ||||
"""Run the WSGI app from the webserver, loading the configuration.""" | error explanation. | ||||
Args: | |||||
config_file (str): Path to the configuration file to load | |||||
type (str): configuration type. For 'local' type, more | |||||
checks are done. | |||||
Raises: | |||||
Error if the setup is not as expected | |||||
Returns: | |||||
configuration as a dict | |||||
""" | |||||
if not config_file: | |||||
raise EnvironmentError('Configuration file must be defined') | |||||
if not os.path.exists(config_file): | |||||
vlorentz: You could use `FileNotFoundError`. | |||||
raise EnvironmentError('Configuration file %s does not exist' % ( | |||||
config_file, )) | |||||
cfg = config.read(config_file) | |||||
if 'storage' not in cfg: | |||||
Not Done Inline ActionsKeyError vlorentz: `KeyError` | |||||
raise EnvironmentError("Missing '%storage' configuration") | |||||
if type == 'local': | |||||
vcfg = cfg['storage'] | |||||
cls = vcfg.get('cls') | |||||
if cls != 'local': | |||||
raise EnvironmentError( | |||||
"The storage backend can only be started with a 'local' " | |||||
"configuration") | |||||
args = vcfg['args'] | |||||
for key in ('db', 'objstorage'): | |||||
if not args.get(key): | |||||
raise EnvironmentError( | |||||
Not Done Inline ActionsValueError vlorentz: `ValueError` | |||||
"Invalid configuration; missing '%s' config entry" % key) | |||||
return cfg | |||||
def make_app_from_configfile(): | |||||
"""Run the WSGI app from the webserver, loading the configuration from | |||||
a configuration file. | |||||
SWH_CONFIG_FILENAME environment variable defines the | |||||
configuration path to load. | |||||
""" | |||||
global api_cfg | global api_cfg | ||||
if not api_cfg: | if not api_cfg: | ||||
api_cfg = config.load_named_config(config_path, DEFAULT_CONFIG) | config_file = os.environ.get('SWH_CONFIG_FILENAME') | ||||
api_cfg = load_and_check_config(config_file) | |||||
app.config.update(api_cfg) | app.config.update(api_cfg) | ||||
handler = logging.StreamHandler() | handler = logging.StreamHandler() | ||||
app.logger.addHandler(handler) | app.logger.addHandler(handler) | ||||
return app(environ, start_response) | return app | ||||
@click.command() | |||||
@click.argument('config-path', required=1) | |||||
@click.option('--host', default='0.0.0.0', help="Host to run the server") | |||||
@click.option('--port', default=5002, type=click.INT, | |||||
help="Binding port of the server") | |||||
@click.option('--debug/--nodebug', default=True, | |||||
help="Indicates if the server should run in debug mode") | |||||
def launch(config_path, host, port, debug): | |||||
app.config.update(config.read(config_path, DEFAULT_CONFIG)) | |||||
app.run(host, port=int(port), debug=bool(debug)) | |||||
if __name__ == '__main__': | if __name__ == '__main__': | ||||
launch() | print('Deprecated. Use swh-storage') |
You could use FileNotFoundError.