app.py 4.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125
  1. # This file is part of DarkFi (https://dark.fi)
  2. #
  3. # Copyright (C) 2020-2025 Dyne.org foundation
  4. #
  5. # This program is free software: you can redistribute it and/or modify
  6. # it under the terms of the GNU Affero General Public License as
  7. # published by the Free Software Foundation, either version 3 of the
  8. # License, or (at your option) any later version.
  9. #
  10. # This program is distributed in the hope that it will be useful,
  11. # but WITHOUT ANY WARRANTY; without even the implied warranty of
  12. # MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
  13. # GNU Affero General Public License for more details.
  14. #
  15. # You should have received a copy of the GNU Affero General Public License
  16. # along with this program. If not, see <https://www.gnu.org/licenses/>.
  17. """
  18. Module: app.py
  19. This module initializes the DarkFi explorer Flask application by registering various blueprints for handling routes
  20. related to blocks, contracts, transactions, search, and the explore section, including the home page. It also defines
  21. error handlers, ensuring appropriate responses for these common HTTP errors.
  22. """
  23. import os
  24. import tomli
  25. from flask import Flask, render_template
  26. from blueprints.explore import explore_bp
  27. from blueprints.block import block_bp
  28. from blueprints.contract import contract_bp
  29. from blueprints.transaction import transaction_bp
  30. def create_app():
  31. """
  32. Creates and configures the DarkFi explorer Flask application.
  33. This function creates and initializes the explorer the Flask app,
  34. registering applicable blueprints for handling explorer-related routes,
  35. and defining error handling for common HTTP errors. It returns a fully
  36. configured Flask application instance.
  37. """
  38. app = Flask(__name__)
  39. # Load the app TOML configuration
  40. env = os.getenv("FLASK_ENV", "localnet")
  41. load_toml_config(app, env)
  42. # Register Blueprints
  43. app.register_blueprint(explore_bp)
  44. app.register_blueprint(block_bp)
  45. app.register_blueprint(contract_bp)
  46. app.register_blueprint(transaction_bp)
  47. # Define page not found error handler
  48. @app.errorhandler(404)
  49. def page_not_found(e):
  50. """
  51. Handles 404 errors by rendering a custom 404 error page when a requested page is not found,
  52. returning a rendered template along with a 404 status code.
  53. Args:
  54. e: The error object associated with the 404 error.
  55. """
  56. # Render the custom 404 error page
  57. return render_template('404.html'), 404
  58. # Define internal server error handler
  59. @app.errorhandler(500)
  60. def internal_server_error(e):
  61. """
  62. Handles 500 errors by rendering a custom 500 error page when an internal server error occurs,
  63. returning a rendered template along with a 500 status code.
  64. Args:
  65. e: The error object associated with the 500 error.
  66. """
  67. # Render the custom 500 error page
  68. return render_template('500.html'), 500
  69. return app
  70. def load_toml_config(app, env="localnet", config_path="site_config.toml"):
  71. """
  72. Loads environment-specific key-value pairs from a TOML configuration file into `app.config`.
  73. Args:
  74. app (Flask): The Flask application.
  75. env (str): The name of the environment section to load (default is "localnet").
  76. config_path (str): The path to the TOML configuration file.
  77. Raises:
  78. FileNotFoundError: If the configuration file cannot be found.
  79. KeyError: If the specified environment section does not exist.
  80. """
  81. # Verify that the configuration file exists
  82. if not os.path.isfile(config_path):
  83. raise FileNotFoundError(f"Configuration file '{config_path}' not found.")
  84. # Open and parse the configuration file (TOML)
  85. with open(config_path, "rb") as f:
  86. config = tomli.load(f)
  87. # Ensure the specified environment section exists in the configuration
  88. if env not in config:
  89. raise KeyError(f"Environment '{env}' not found in {config_path}")
  90. # Load the environment specific configurations into the Flask app's config object
  91. for key, value in config[env].items():
  92. app.config[key.upper()] = value
  93. # Print the loaded configuration for debugging or confirmation purposes
  94. print("\n" + "=" * 40)
  95. print("Loaded Explorer Site Configuration")
  96. print("=" * 40)
  97. for key in config[env]:
  98. print(f"{key.upper()} = {app.config[key.upper()]}")
  99. print("=" * 40 + "\n")