From a2faa5f232273b7cc7416ae2a600b0a8c1abca62 Mon Sep 17 00:00:00 2001
From: Tatenda <31291528+rideam@users.noreply.github.com>
Date: Mon, 27 Feb 2023 16:05:01 +0200
Subject: [PATCH] prepare app for deployment

---
 app.py            | 54 ++++++++++++++++++++++++++++++++++++++++++++++-
 config.py         | 12 ++++++++---
 requirements.txt  | 50 ++++++++++++++++++++++++++-----------------
 routes/appauth.py |  4 ----
 settings.py       |  6 +++++-
 5 files changed, 98 insertions(+), 28 deletions(-)

diff --git a/app.py b/app.py
index 7233c3d..f8776ac 100644
--- a/app.py
+++ b/app.py
@@ -1,6 +1,12 @@
 from flask import Flask, Response
 from flask_migrate import Migrate
 
+from flask.logging import default_handler
+import logging
+from logging.handlers import RotatingFileHandler
+from click import echo
+import sqlalchemy as sa
+
 import views
 import settings
 from routes import *
@@ -32,6 +38,49 @@
 migrate = Migrate(app, db)
 
 
+def check_db_init():
+    # Check if the database needs to be initialized
+    engine = sa.create_engine(app.config['SQLALCHEMY_DATABASE_URI'])
+    inspector = sa.inspect(engine)
+    if not inspector.has_table("user"):
+        with app.app_context():
+            db.drop_all()
+            db.create_all()
+            app.logger.info('Initialized the database!')
+    else:
+        app.logger.info('Database already contains the users table.')
+
+
+def configure_logging():
+    # Logging Configuration
+    if app.config['LOG_WITH_GUNICORN']:
+        gunicorn_error_logger = logging.getLogger('gunicorn.error')
+        app.logger.handlers.extend(gunicorn_error_logger.handlers)
+        app.logger.setLevel(logging.DEBUG)
+    else:
+        file_handler = RotatingFileHandler('instance/bima.log',
+                                           maxBytes=16384,
+                                           backupCount=20)
+        file_formatter = logging.Formatter('%(asctime)s %(levelname)s %(threadName)s-%(thread)d: %(message)s [in %(filename)s:%(lineno)d]')
+        file_handler.setFormatter(file_formatter)
+        file_handler.setLevel(logging.INFO)
+        app.logger.addHandler(file_handler)
+
+    # Remove the default logger configured by Flask
+    app.logger.removeHandler(default_handler)
+
+    app.logger.info('Starting the Bima Insurance app...')
+
+
+def register_cli_commands(app):
+    @app.cli.command('init_db')
+    def initialize_database():
+        """Initialize the database."""
+        db.drop_all()
+        db.create_all()
+        echo('Initialized the database!')
+
+
 @auth.verify_password
 def verify_password(username, password):
     """ Verify admin username and password for the admin page
@@ -126,5 +175,8 @@ def make_shell_context():
 app.register_blueprint(appauth.auth_bp)
 app.register_blueprint(data.data_bp)
 
+configure_logging()
+check_db_init()
+
 if __name__ == "__main__":
-    app.run(host='0.0.0.0', port=5001, debug=True)
+    app.run()
diff --git a/config.py b/config.py
index 4c3a43d..ad6df51 100644
--- a/config.py
+++ b/config.py
@@ -6,12 +6,18 @@
 
 
 class BaseConfig(object):
+    FLASK_ENV = 'production'
     DEBUG = False
     TESTING = False
     SESSION_COOKIE_SAMESITE = "None"
     SESSION_COOKIE_SECURE = True
-    SQLALCHEMY_DATABASE_URI = 'postgresql:///playground'
-    # SQLALCHEMY_DATABASE_URI = 'sqlite:///database.db'
+    SQLALCHEMY_DATABASE_URI = settings.db_url
     SQLALCHEMY_TRACK_MODIFICATIONS = False
-    FLASK_ADMIN_SWATCH = 'readable'
+    FLASK_ADMIN_SWATCH = settings.admin_swatch
     TEMPLATE_MODE = settings.template_mode
+    LOG_WITH_GUNICORN = settings.log_with_gunicorn
+
+
+class DevelopmentConfig(BaseConfig):
+    FLASK_ENV = 'development'
+    DEBUG = True
diff --git a/requirements.txt b/requirements.txt
index 3162e0d..31ef33a 100644
--- a/requirements.txt
+++ b/requirements.txt
@@ -1,19 +1,31 @@
-Flask
-Flask-HTTPAuth
-Flask-Login
-Flask-Migrate
-Flask-Script
-Flask-SQLAlchemy
-Flask-WTF
-
-psycopg2
-psycopg2-binary
-py-algorand-sdk
-
-python-dotenv
-SQLAlchemy
-tomlkit
-typing_extensions
-Werkzeug
-WTForms
-Flask-Admin
\ No newline at end of file
+alembic==1.9.4
+cffi==1.15.1
+click==8.1.3
+Flask==2.2.3
+Flask-Admin @ git+https://github.com/flask-admin/flask-admin@c4ba7cc55ea0592f8946fec1138c2841607e33b5
+Flask-HTTPAuth==4.7.0
+Flask-Login==0.6.2
+Flask-Migrate==4.0.4
+Flask-Script==2.0.6
+Flask-SQLAlchemy==3.0.3
+Flask-WTF==1.1.1
+gunicorn==20.1.0
+importlib-metadata==6.0.0
+itsdangerous==2.1.2
+Jinja2==3.1.2
+Mako==1.2.4
+MarkupSafe==2.1.2
+msgpack==1.0.4
+psycopg2==2.9.5
+psycopg2-binary==2.9.5
+py-algorand-sdk==2.0.0
+pycparser==2.21
+pycryptodomex==3.17
+PyNaCl==1.5.0
+python-dotenv==0.21.1
+SQLAlchemy==2.0.3
+tomlkit==0.11.6
+typing_extensions==4.5.0
+Werkzeug==2.2.3
+WTForms==3.0.1
+zipp==3.13.0
diff --git a/routes/appauth.py b/routes/appauth.py
index 90b95ef..1fd8e4b 100644
--- a/routes/appauth.py
+++ b/routes/appauth.py
@@ -36,14 +36,10 @@ def login():
                     db.session.commit()
             except Exception as err:
                 print(err)
-            print('passed by here')
-
             return redirect(url_for('main_bp.index'))
         except Exception as err:
             flash(err)
-            print('in exception')
             return render_template('login.html', form=form)
-    print('out here')
     return render_template('login.html', form=form)
 
 
diff --git a/settings.py b/settings.py
index de3a2e3..e65351a 100644
--- a/settings.py
+++ b/settings.py
@@ -3,7 +3,7 @@
 
 load_dotenv()
 
-configClass = 'config.BaseConfig'
+configClass = os.getenv("CONFIG_CLASS", 'config.BaseConfig')
 secret_key = os.environ["SECRET_FLASK"]
 
 algod_api = os.environ["TESTNET_ALGOD_ADDRESS"]
@@ -18,5 +18,9 @@
 
 admin_user = os.environ["ADMIN_USERNAME"]
 admin_pwd = os.environ["ADMIN_PASSWORD"]
+admin_swatch = os.environ['ADMIN_SWATCH']
+
+db_url = os.environ['DATABASE_URL'].replace("postgres://", "postgresql://", 1)
+log_with_gunicorn = os.getenv('LOG_WITH_GUNICORN', default=False)
 
 template_mode = 'bootstrap3'