content: # Copyright Contributors to the Amundsen project.
  # SPDX-License-Identifier: Apache-2.0
  
  import ast
  import importlib
  import logging
  import logging.config
  import os
  import sys
  
  from flask import Blueprint, Flask
  from flask_restful import Api
  from typing import Optional
  
  from amundsen_application.api import init_routes
  from amundsen_application.api.announcements.v0 import announcements_blueprint
  from amundsen_application.api.issue.issue import IssueAPI, IssuesAPI
  from amundsen_application.api.log.v0 import log_blueprint
  from amundsen_application.api.mail.v0 import mail_blueprint
  from amundsen_application.api.metadata.v0 import metadata_blueprint
  from amundsen_application.api.preview.dashboard.v0 import \
      dashboard_preview_blueprint
  from amundsen_application.api.preview.v0 import preview_blueprint
  from amundsen_application.api.quality.v0 import quality_blueprint
  from amundsen_application.api.search.v1 import search_blueprint
  from amundsen_application.api.notice.v0 import notices_blueprint
  from amundsen_application.api.v0 import blueprint
  from amundsen_application.deprecations import process_deprecations
  
  # For customized flask use below arguments to override.
  
  FLASK_APP_MODULE_NAME = os.getenv('FLASK_APP_MODULE_NAME') or os.getenv('APP_WRAPPER')
  FLASK_APP_CLASS_NAME = os.getenv('FLASK_APP_CLASS_NAME') or os.getenv('APP_WRAPPER_CLASS')
  FLASK_APP_KWARGS_DICT_STR = os.getenv('FLASK_APP_KWARGS_DICT') or os.getenv('APP_WRAPPER_ARGS')
  
  """ Support for importing a subclass of flask.Flask, via env variables """
  if FLASK_APP_MODULE_NAME and FLASK_APP_CLASS_NAME:
      print('Using requested Flask module {module_name} and class {class_name}'
            .format(module_name=FLASK_APP_MODULE_NAME, class_name=FLASK_APP_CLASS_NAME), file=sys.stderr)
      moduleName = FLASK_APP_MODULE_NAME
      module = importlib.import_module(moduleName)
      moduleClass = FLASK_APP_CLASS_NAME
      app_wrapper_class = getattr(module, moduleClass)  # type: ignore
  else:
      app_wrapper_class = Flask
  
  PROJECT_ROOT = os.path.dirname(os.path.abspath(__file__))
  STATIC_ROOT = os.getenv('STATIC_ROOT', 'static')
  static_dir = os.path.join(PROJECT_ROOT, STATIC_ROOT)
  
  
  def create_app(config_module_class: Optional[str] = None, template_folder: Optional[str] = None) -> Flask:
      """ Support for importing arguments for a subclass of flask.Flask """
      args = ast.literal_eval(FLASK_APP_KWARGS_DICT_STR) if FLASK_APP_KWARGS_DICT_STR else {}
  
      tmpl_dir = template_folder if template_folder else os.path.join(PROJECT_ROOT, static_dir, 'dist/templates')
      app = app_wrapper_class(__name__, static_folder=static_dir, template_folder=tmpl_dir, **args)
  
      # Support for importing a custom config class
      if not config_module_class:
          config_module_class = os.getenv('FRONTEND_SVC_CONFIG_MODULE_CLASS')
  
      app.config.from_object(config_module_class)
  
      if app.config.get('LOG_CONFIG_FILE'):
          logging.config.fileConfig(app.config['LOG_CONFIG_FILE'], disable_existing_loggers=False)
      else:
          logging.basicConfig(format=app.config['LOG_FORMAT'], datefmt=app.config.get('LOG_DATE_FORMAT'))
          logging.getLogger().setLevel(app.config['LOG_LEVEL'])
  
      logging.info('Created app with config name {}'.format(config_module_class))
      logging.info('Using metadata service at {}'.format(app.config.get('METADATASERVICE_BASE')))
      logging.info('Using search service at {}'.format(app.config.get('SEARCHSERVICE_BASE')))
  
      api_bp = Blueprint('api', __name__)
      api = Api(api_bp)
  
      api.add_resource(IssuesAPI,
                       '/api/issue/issues', endpoint='issues')
      api.add_resource(IssueAPI,
                       '/api/issue/issue', endpoint='issue')
  
      app.register_blueprint(blueprint)
      app.register_blueprint(announcements_blueprint)
      app.register_blueprint(log_blueprint)
      app.register_blueprint(mail_blueprint)
      app.register_blueprint(metadata_blueprint)
      app.register_blueprint(preview_blueprint)
      app.register_blueprint(quality_blueprint)
      app.register_blueprint(search_blueprint)
      app.register_blueprint(notices_blueprint)
      app.register_blueprint(api_bp)
      app.register_blueprint(dashboard_preview_blueprint)
      init_routes(app)
  
      init_custom_routes = app.config.get('INIT_CUSTOM_ROUTES')
      if init_custom_routes:
          init_custom_routes(app)
  
      # handles the deprecation warnings
      # and process any config/environment variables accordingly
      process_deprecations(app)
  
      return app
  