diff --git a/Dockerfile b/Dockerfile index 227dd1a..dcdc2ce 100644 --- a/Dockerfile +++ b/Dockerfile @@ -41,4 +41,5 @@ RUN chown -R myuser:myuser /app USER myuser # Start gunicorn with the appropriate options -CMD ["gunicorn", "-b", "0.0.0.0:3000", "--log-level=debug", "--workers=1", "app:app"] +# Without "2>&1" the gunicorn internal logging shows in 'docker logs' but doesn't go to stdout like our 'printf' commands. +CMD ["gunicorn", "-b", "0.0.0.0:3000", "--log-level=debug", "--workers=1", "app:app", "2>&1"] diff --git a/README.md b/README.md index 8b874fe..7eb0cc1 100644 --- a/README.md +++ b/README.md @@ -240,6 +240,7 @@ Run the app: ```commandline sh <(curl https://pkgx.sh) +python.org +virtualenv.pypa.io sh +# first time python -m venv . source bin/activate @@ -249,6 +250,8 @@ pip install -r requirements.txt cp data/webpush.db.empty data/webpush.db +# For DB access, you'll have to uncomment the local path for `db_uri`. + # 3 workers would trigger 3 daily subscription runs gunicorn -b 0.0.0.0:3000 --log-level=debug --workers=1 app:app diff --git a/app.py b/app.py index d0b5235..2896b76 100644 --- a/app.py +++ b/app.py @@ -23,7 +23,11 @@ CONTACT_EMAIL = "mailto:info@timesafari.app" app = Flask(__name__) + class WebPushService(): + + latest_subscription_run = None + """ This class provides services for sending web push notifications. """ @@ -44,10 +48,12 @@ class WebPushService(): # Setting the application instance self.app = app self.app.add_url_rule('/web-push/regenerate-vapid', view_func=self.regenerate_vapid, methods=['POST']) + self.app.add_url_rule('/web-push/ping', view_func=self.ping, methods=['GET']) # Setting the database URI for the application db_uri = os.getenv('SQLALCHEMY_DATABASE_URI', 'sqlite:////app/instance/data/webpush.db') # This relative path works in docker-compose + # This relative path works on a local run if you link to this dir from "var/app-instance" #db_uri = os.getenv('SQLALCHEMY_DATABASE_URI', 'sqlite:///data/webpush.db') self.app.config['SQLALCHEMY_DATABASE_URI'] = db_uri @@ -230,10 +236,24 @@ class WebPushService(): print(f"Result from sub {subscription.id}: success={result['success']} text={result['message']}", flush=True) print(f"{now} - Finished sending {len(all_subscriptions)} subscriptions.", flush=True) + self.latest_subscription_run = now + # Sleeping for 24 hours before sending the next set of notifications time.sleep(24 * 60 * 60) + # This is an endpoint, routed in __init__ + def ping(self) -> Response: + """ + Endpoint to show liveness info + + Returns: + - Response: Text with some subscription-run info + """ + + return f"pong ... with latest subscription run at {self.latest_subscription_run}" + + # This is an endpoint, routed in __init__ def regenerate_vapid(self) -> Tuple[str, int]: """