
pythonanywhere.com
Webapp developed along the lines of [A beginner's guide to building a simple database-backed Flask website on PythonAnywhere](https://blog.pythonanywhere.com/121/)
We've added a formal Dockerfile and requirements.txt to simplify environment setup and enable containerized deployment of the application. By building on python:3.13-alpine, this transition ensures consistent runtime environments across development and production while maintaining a lightweight footprint. You can now build and run the services using standard container workflows. 
We have integrated an automated build and deployment workflow for the project targeting Azure App Service. The pipeline uses GitHub Actions to build the .NET application on Windows runners and subsequently deploy the artifact to production. This streamlines delivery by ensuring every push to the main branch is automatically deployed. 🚀
Updated flask_app.py to make module imports unconditional, as these dependencies are required regardless of the current REQUIRE_LOGIN configuration. Previously, disabling the login requirement caused potential runtime errors when the application accessed shared logic that depended on these imports. This ensures a more stable codebase and prevents import-related crashes.

This release moves away from the insecure shared username/password configuration previously handled by Flask's HTTPBasicAuth in favor of a new, robust custom login page. This update introduces individual user authentication, enabling the system to accurately track author attribution and timestamps for all posts. This shift provides a significantly more secure and auditable posting environment for all users. 
Added authenticated login/logout navigation and updated the comment form to reflect signed-in state.
This change wires in a dedicated /logout/ route with flask_login and exposes login/logout actions directly in the navbar, so the app now has a clearer session flow. The main page template also checks current_user.is_authenticated to render different comment form copy for logged-in users versus guests, making the UI better match the app’s access model. In practice, users now get clearer cues about whether they’re signed in and how they can interact with comments.
This 1.0.0 release packages a small but complete web app: a Flask-based scratchpad/comment board with SQLAlchemy-backed storage, a simple Bootstrap UI, and optional HTTP basic auth to protect posting. It also includes PythonAnywhere automation to reload the app and recreate its scheduled task, which makes the deployment more self-maintaining in production. For developers, the notable part is that this moves beyond a demo into an end-to-end deployable service with app, template, database model, and hosting automation all checked in. Practical effect: the project is now usable as a live, persistent mini app rather than just local prototype code. 
This change replaces the previous single hardcoded username/password check with a Flask-Login based flow that defines a User model, registers a user loader, and logs users in through login_user(). It also adds password-hash verification and support for multiple in-memory users, which makes the login page behavior closer to a real application and easier to extend. The main practical effect is cleaner auth logic and a more realistic foundation for protected routes going forward.
This change turns /login/ from a static page into a GET/POST login handler that checks submitted credentials against a hardcoded username/password pair and redirects successful logins back to the app. The login template now renders an inline warning when authentication fails, making the flow easier to test and understand. It’s still clearly a placeholder implementation, but it establishes the request handling and UX needed for a real login flow later.
This commit introduces a first-pass /login/ endpoint with a Bootstrap-backed HTML form for collecting username and password, while also renaming the existing @auth.verify_password callback from login to auth_verify_password. The rename prevents the auth function from colliding with the new Flask route handler and makes the authentication flow easier to reason about as the app grows. The page is mostly a UI scaffold for now rather than a complete login workflow, but it establishes the entry point for browser-based authentication.
This change turns the one-off PythonAnywhere keepalive script into a self-rescheduling job: after triggering the web app reload/extend call, it now queries existing scheduled tasks, removes prior copies of the same command, and creates a fresh daily task. The included log shows a couple of failed scheduling attempts while dialing in the API payload, followed by a successful task creation, which confirms the loop is now working end to end. Practically, this should keep the app renewed automatically without manual task setup.
This change introduces a small automation script that calls the PythonAnywhere API to reload the deployed web app and appends the result to a log file for visibility. It looks like the goal is to replace a manual “keep it running” step with a scheduled task, reducing the chance that the site quietly goes stale or needs hands-on maintenance. The Flask app itself is unchanged functionally; the main impact is operational reliability for the existing deployment. In practice, the site should stay up with less babysitting.
The README now includes a direct link to the live demo, making the project easier to evaluate at a glance. This is a small documentation improvement rather than a code change, but it lowers the friction for anyone who wants to see the app in action before cloning or installing anything. Practical effect: developers can reach the running demo faster.
This change splits the /comment_page handler into separate GET and POST paths and wraps authentication behind a small conditional decorator helper. The practical effect is that viewing comments can stay public, while posting comments is protected when REQUIRE_LOGIN is enabled, instead of forcing auth for every request to the route. It also makes the request flow easier to reason about by isolating rendering from mutation logic. should_post: true
This fixes a real form-submission bug in the scratchpad UI by replacing action="." with {{ url_for('handle_comments') }} in templates/main_page.html. The previous relative form action was brittle in Flask because trailing-slash handling can make the browser POST to a URL the route doesn't actually accept, leading to “Method Not Allowed” errors. Using url_for makes the template target the exact registered endpoint, so comment posting should now work reliably in practice.
This finishes the comment flow by replacing the temporary in-memory list with real SQLAlchemy reads and writes. The POST handler now creates and commits Comment records, the GET handler loads comments from the database, and the template was updated to render comment.content instead of plain strings. In practice, comments now survive across requests and behave like a proper persisted feature.
This change introduces a Comment model in flask_app.py with an explicit comments table, primary key, and content field. It lays the groundwork for replacing the in-memory comments list with persistent storage, which is an important step toward making the app stateful across restarts. Practically, this sets up the database layer needed for real comment persistence and future CRUD work.
This change introduces a simple REQUIRE_LOGIN flag in flask_app.py so the app can run with or without HTTP basic auth. When the toggle is off, password verification is bypassed and the auth hashing import is skipped, making it easier to isolate whether failures are caused by login plumbing or by the custom app logic itself. It’s a small debugging-oriented change, but it should make local testing and troubleshooting much faster.
This change wires flask_sqlalchemy into flask_app.py and configures a MySQL connection, including pool recycle and SQLAlchemy settings. It’s an important step toward replacing the app’s current in-memory data structures with persistent storage that survives restarts and supports real deployments. One notable concern is that the database credentials are committed directly in code, so the next practical improvement should be moving them into environment-based configuration. Overall, this sets up the foundation for storing application data durably.
This change adds in-app authentication to the comment page by wiring Flask-HTTPAuth into the Flask app and verifying a hashed password before serving or accepting comments. The root route now redirects to an authenticated /comment_page, which makes the app's access control explicit in code instead of relying on hosting-layer protection. It also replaces an exception path with a simple response for unknown methods. Practically, the app is now self-contained and protected even if the deployment environment doesn’t provide password gating.