def create_app_sphinx(): """Creates application for generating the documentation using Sphinx. Read the Docs builder doesn't have a database or any other custom software that we use, so we have to ignore these initialization steps. Only blueprints/views are needed to build documentation. """ app = CustomFlask(import_name=__name__, use_flask_uuid=True) _register_blueprints(app) return app
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration files app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'default_config.py' )) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'consul_config.py' ), silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'custom_config.py' ), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug # Error handling from critiquebrainz.ws.errors import init_error_handlers init_error_handlers(app) app.init_loggers( file_config=app.config.get("LOG_FILE"), email_config=app.config.get("LOG_EMAIL"), sentry_config=app.config.get("LOG_SENTRY"), ) # Database from critiquebrainz.db import init_db_engine init_db_engine(app.config.get("SQLALCHEMY_DATABASE_URI")) # Redis (cache) from brainzutils import cache if "REDIS_HOST" in app.config and \ "REDIS_PORT" in app.config and \ "REDIS_NAMESPACE" in app.config: cache.init( host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"], namespace=app.config["REDIS_NAMESPACE"], ) else: logging.warning("Redis is not defined in config file. Skipping initialization.") # OAuth from critiquebrainz.ws.oauth import oauth oauth.init_app(app) app.config["JSONIFY_PRETTYPRINT_REGULAR"] = False _register_blueprints(app) return app
def create_app(config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration files app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), "..", "default_config.py")) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'consul_config.py'), silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) app.init_loggers( file_config=app.config.get("LOG_FILE"), sentry_config=app.config.get("LOG_SENTRY"), ) # Blueprints from mbspotify.views import main_bp app.register_blueprint(main_bp) return app
def create_app(debug=None): """ Uses brainzutils (https://github.com/metabrainz/brainzutils-python) to log exceptions to sentry. """ # create flask application app = CustomFlask(import_name=__name__) # load config config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), 'config.py') # config must exist to link the file with our flask app. if os.path.exists(config_file): app.config.from_pyfile(config_file) else: raise FileNotFoundError(errno.ENOENT, os.strerror(errno.ENOENT), config_file) if debug is not None: app.debug = debug # attach app logs to sentry. app.init_loggers(sentry_config=app.config.get('LOG_SENTRY')) return app
def create_app_with_configuration(config_path=None): """Create a Flask application and load all configuration files""" app = CustomFlask(import_name=__name__, use_flask_uuid=True, use_debug_toolbar=True) # Configuration root_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..") app.config.from_pyfile(os.path.join(root_path, 'default_config.py')) app.config.from_pyfile(os.path.join(root_path, 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) return app
def create_app_rtfd(): """Creates application for generating the documentation. Read the Docs builder doesn't have any of our databases or special packages (like MessyBrainz), so we have to ignore these initialization steps. Only blueprints/views are needed to render documentation. """ app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'rtd_config.py')) _register_blueprints(app) return app
def create_app_sphinx(): app = CustomFlask(__name__) _register_blueprints(app) return app
def create_app(debug=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration load_config(app) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Logging app.init_loggers(file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY') ) # Database connection from db import init_db_engine init_db_engine(app.config['SQLALCHEMY_DATABASE_URI']) # Cache if 'REDIS_HOST' in app.config and\ 'REDIS_PORT' in app.config and\ 'REDIS_NAMESPACE' in app.config and\ 'REDIS_NS_VERSIONS_LOCATION' in app.config: if not os.path.exists(app.config['REDIS_NS_VERSIONS_LOCATION']): os.makedirs(app.config['REDIS_NS_VERSIONS_LOCATION']) from brainzutils import cache cache.init( host=app.config['REDIS_HOST'], port=app.config['REDIS_PORT'], namespace=app.config['REDIS_NAMESPACE'], ns_versions_loc=app.config['REDIS_NS_VERSIONS_LOCATION']) else: raise Exception('One or more redis cache configuration options are missing from config.py') # Extensions from flask_uuid import FlaskUUID FlaskUUID(app) # MusicBrainz import musicbrainzngs from db import SCHEMA_VERSION musicbrainzngs.set_useragent(app.config['MUSICBRAINZ_USERAGENT'], SCHEMA_VERSION) if app.config['MUSICBRAINZ_HOSTNAME']: musicbrainzngs.set_hostname(app.config['MUSICBRAINZ_HOSTNAME']) # OAuth from webserver.login import login_manager, provider login_manager.init_app(app) provider.init(app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Error handling from webserver.errors import init_error_handlers init_error_handlers(app) # Static files import static_manager static_manager.read_manifest() # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from webserver import utils app.jinja_env.filters['date'] = utils.reformat_date app.jinja_env.filters['datetime'] = utils.reformat_datetime app.context_processor(lambda: dict(get_static_path=static_manager.get_static_path)) _register_blueprints(app) # Admin section from flask_admin import Admin from webserver.admin import views as admin_views admin = Admin(app, index_view=admin_views.HomeView(name='Admin')) admin.add_view(admin_views.AdminsView(name='Admins')) @ app.before_request def before_request_gdpr_check(): # skip certain pages, static content and the API if request.path == url_for('index.gdpr_notice') \ or request.path == url_for('login.logout') \ or request.path.startswith('/_debug') \ or request.path.startswith('/static') \ or request.path.startswith(API_PREFIX): return # otherwise if user is logged in and hasn't agreed to gdpr, # redirect them to agree to terms page. elif current_user.is_authenticated and current_user.gdpr_agreed is None: return redirect(url_for('index.gdpr_notice', next=request.full_path)) return app
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration files app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'default_config.py' )) config_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'consul_config.py' ) if deploy_env: print("Checking if consul template generated config file exists: {}".format(config_file)) for _ in range(CONSUL_CONFIG_FILE_RETRY_COUNT): if not os.path.exists(config_file): sleep(1) if not os.path.exists(config_file): print("No configuration file generated yet. Retried {} times, exiting.".format(CONSUL_CONFIG_FILE_RETRY_COUNT)) sys.exit(-1) print("Loading consul config file {}".format(config_file)) app.config.from_pyfile(config_file, silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'custom_config.py' ), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Error handling from critiquebrainz.frontend.error_handlers import init_error_handlers init_error_handlers(app) # Static files from critiquebrainz.frontend import static_manager static_manager.read_manifest() app.init_loggers( file_config=app.config.get("LOG_FILE"), email_config=app.config.get("LOG_EMAIL"), sentry_config=app.config.get("LOG_SENTRY"), ) # Database from critiquebrainz.db import init_db_engine init_db_engine(app.config.get("SQLALCHEMY_DATABASE_URI")) add_robots(app) # MusicBrainz Database from critiquebrainz.frontend.external import musicbrainz_db musicbrainz_db.init_db_engine(app.config.get('MB_DATABASE_URI')) # Redis (cache) from brainzutils import cache if "REDIS_HOST" in app.config and \ "REDIS_PORT" in app.config and \ "REDIS_NAMESPACE" in app.config: cache.init( host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"], namespace=app.config["REDIS_NAMESPACE"], ) else: logging.warning("Redis is not defined in config file. Skipping initialization.") from critiquebrainz.frontend import babel babel.init_app(app) from critiquebrainz.frontend import login login.login_manager.init_app(app) from critiquebrainz.frontend.login.provider import MusicBrainzAuthentication login.mb_auth = MusicBrainzAuthentication( name='musicbrainz', client_id=app.config['MUSICBRAINZ_CLIENT_ID'], client_secret=app.config['MUSICBRAINZ_CLIENT_SECRET'], authorize_url="https://musicbrainz.org/oauth2/authorize", access_token_url="https://musicbrainz.org/oauth2/token", base_url="https://musicbrainz.org/", ) # APIs from critiquebrainz.frontend.external import mbspotify mbspotify.init(app.config['MBSPOTIFY_BASE_URI'], app.config['MBSPOTIFY_ACCESS_KEY']) from critiquebrainz.frontend.external import musicbrainz musicbrainz.init( app_name=app.config['MUSICBRAINZ_USERAGENT'] or "CritiqueBrainz Custom", app_version="1.0", hostname=app.config['MUSICBRAINZ_HOSTNAME'] or "musicbrainz.org", ) # Template utilities # TODO (code-master5): disabled no-member warnings just as a workaround to deal with failing tests till the # issue [https://github.com/PyCQA/pylint/issues/2563] with pylint is resolved app.jinja_env.add_extension('jinja2.ext.do') from critiquebrainz.utils import reformat_date, reformat_datetime, track_length, parameterize from critiquebrainz.frontend.external.musicbrainz_db.entities import get_entity_by_id app.jinja_env.filters['date'] = reformat_date app.jinja_env.filters['datetime'] = reformat_datetime app.jinja_env.filters['track_length'] = track_length app.jinja_env.filters['parameterize'] = parameterize app.jinja_env.filters['entity_details'] = get_entity_by_id from flask_babel import Locale, get_locale app.jinja_env.filters['language_name'] = lambda language_code: Locale(language_code).get_language_name(get_locale()) app.context_processor(lambda: dict(get_static_path=static_manager.get_static_path)) # Blueprints from critiquebrainz.frontend.views.index import frontend_bp from critiquebrainz.frontend.views.review import review_bp from critiquebrainz.frontend.views.search import search_bp from critiquebrainz.frontend.views.artist import artist_bp from critiquebrainz.frontend.views.release_group import release_group_bp from critiquebrainz.frontend.views.release import release_bp from critiquebrainz.frontend.views.event import event_bp from critiquebrainz.frontend.views.mapping import mapping_bp from critiquebrainz.frontend.views.user import user_bp from critiquebrainz.frontend.views.profile import profile_bp from critiquebrainz.frontend.views.place import place_bp from critiquebrainz.frontend.views.profile_apps import profile_apps_bp from critiquebrainz.frontend.views.login import login_bp from critiquebrainz.frontend.views.oauth import oauth_bp from critiquebrainz.frontend.views.reports import reports_bp from critiquebrainz.frontend.views.moderators import moderators_bp from critiquebrainz.frontend.views.log import log_bp from critiquebrainz.frontend.views.comment import comment_bp from critiquebrainz.frontend.views.rate import rate_bp app.register_blueprint(frontend_bp) app.register_blueprint(review_bp, url_prefix='/review') app.register_blueprint(search_bp, url_prefix='/search') app.register_blueprint(artist_bp, url_prefix='/artist') app.register_blueprint(release_group_bp, url_prefix='/release-group') app.register_blueprint(release_bp, url_prefix='/release') app.register_blueprint(event_bp, url_prefix='/event') app.register_blueprint(place_bp, url_prefix='/place') app.register_blueprint(mapping_bp, url_prefix='/mapping') app.register_blueprint(user_bp, url_prefix='/user') app.register_blueprint(profile_bp, url_prefix='/profile') app.register_blueprint(profile_apps_bp, url_prefix='/profile/applications') app.register_blueprint(login_bp, url_prefix='/login') app.register_blueprint(oauth_bp, url_prefix='/oauth') app.register_blueprint(reports_bp, url_prefix='/reports') app.register_blueprint(log_bp, url_prefix='/log') app.register_blueprint(moderators_bp, url_prefix='/moderators') app.register_blueprint(comment_bp, url_prefix='/comments') app.register_blueprint(rate_bp, url_prefix='/rate') return app
def gen_app(config_path=None, debug=None): """ Generate a Flask app for LB with all configurations done and connections established. In the Flask app returned, blueprints are not registered. """ app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) print("Starting metabrainz service with %s environment." % deploy_env) # Load configuration files: If we're running under a docker deployment, wait until config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'config.py') if deploy_env: print("Checking if consul template generated config file exists: %s" % config_file) for i in range(CONSUL_CONFIG_FILE_RETRY_COUNT): if not os.path.exists(config_file): sleep(1) if not os.path.exists(config_file): print( "No configuration file generated yet. Retried %d times, exiting." % CONSUL_CONFIG_FILE_RETRY_COUNT) sys.exit(-1) print("loading consul config file %s)" % config_file) app.config.from_pyfile(config_file) else: app.config.from_pyfile(config_file) if debug is not None: app.debug = debug # initialize Flask-DebugToolbar if the debug option is True if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Output config values and some other info print('Configuration values are as follows: ') print(pprint.pformat(app.config, indent=4)) try: with open('.git-version') as git_version_file: print('Running on git commit: %s', git_version_file.read().strip()) except IOError as e: print('Unable to retrieve git commit. Error: %s', str(e)) # Logging app.init_loggers(file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY')) # Redis connection create_redis(app) # Influx connection create_influx(app) # RabbitMQ connection create_rabbitmq(app) # Database connection from listenbrainz import db db.init_db_connection(app.config['SQLALCHEMY_DATABASE_URI']) from listenbrainz.webserver.external import messybrainz messybrainz.init_db_connection( app.config['MESSYBRAINZ_SQLALCHEMY_DATABASE_URI']) # OAuth from listenbrainz.webserver.login import login_manager, provider login_manager.init_app(app) provider.init(app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Error handling from listenbrainz.webserver.errors import init_error_handlers init_error_handlers(app) from listenbrainz.webserver import rate_limiter @app.after_request def after_request_callbacks(response): return rate_limiter.inject_x_rate_headers(response) # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from listenbrainz.webserver import utils app.jinja_env.filters['date'] = utils.reformat_date app.jinja_env.filters['datetime'] = utils.reformat_datetime return app
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration files app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'default_config.py')) config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'consul_config.py') if deploy_env: print("Checking if consul template generated config file exists: {}". format(config_file)) for _ in range(CONSUL_CONFIG_FILE_RETRY_COUNT): if not os.path.exists(config_file): sleep(1) if not os.path.exists(config_file): print( "No configuration file generated yet. Retried {} times, exiting." .format(CONSUL_CONFIG_FILE_RETRY_COUNT)) sys.exit(-1) print("Loading consul config file {}".format(config_file)) app.config.from_pyfile(config_file, silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Error handling from critiquebrainz.frontend.error_handlers import init_error_handlers init_error_handlers(app) # Static files from critiquebrainz.frontend import static_manager static_manager.read_manifest() app.init_loggers( file_config=app.config.get("LOG_FILE"), email_config=app.config.get("LOG_EMAIL"), sentry_config=app.config.get("LOG_SENTRY"), ) # CritiqueBrainz Database from critiquebrainz import db as critiquebrainz_db critiquebrainz_db.init_db_engine(app.config.get("SQLALCHEMY_DATABASE_URI")) add_robots(app) # MusicBrainz Database from brainzutils import musicbrainz_db musicbrainz_db.init_db_engine(app.config.get("MB_DATABASE_URI")) # Redis (cache) from brainzutils import cache if "REDIS_HOST" in app.config and \ "REDIS_PORT" in app.config and \ "REDIS_NAMESPACE" in app.config: cache.init( host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"], namespace=app.config["REDIS_NAMESPACE"], ) else: logging.warning( "Redis is not defined in config file. Skipping initialization.") from critiquebrainz.frontend import babel babel.init_app(app) from critiquebrainz.frontend import login login.login_manager.init_app(app) from critiquebrainz.frontend.login.provider import MusicBrainzAuthentication login.mb_auth = MusicBrainzAuthentication( name='musicbrainz', client_id=app.config['MUSICBRAINZ_CLIENT_ID'], client_secret=app.config['MUSICBRAINZ_CLIENT_SECRET'], authorize_url="https://musicbrainz.org/oauth2/authorize", access_token_url="https://musicbrainz.org/oauth2/token", base_url="https://musicbrainz.org/", ) # APIs from critiquebrainz.frontend.external import mbspotify mbspotify.init(app.config['MBSPOTIFY_BASE_URI'], app.config['MBSPOTIFY_ACCESS_KEY']) from critiquebrainz.frontend.external import musicbrainz musicbrainz.init( app_name=app.config['MUSICBRAINZ_USERAGENT'] or "CritiqueBrainz Custom", app_version="1.0", hostname=app.config['MUSICBRAINZ_HOSTNAME'] or "musicbrainz.org", ) # Template utilities # TODO (code-master5): disabled no-member warnings just as a workaround to deal with failing tests till the # issue [https://github.com/PyCQA/pylint/issues/2563] with pylint is resolved app.jinja_env.add_extension('jinja2.ext.do') from critiquebrainz.utils import reformat_date, reformat_datetime, track_length, track_length_ms, parameterize from critiquebrainz.frontend.external.musicbrainz_db.entities import get_entity_by_id from critiquebrainz.frontend.forms.utils import get_language_name app.jinja_env.filters['date'] = reformat_date app.jinja_env.filters['datetime'] = reformat_datetime app.jinja_env.filters['track_length'] = track_length app.jinja_env.filters['track_length_ms'] = track_length_ms app.jinja_env.filters['parameterize'] = parameterize app.jinja_env.filters['entity_details'] = get_entity_by_id app.jinja_env.filters['language_name'] = get_language_name app.context_processor( lambda: dict(get_static_path=static_manager.get_static_path)) # Blueprints from critiquebrainz.frontend.views.index import frontend_bp from critiquebrainz.frontend.views.review import review_bp from critiquebrainz.frontend.views.search import search_bp from critiquebrainz.frontend.views.artist import artist_bp from critiquebrainz.frontend.views.label import label_bp from critiquebrainz.frontend.views.release_group import release_group_bp from critiquebrainz.frontend.views.release import release_bp from critiquebrainz.frontend.views.work import work_bp from critiquebrainz.frontend.views.event import event_bp from critiquebrainz.frontend.views.mapping import mapping_bp from critiquebrainz.frontend.views.user import user_bp from critiquebrainz.frontend.views.profile import profile_bp from critiquebrainz.frontend.views.place import place_bp from critiquebrainz.frontend.views.profile_apps import profile_apps_bp from critiquebrainz.frontend.views.login import login_bp from critiquebrainz.frontend.views.oauth import oauth_bp from critiquebrainz.frontend.views.reports import reports_bp from critiquebrainz.frontend.views.moderators import moderators_bp from critiquebrainz.frontend.views.log import log_bp from critiquebrainz.frontend.views.comment import comment_bp from critiquebrainz.frontend.views.rate import rate_bp from critiquebrainz.frontend.views.statistics import statistics_bp app.register_blueprint(frontend_bp) app.register_blueprint(review_bp, url_prefix='/review') app.register_blueprint(search_bp, url_prefix='/search') app.register_blueprint(artist_bp, url_prefix='/artist') app.register_blueprint(label_bp, url_prefix='/label') app.register_blueprint(release_group_bp, url_prefix='/release-group') app.register_blueprint(release_bp, url_prefix='/release') app.register_blueprint(work_bp, url_prefix='/work') app.register_blueprint(event_bp, url_prefix='/event') app.register_blueprint(place_bp, url_prefix='/place') app.register_blueprint(mapping_bp, url_prefix='/mapping') app.register_blueprint(user_bp, url_prefix='/user') app.register_blueprint(profile_bp, url_prefix='/profile') app.register_blueprint(profile_apps_bp, url_prefix='/profile/applications') app.register_blueprint(login_bp, url_prefix='/login') app.register_blueprint(oauth_bp, url_prefix='/oauth') app.register_blueprint(reports_bp, url_prefix='/reports') app.register_blueprint(log_bp, url_prefix='/log') app.register_blueprint(moderators_bp, url_prefix='/moderators') app.register_blueprint(comment_bp, url_prefix='/comments') app.register_blueprint(rate_bp, url_prefix='/rate') app.register_blueprint(statistics_bp, url_prefix='/statistics') return app
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'default_config.py')) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Redis (cache) from brainzutils import cache try: cache.init( host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"], namespace=app.config["REDIS_NAMESPACE"], ) except KeyError as e: logging.error( "Redis is not defined in config file. Error: {}".format(e)) raise # Logging app.init_loggers(file_config=app.config.get('LOG_FILE'), sentry_config=app.config.get('LOG_SENTRY')) # Extensions from flask_uuid import FlaskUUID FlaskUUID(app) # Error handling from messybrainz.webserver.errors import init_error_handlers init_error_handlers(app) # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from messybrainz.webserver import utils app.jinja_env.filters['date'] = utils.reformat_date app.jinja_env.filters['datetime'] = utils.reformat_datetime # Blueprints from messybrainz.webserver.views.index import index_bp from messybrainz.webserver.views.api import api_bp app.register_blueprint(index_bp) app.register_blueprint(api_bp) db.init_db_engine(app.config['SQLALCHEMY_DATABASE_URI']) return app
def create_app(debug=None): """ Generate a Flask app for LB with all configurations done and connections established. In the Flask app returned, blueprints are not registered. """ app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) load_config(app) if debug is not None: app.debug = debug # As early as possible, if debug is True, set the log level of our 'listenbrainz' logger to DEBUG # to prevent flask from creating a new log handler if app.debug: logger = logging.getLogger('listenbrainz') logger.setLevel(logging.DEBUG) # initialize Flask-DebugToolbar if the debug option is True if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() sentry_config = app.config.get('LOG_SENTRY') if sentry_config: sentry.init_sentry(**sentry_config) # Initialize BU cache and metrics cache.init(host=app.config['REDIS_HOST'], port=app.config['REDIS_PORT'], namespace=app.config['REDIS_NAMESPACE']) metrics.init("listenbrainz") # Database connections from listenbrainz import db from listenbrainz.db import timescale as ts from listenbrainz import messybrainz as msb db.init_db_connection(app.config['SQLALCHEMY_DATABASE_URI']) ts.init_db_connection(app.config['SQLALCHEMY_TIMESCALE_URI']) msb.init_db_connection(app.config['MESSYBRAINZ_SQLALCHEMY_DATABASE_URI']) # Redis connection from listenbrainz.webserver.redis_connection import init_redis_connection init_redis_connection(app.logger) # Timescale connection from listenbrainz.webserver.timescale_connection import init_timescale_connection init_timescale_connection(app) # RabbitMQ connection from listenbrainz.webserver.rabbitmq_connection import init_rabbitmq_connection try: init_rabbitmq_connection(app) except ConnectionError: app.logger.critical("RabbitMQ service is not up!", exc_info=True) if app.config['MB_DATABASE_URI']: from brainzutils import musicbrainz_db musicbrainz_db.init_db_engine(app.config['MB_DATABASE_URI']) # OAuth from listenbrainz.webserver.login import login_manager, provider login_manager.init_app(app) provider.init(app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Error handling from listenbrainz.webserver.errors import init_error_handlers init_error_handlers(app) from brainzutils.ratelimit import inject_x_rate_headers, set_user_validation_function set_user_validation_function(check_ratelimit_token_whitelist) @app.after_request def after_request_callbacks(response): return inject_x_rate_headers(response) # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from listenbrainz.webserver import utils app.jinja_env.filters['date'] = utils.reformat_date app.jinja_env.filters['datetime'] = utils.reformat_datetime return app
def create_app(config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, use_debug_toolbar=True, ) # Configuration files app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'default_config.py' )) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'consul_config.py' ), silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'custom_config.py' ), silent=True) if config_path: app.config.from_pyfile(config_path) app.init_loggers( file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY'), ) # Database from metabrainz import db db.init_db_engine(app.config["SQLALCHEMY_DATABASE_URI"]) from metabrainz import model model.db.init_app(app) # Redis (cache) from brainzutils import cache cache.init(**app.config['REDIS']) # MusicBrainz OAuth from metabrainz.users import login_manager, musicbrainz_login login_manager.init_app(app) musicbrainz_login.init( app.config['MUSICBRAINZ_BASE_URL'], app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET'] ) # Templates from metabrainz.utils import reformat_datetime app.jinja_env.filters['datetime'] = reformat_datetime app.jinja_env.filters['nl2br'] = lambda val: val.replace('\n', '<br />') if val else '' # Error handling from metabrainz.errors import init_error_handlers init_error_handlers(app) add_robots(app) # Blueprints _register_blueprints(app) # ADMIN SECTION from flask_admin import Admin from metabrainz.admin.views import HomeView admin = Admin(app, index_view=HomeView(name='Pending users')) # Models from metabrainz.model.user import UserAdminView from metabrainz.model.payment import PaymentAdminView from metabrainz.model.tier import TierAdminView admin.add_view(UserAdminView(model.db.session, category='Users', endpoint="user_model")) admin.add_view(PaymentAdminView(model.db.session, endpoint="donation_model")) admin.add_view(TierAdminView(model.db.session, endpoint="tier_model")) # Custom stuff from metabrainz.admin.views import CommercialUsersView from metabrainz.admin.views import UsersView from metabrainz.admin.views import TokensView from metabrainz.admin.views import StatsView admin.add_view(CommercialUsersView(name='Commercial users', category='Users')) admin.add_view(UsersView(name='Search', category='Users')) admin.add_view(TokensView(name='Access tokens', category='Users')) admin.add_view(StatsView(name='Statistics')) return app
def create_app(debug=None, config_path=None): app = CustomFlask(import_name=__name__, use_flask_uuid=True, use_debug_toolbar=True) # Configuration root_path = os.path.join(os.path.dirname(os.path.realpath(__file__)), "..") app.config.from_pyfile(os.path.join(root_path, 'default_config.py')) app.config.from_pyfile(os.path.join(root_path, 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug # Logging from webserver.loggers import init_loggers init_loggers(app) # Database connection from db import init_db_engine init_db_engine(app.config['SQLALCHEMY_DATABASE_URI']) # Memcached if 'MEMCACHED_SERVERS' in app.config: from db import cache cache.init(app.config['MEMCACHED_SERVERS'], app.config['MEMCACHED_NAMESPACE'], debug=1 if app.debug else 0) # Extensions from flask_uuid import FlaskUUID FlaskUUID(app) # MusicBrainz import musicbrainzngs from db import SCHEMA_VERSION musicbrainzngs.set_useragent(app.config['MUSICBRAINZ_USERAGENT'], SCHEMA_VERSION) if app.config['MUSICBRAINZ_HOSTNAME']: musicbrainzngs.set_hostname(app.config['MUSICBRAINZ_HOSTNAME']) # OAuth from webserver.login import login_manager, provider login_manager.init_app(app) provider.init(app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Error handling from webserver.errors import init_error_handlers init_error_handlers(app) # Static files import static_manager static_manager.read_manifest() # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from webserver import utils app.jinja_env.filters['date'] = utils.reformat_date app.jinja_env.filters['datetime'] = utils.reformat_datetime app.context_processor( lambda: dict(get_static_path=static_manager.get_static_path)) _register_blueprints(app) # Admin section from flask_admin import Admin from webserver.admin import views as admin_views admin = Admin(app, index_view=admin_views.HomeView(name='Admin')) admin.add_view(admin_views.AdminsView(name='Admins')) return app
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration files app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'default_config.py' )) config_file = os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'consul_config.py' ) if deploy_env: print("Checking if consul template generated config file exists: {}".format(config_file)) for _ in range(CONSUL_CONFIG_FILE_RETRY_COUNT): if not os.path.exists(config_file): sleep(1) if not os.path.exists(config_file): print("No configuration file generated yet. Retried {} times, exiting.".format(CONSUL_CONFIG_FILE_RETRY_COUNT)) sys.exit(-1) print("Loading consul config file {}".format(config_file)) app.config.from_pyfile(config_file, silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'custom_config.py' ), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug # Error handling from critiquebrainz.ws.errors import init_error_handlers init_error_handlers(app) app.init_loggers( file_config=app.config.get("LOG_FILE"), email_config=app.config.get("LOG_EMAIL"), sentry_config=app.config.get("LOG_SENTRY"), ) # Database from critiquebrainz.db import init_db_engine init_db_engine(app.config.get("SQLALCHEMY_DATABASE_URI")) # Redis (cache) from brainzutils import cache if "REDIS_HOST" in app.config and \ "REDIS_PORT" in app.config and \ "REDIS_NAMESPACE" in app.config: cache.init( host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"], namespace=app.config["REDIS_NAMESPACE"], ) else: logging.warning("Redis is not defined in config file. Skipping initialization.") # OAuth from critiquebrainz.ws.oauth import oauth oauth.init_app(app) app.config["JSONIFY_PRETTYPRINT_REGULAR"] = False _register_blueprints(app) return app
def gen_app(config_path=None, debug=None): """ Generate a Flask app for LB with all configurations done and connections established. In the Flask app returned, blueprints are not registered. """ app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) load_config(app) if debug is not None: app.debug = debug # initialize Flask-DebugToolbar if the debug option is True if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Logging app.init_loggers(file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY')) # Redis connection create_redis(app) # Influx connection create_influx(app) # RabbitMQ connection try: create_rabbitmq(app) except ConnectionError: app.logger.critical("RabbitMQ service is not up!", exc_info=True) # Database connection from listenbrainz import db db.init_db_connection(app.config['SQLALCHEMY_DATABASE_URI']) from listenbrainz.webserver.external import messybrainz messybrainz.init_db_connection( app.config['MESSYBRAINZ_SQLALCHEMY_DATABASE_URI']) if app.config['MB_DATABASE_URI']: from brainzutils import musicbrainz_db musicbrainz_db.init_db_engine(app.config['MB_DATABASE_URI']) # OAuth from listenbrainz.webserver.login import login_manager, provider login_manager.init_app(app) provider.init(app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Error handling from listenbrainz.webserver.errors import init_error_handlers init_error_handlers(app) from listenbrainz.webserver import rate_limiter @app.after_request def after_request_callbacks(response): return rate_limiter.inject_x_rate_headers(response) # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from listenbrainz.webserver import utils app.jinja_env.filters['date'] = utils.reformat_date app.jinja_env.filters['datetime'] = utils.reformat_datetime return app
def create_app(config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, use_debug_toolbar=True, ) # Configuration files app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'default_config.py')) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'consul_config.py'), silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) app.init_loggers( file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY'), ) # Database from metabrainz import db db.init_db_engine(app.config["SQLALCHEMY_DATABASE_URI"]) from metabrainz import model model.db.init_app(app) # Redis (cache) from brainzutils import cache cache.init(**app.config['REDIS']) # MusicBrainz OAuth from metabrainz.users import login_manager, musicbrainz_login login_manager.init_app(app) musicbrainz_login.init(app.config['MUSICBRAINZ_BASE_URL'], app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Templates from metabrainz.utils import reformat_datetime app.jinja_env.filters['datetime'] = reformat_datetime app.jinja_env.filters['nl2br'] = lambda val: val.replace('\n', '<br />' ) if val else '' # Error handling from metabrainz.errors import init_error_handlers init_error_handlers(app) add_robots(app) from metabrainz import babel babel.init_app(app) from flask_uploads import configure_uploads from metabrainz.admin.forms import LOGO_UPLOAD_SET configure_uploads(app, upload_sets=[ LOGO_UPLOAD_SET, ]) # Blueprints _register_blueprints(app) # ADMIN SECTION from flask_admin import Admin from metabrainz.admin.views import HomeView admin = Admin(app, index_view=HomeView(name='Pending users'), template_mode='bootstrap3') # Models from metabrainz.model.user import UserAdminView from metabrainz.model.payment import PaymentAdminView from metabrainz.model.tier import TierAdminView admin.add_view( UserAdminView(model.db.session, category='Users', endpoint="user_model")) admin.add_view( PaymentAdminView(model.db.session, category='Payments', endpoint="payment_model")) admin.add_view(TierAdminView(model.db.session, endpoint="tier_model")) # Custom stuff from metabrainz.admin.views import CommercialUsersView from metabrainz.admin.views import UsersView from metabrainz.admin.views import PaymentsView from metabrainz.admin.views import TokensView from metabrainz.admin.views import StatsView admin.add_view( CommercialUsersView(name='Commercial users', category='Users')) admin.add_view(UsersView(name='Search', category='Users')) admin.add_view(PaymentsView(name='All', category='Payments')) admin.add_view(TokensView(name='Access tokens', category='Users')) admin.add_view(StatsView(name='Statistics')) return app
import eventlet eventlet.monkey_patch() from flask import Flask, current_app, request from flask_socketio import SocketIO, join_room, leave_room, emit, rooms from werkzeug.exceptions import BadRequest import argparse import json from listenbrainz.webserver import load_config from brainzutils.flask import CustomFlask from listenbrainz.follow_server.dispatcher import FollowDispatcher app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) load_config(app) # Error handling from listenbrainz.webserver.errors import init_error_handlers init_error_handlers(app) # Logging app.init_loggers(file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY')) socketio = SocketIO(app, cors_allowed_origins='*') @socketio.on('json')
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration files app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'default_config.py')) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'consul_config.py'), silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Error handling from critiquebrainz.frontend.error_handlers import init_error_handlers init_error_handlers(app) # Static files from critiquebrainz.frontend import static_manager static_manager.read_manifest() app.init_loggers( file_config=app.config.get("LOG_FILE"), email_config=app.config.get("LOG_EMAIL"), sentry_config=app.config.get("LOG_SENTRY"), ) # Database from critiquebrainz.db import init_db_engine init_db_engine(app.config.get("SQLALCHEMY_DATABASE_URI")) add_robots(app) # MusicBrainz Database from critiquebrainz.frontend.external import musicbrainz_db musicbrainz_db.init_db_engine(app.config.get('MB_DATABASE_URI')) # Redis (cache) from brainzutils import cache if "REDIS_HOST" in app.config and \ "REDIS_PORT" in app.config and \ "REDIS_NAMESPACE" in app.config: cache.init( host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"], namespace=app.config["REDIS_NAMESPACE"], ) else: logging.warning( "Redis is not defined in config file. Skipping initialization.") from critiquebrainz.frontend import babel babel.init_app(app) from critiquebrainz.frontend import login login.login_manager.init_app(app) from critiquebrainz.frontend.login.provider import MusicBrainzAuthentication login.mb_auth = MusicBrainzAuthentication( name='musicbrainz', client_id=app.config['MUSICBRAINZ_CLIENT_ID'], client_secret=app.config['MUSICBRAINZ_CLIENT_SECRET'], authorize_url="https://musicbrainz.org/oauth2/authorize", access_token_url="https://musicbrainz.org/oauth2/token", base_url="https://musicbrainz.org/", ) # APIs from critiquebrainz.frontend.external import mbspotify mbspotify.init(app.config['MBSPOTIFY_BASE_URI'], app.config['MBSPOTIFY_ACCESS_KEY']) from critiquebrainz.frontend.external import musicbrainz musicbrainz.init( app_name=app.config['MUSICBRAINZ_USERAGENT'] or "CritiqueBrainz Custom", app_version="1.0", hostname=app.config['MUSICBRAINZ_HOSTNAME'] or "musicbrainz.org", ) # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from critiquebrainz.utils import reformat_date, reformat_datetime, track_length, parameterize from critiquebrainz.frontend.external.musicbrainz_db.entities import get_entity_by_id app.jinja_env.filters['date'] = reformat_date app.jinja_env.filters['datetime'] = reformat_datetime app.jinja_env.filters['track_length'] = track_length app.jinja_env.filters['parameterize'] = parameterize app.jinja_env.filters['entity_details'] = get_entity_by_id from flask_babel import Locale, get_locale app.jinja_env.filters['language_name'] = lambda language_code: Locale( language_code).get_language_name(get_locale()) app.context_processor( lambda: dict(get_static_path=static_manager.get_static_path)) # Blueprints from critiquebrainz.frontend.views.index import frontend_bp from critiquebrainz.frontend.views.review import review_bp from critiquebrainz.frontend.views.search import search_bp from critiquebrainz.frontend.views.artist import artist_bp from critiquebrainz.frontend.views.release_group import release_group_bp from critiquebrainz.frontend.views.release import release_bp from critiquebrainz.frontend.views.event import event_bp from critiquebrainz.frontend.views.mapping import mapping_bp from critiquebrainz.frontend.views.user import user_bp from critiquebrainz.frontend.views.profile import profile_bp from critiquebrainz.frontend.views.place import place_bp from critiquebrainz.frontend.views.profile_apps import profile_apps_bp from critiquebrainz.frontend.views.login import login_bp from critiquebrainz.frontend.views.oauth import oauth_bp from critiquebrainz.frontend.views.reports import reports_bp from critiquebrainz.frontend.views.moderators import moderators_bp from critiquebrainz.frontend.views.log import log_bp app.register_blueprint(frontend_bp) app.register_blueprint(review_bp, url_prefix='/review') app.register_blueprint(search_bp, url_prefix='/search') app.register_blueprint(artist_bp, url_prefix='/artist') app.register_blueprint(release_group_bp, url_prefix='/release-group') app.register_blueprint(release_bp, url_prefix='/release') app.register_blueprint(event_bp, url_prefix='/event') app.register_blueprint(place_bp, url_prefix='/place') app.register_blueprint(mapping_bp, url_prefix='/mapping') app.register_blueprint(user_bp, url_prefix='/user') app.register_blueprint(profile_bp, url_prefix='/profile') app.register_blueprint(profile_apps_bp, url_prefix='/profile/applications') app.register_blueprint(login_bp, url_prefix='/login') app.register_blueprint(oauth_bp, url_prefix='/oauth') app.register_blueprint(reports_bp, url_prefix='/reports') app.register_blueprint(log_bp, url_prefix='/log') app.register_blueprint(moderators_bp, url_prefix='/moderators') return app
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) print("Starting metabrainz service with %s environment." % deploy_env) # Now load other bits of configuration print("loading %s" % os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'default_config.py')) app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', 'default_config.py')) print("loading %s" % os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'custom_config.py')) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'custom_config.py'), silent=True) if config_path: print("loading custom %s" % config_path) app.config.from_pyfile(config_path) # Load configuration files: If we're running under a docker deployment, wait until # the consul configuration is available. if deploy_env: consul_config = os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'consul_config.py') print("loading consul %s" % consul_config) for i in range(CONSUL_CONFIG_FILE_RETRY_COUNT): if not os.path.exists(consul_config): sleep(1) if not os.path.exists(consul_config): print( "No configuration file generated yet. Retried %d times, exiting." % CONSUL_CONFIG_FILE_RETRY_COUNT) sys.exit(-1) app.config.from_pyfile(consul_config, silent=True) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Printing out some debug values such as config and git commit try: with open(".git-version") as f: git_version = f.read() print('Running on git commit %s' % git_version.strip()) except IOError: print( "Unable to retrieve git commit. Use docker/push.sh to push images for production." ) print('Configuration values are as follows: ') print(pprint.pformat(app.config, indent=4)) app.init_loggers( file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY'), ) # Database from metabrainz import db db.init_db_engine(app.config["SQLALCHEMY_DATABASE_URI"]) from metabrainz import model model.db.init_app(app) # Redis (cache) from brainzutils import cache cache.init(**app.config['REDIS']) # MusicBrainz OAuth from metabrainz.users import login_manager, musicbrainz_login login_manager.init_app(app) musicbrainz_login.init(app.config['MUSICBRAINZ_BASE_URL'], app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Templates from metabrainz.utils import reformat_datetime app.jinja_env.filters['datetime'] = reformat_datetime app.jinja_env.filters['nl2br'] = lambda val: val.replace('\n', '<br />' ) if val else '' # Error handling from metabrainz.errors import init_error_handlers init_error_handlers(app) add_robots(app) from metabrainz import babel babel.init_app(app) from flask_uploads import configure_uploads from metabrainz.admin.forms import LOGO_UPLOAD_SET configure_uploads(app, upload_sets=[ LOGO_UPLOAD_SET, ]) # Blueprints _register_blueprints(app) # ADMIN SECTION from flask_admin import Admin from metabrainz.admin.views import HomeView admin = Admin(app, index_view=HomeView(name='Pending users'), template_mode='bootstrap3') # Models from metabrainz.model.user import UserAdminView from metabrainz.model.payment import PaymentAdminView from metabrainz.model.tier import TierAdminView admin.add_view( UserAdminView(model.db.session, category='Users', endpoint="user_model")) admin.add_view( PaymentAdminView(model.db.session, category='Payments', endpoint="payment_model")) admin.add_view(TierAdminView(model.db.session, endpoint="tier_model")) # Custom stuff from metabrainz.admin.views import CommercialUsersView from metabrainz.admin.views import UsersView from metabrainz.admin.views import PaymentsView from metabrainz.admin.views import TokensView from metabrainz.admin.views import StatsView admin.add_view( CommercialUsersView(name='Commercial users', category='Users')) admin.add_view(UsersView(name='Search', category='Users')) admin.add_view(PaymentsView(name='All', category='Payments')) admin.add_view(TokensView(name='Access tokens', category='Users')) admin.add_view(StatsView(name='Statistics')) return app
def create_app(debug=None, config_path=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration files app.config.from_pyfile( os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'default_config.py')) config_file = os.path.join(os.path.dirname(os.path.realpath(__file__)), '..', '..', 'consul_config.py') if deploy_env: print("Checking if consul template generated config file exists: {}". format(config_file)) for _ in range(CONSUL_CONFIG_FILE_RETRY_COUNT): if not os.path.exists(config_file): sleep(1) if not os.path.exists(config_file): print( "No configuration file generated yet. Retried {} times, exiting." .format(CONSUL_CONFIG_FILE_RETRY_COUNT)) sys.exit(-1) print("Loading consul config file {}".format(config_file)) app.config.from_pyfile(config_file, silent=True) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', '..', 'custom_config.py'), silent=True) if config_path: app.config.from_pyfile(config_path) if debug is not None: app.debug = debug # Error handling from critiquebrainz.ws.errors import init_error_handlers init_error_handlers(app) app.init_loggers( file_config=app.config.get("LOG_FILE"), email_config=app.config.get("LOG_EMAIL"), sentry_config=app.config.get("LOG_SENTRY"), ) # CritiqueBrainz Database from critiquebrainz import db as critiquebrainz_db critiquebrainz_db.init_db_engine(app.config.get("SQLALCHEMY_DATABASE_URI")) # MusicBrainz Database from brainzutils import musicbrainz_db musicbrainz_db.init_db_engine(app.config.get("MB_DATABASE_URI")) # Redis (cache) from brainzutils import cache if "REDIS_HOST" in app.config and \ "REDIS_PORT" in app.config and \ "REDIS_NAMESPACE" in app.config: cache.init( host=app.config["REDIS_HOST"], port=app.config["REDIS_PORT"], namespace=app.config["REDIS_NAMESPACE"], ) else: logging.warning( "Redis is not defined in config file. Skipping initialization.") # OAuth from critiquebrainz.ws.oauth import oauth oauth.init_app(app) app.config["JSONIFY_PRETTYPRINT_REGULAR"] = False _register_blueprints(app) return app
def create_app(debug=None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # Configuration load_config(app) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Logging app.init_loggers(file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY') ) # Database connection from db import init_db_engine init_db_engine(app.config['SQLALCHEMY_DATABASE_URI']) # Cache if 'REDIS_HOST' in app.config and\ 'REDIS_PORT' in app.config and\ 'REDIS_NAMESPACE' in app.config and\ 'REDIS_NS_VERSIONS_LOCATION' in app.config: if not os.path.exists(app.config['REDIS_NS_VERSIONS_LOCATION']): os.makedirs(app.config['REDIS_NS_VERSIONS_LOCATION']) from brainzutils import cache cache.init( host=app.config['REDIS_HOST'], port=app.config['REDIS_PORT'], namespace=app.config['REDIS_NAMESPACE'], ns_versions_loc=app.config['REDIS_NS_VERSIONS_LOCATION']) else: raise Exception('One or more redis cache configuration options are missing from config.py') # Add rate limiting support @app.after_request def after_request_callbacks(response): return inject_x_rate_headers(response) # check for ratelimit config values and set them if present if 'RATELIMIT_PER_IP' in app.config and 'RATELIMIT_WINDOW' in app.config: set_rate_limits(app.config['RATELIMIT_PER_IP'], app.config['RATELIMIT_PER_IP'], app.config['RATELIMIT_WINDOW']) # MusicBrainz import musicbrainzngs from db import SCHEMA_VERSION musicbrainzngs.set_useragent(app.config['MUSICBRAINZ_USERAGENT'], SCHEMA_VERSION) if app.config['MUSICBRAINZ_HOSTNAME']: musicbrainzngs.set_hostname(app.config['MUSICBRAINZ_HOSTNAME']) # OAuth from webserver.login import login_manager, provider login_manager.init_app(app) provider.init(app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET']) # Error handling from webserver.errors import init_error_handlers init_error_handlers(app) # Static files import static_manager # Template utilities app.jinja_env.add_extension('jinja2.ext.do') from webserver import utils app.jinja_env.filters['date'] = utils.reformat_date app.jinja_env.filters['datetime'] = utils.reformat_datetime # During development, built js and css assets don't have a hash, but in production we use # a manifest to map a name to name.hash.extension for caching/cache busting if app.debug: app.context_processor(lambda: dict(get_static_path=static_manager.development_get_static_path)) else: static_manager.read_manifest() app.context_processor(lambda: dict(get_static_path=static_manager.manifest_get_static_path)) _register_blueprints(app) # Admin section from flask_admin import Admin from webserver.admin import views as admin_views admin = Admin(app, index_view=admin_views.HomeView(name='Admin')) admin.add_view(admin_views.AdminsView(name='Admins')) @app.before_request def prod_https_login_redirect(): """ Redirect to HTTPS in production except for the API endpoints """ if urlparse.urlsplit(request.url).scheme == 'http' \ and app.config['DEBUG'] == False \ and app.config['TESTING'] == False \ and request.blueprint not in ('api', 'api_v1_core', 'api_v1_datasets', 'api_v1_dataset_eval'): url = request.url[7:] # remove http:// from url return redirect('https://{}'.format(url), 301) @app.before_request def before_request_gdpr_check(): # skip certain pages, static content and the API if request.path == url_for('index.gdpr_notice') \ or request.path == url_for('login.logout') \ or request.path.startswith('/_debug') \ or request.path.startswith('/static') \ or request.path.startswith(API_PREFIX): return # otherwise if user is logged in and hasn't agreed to gdpr, # redirect them to agree to terms page. elif current_user.is_authenticated and current_user.gdpr_agreed is None: return redirect(url_for('index.gdpr_notice', next=request.full_path)) return app
def create_app(debug=None, config_path = None): app = CustomFlask( import_name=__name__, use_flask_uuid=True, ) # get rid of some really pesky warning. Remove this in April 2020, when it shouldn't be needed anymore. app.config['SQLALCHEMY_TRACK_MODIFICATIONS'] = True print("Starting metabrainz service with %s environment." % deploy_env); # This is used to run tests, but not for dev or deployment if config_path: print("loading %s" % config_path) app.config.from_pyfile(config_path) else: print("loading %s" % os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'config.py')) app.config.from_pyfile(os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'config.py' )) # Load configuration files: If we're running under a docker deployment, wait until # the consul configuration is available. if deploy_env: consul_config = os.path.join( os.path.dirname(os.path.realpath(__file__)), '..', 'consul_config.py') print("loading consul %s" % consul_config) for i in range(CONSUL_CONFIG_FILE_RETRY_COUNT): if not os.path.exists(consul_config): sleep(1) if not os.path.exists(consul_config): print("No configuration file generated yet. Retried %d times, exiting." % CONSUL_CONFIG_FILE_RETRY_COUNT); sys.exit(-1) app.config.from_pyfile(consul_config, silent=True) if debug is not None: app.debug = debug if app.debug and app.config['SECRET_KEY']: app.init_debug_toolbar() # Printing out some debug values such as config and git commit try: with open(".git-version") as f: git_version = f.read() print('Running on git commit %s' % git_version.strip()) except IOError: print("Unable to retrieve git commit. Use docker/push.sh to push images for production.") print('Configuration values are as follows: ') print(pprint.pformat(app.config, indent=4)) app.init_loggers( file_config=app.config.get('LOG_FILE'), email_config=app.config.get('LOG_EMAIL'), sentry_config=app.config.get('LOG_SENTRY'), ) # Database from metabrainz import db db.init_db_engine(app.config["SQLALCHEMY_DATABASE_URI"]) from metabrainz import model model.db.init_app(app) # Redis (cache) from brainzutils import cache cache.init(**app.config['REDIS']) # MusicBrainz OAuth from metabrainz.users import login_manager, musicbrainz_login login_manager.init_app(app) musicbrainz_login.init( app.config['MUSICBRAINZ_BASE_URL'], app.config['MUSICBRAINZ_CLIENT_ID'], app.config['MUSICBRAINZ_CLIENT_SECRET'] ) # Templates from metabrainz.utils import reformat_datetime app.jinja_env.filters['datetime'] = reformat_datetime app.jinja_env.filters['nl2br'] = lambda val: val.replace('\n', '<br />') if val else '' # Error handling from metabrainz.errors import init_error_handlers init_error_handlers(app) add_robots(app) from metabrainz import babel babel.init_app(app) from flask_uploads import configure_uploads from metabrainz.admin.forms import LOGO_UPLOAD_SET configure_uploads(app, upload_sets=[ LOGO_UPLOAD_SET, ]) # Blueprints _register_blueprints(app) # ADMIN SECTION from flask_admin import Admin from metabrainz.admin.views import HomeView admin = Admin(app, index_view=HomeView(name='Pending users'), template_mode='bootstrap3') # Models from metabrainz.model.user import UserAdminView from metabrainz.model.payment import PaymentAdminView from metabrainz.model.tier import TierAdminView admin.add_view(UserAdminView(model.db.session, category='Users', endpoint="user_model")) admin.add_view(PaymentAdminView(model.db.session, category='Payments', endpoint="payment_model")) admin.add_view(TierAdminView(model.db.session, endpoint="tier_model")) # Custom stuff from metabrainz.admin.views import CommercialUsersView from metabrainz.admin.views import UsersView from metabrainz.admin.views import PaymentsView from metabrainz.admin.views import TokensView from metabrainz.admin.views import StatsView admin.add_view(CommercialUsersView(name='Commercial users', category='Users')) admin.add_view(UsersView(name='Search', category='Users')) admin.add_view(PaymentsView(name='All', category='Payments')) admin.add_view(TokensView(name='Access tokens', category='Users')) admin.add_view(StatsView(name='Statistics', category='Statistics')) admin.add_view(StatsView(name='Top IPs', endpoint="statsview/top-ips", category='Statistics')) admin.add_view(StatsView(name='Top Tokens', endpoint="statsview/top-tokens", category='Statistics')) return app