An ebook/comic library service and web client
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

107 lines
2.9 KiB

  1. """Atheneum Flask Application."""
  2. import os
  3. from logging.config import dictConfig
  4. from flask import Flask
  5. from flask_migrate import Migrate
  6. from atheneum.db import db
  7. from atheneum.errors import BaseError, handle_atheneum_base_error, \
  8. handle_atheneum_404_error
  9. from atheneum.utility import json_utility, session_utility
  10. dictConfig({
  11. 'version': 1,
  12. 'formatters': {'default': {
  13. 'format': '[%(asctime)s] %(levelname)s in %(module)s: %(message)s',
  14. }},
  15. 'handlers': {'wsgi': {
  16. 'class': 'logging.StreamHandler',
  17. 'stream': 'ext://flask.logging.wsgi_errors_stream',
  18. 'formatter': 'default'
  19. }},
  20. 'root': {
  21. 'level': 'INFO',
  22. 'handlers': ['wsgi']
  23. }
  24. })
  25. def create_app(test_config: dict = None) -> Flask:
  26. """
  27. Create an instance of Atheneum.
  28. :param test_config:
  29. :return:
  30. """
  31. app = Flask(__name__, instance_relative_config=True)
  32. app.logger.debug('Creating Atheneum Server')
  33. data_directory = os.getenv('ATHENEUM_DATA_DIRECTORY', '/tmp')
  34. app.logger.debug('Atheneum Data Directory: %s', data_directory)
  35. default_database_uri = 'sqlite:///{}/atheneum.db'.format(data_directory)
  36. app.config.from_mapping(
  37. SECRET_KEY='dev',
  38. SQLALCHEMY_DATABASE_URI=default_database_uri,
  39. SQLALCHEMY_TRACK_MODIFICATIONS=False,
  40. TRAP_HTTP_EXCEPTIONS=True,
  41. )
  42. if test_config is None:
  43. app.logger.debug('Loading configurations')
  44. app.config.from_object('atheneum.default_settings')
  45. app.config.from_pyfile('config.py', silent=True)
  46. if os.getenv('ATHENEUM_SETTINGS', None):
  47. app.config.from_envvar('ATHENEUM_SETTINGS')
  48. else:
  49. app.logger.debug('Loading test configuration')
  50. app.config.from_mapping(test_config)
  51. try:
  52. os.makedirs(app.instance_path)
  53. except OSError:
  54. pass
  55. app.json_encoder = json_utility.CustomJSONEncoder
  56. app.session_interface = session_utility.DisableSessionInterface()
  57. app.logger.debug('Initializing Application')
  58. db.init_app(app)
  59. app.logger.debug('Registering Database Models')
  60. Migrate(app, db)
  61. return app
  62. def register_blueprints(app: Flask) -> None:
  63. """
  64. Register blueprints for the application.
  65. :param app:
  66. :return:
  67. """
  68. from atheneum.api import AUTH_BLUEPRINT, USER_BLUEPRINT
  69. app.register_blueprint(AUTH_BLUEPRINT)
  70. app.register_blueprint(USER_BLUEPRINT)
  71. def register_error_handlers(app: Flask) -> None:
  72. """
  73. Register error handlers for the application.
  74. :param app:
  75. :return:
  76. """
  77. app.register_error_handler(404, handle_atheneum_404_error)
  78. app.register_error_handler(BaseError, handle_atheneum_base_error)
  79. atheneum = create_app() # pylint: disable=C0103
  80. register_blueprints(atheneum)
  81. register_error_handlers(atheneum)
  82. logger = atheneum.logger # pylint: disable=C0103
  83. if __name__ == "__main__":
  84. atheneum.run()