{"id":14065498,"url":"https://github.com/app-generator/sample-flask-best-practices","last_synced_at":"2025-09-05T11:36:37.359Z","repository":{"id":41509031,"uuid":"485898217","full_name":"app-generator/sample-flask-best-practices","owner":"app-generator","description":"Flask Best Practices for Deployment | AppSeed ","archived":false,"fork":false,"pushed_at":"2022-05-30T06:19:17.000Z","size":244,"stargazers_count":29,"open_issues_count":2,"forks_count":8,"subscribers_count":6,"default_branch":"main","last_synced_at":"2025-03-11T05:55:55.136Z","etag":null,"topics":["appseed-sample","flask-sample"],"latest_commit_sha":null,"homepage":"https://appseed.us","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/app-generator.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null}},"created_at":"2022-04-26T18:11:35.000Z","updated_at":"2025-01-15T06:11:20.000Z","dependencies_parsed_at":"2022-09-21T11:20:23.310Z","dependency_job_id":null,"html_url":"https://github.com/app-generator/sample-flask-best-practices","commit_stats":null,"previous_names":[],"tags_count":1,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-flask-best-practices","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-flask-best-practices/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-flask-best-practices/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/app-generator%2Fsample-flask-best-practices/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/app-generator","download_url":"https://codeload.github.com/app-generator/sample-flask-best-practices/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":243955701,"owners_count":20374373,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["appseed-sample","flask-sample"],"created_at":"2024-08-13T07:04:31.511Z","updated_at":"2025-03-19T00:31:01.252Z","avatar_url":"https://github.com/app-generator.png","language":"Python","funding_links":[],"categories":["Python"],"sub_categories":[],"readme":"# Flask Best Practices\n\nA simple `Flask` codebase that provides best practices for a secure production deployment.\n\n\u003e Status: **WIP** (not stable)\n\n\u003cbr /\u003e\n\u003cbr /\u003e\n\n\u003e Checklist \n\n| Status | Item | info | \n| --- | --- | --- |\n| ✔️ | `Up-to-date Dependencies` | - |\n| ✔️ | Flask-Login, Flask-SqlAlchemy | - |\n| ✔️ | BS5 for styling | Local path (latest BS5 stable version) |\n| ✔️ | Simple Custom Login / Register pages | - | \n| ✔️ | Password Recovery | - | \n| ✔️ | Unitary tests | - |\n| ✔️ | SCSS to CSS compilation | via pyScss |\n| ✔️ | Rate Limiter for Login \u0026 Register | via [Flask-RateLimiter](https://pypi.org/project/Flask-RateLimiter/) |\n| ✔️ | [Flask-Talisman](https://pypi.org/project/flask-talisman/) | Default policy |\n| ✔️ | Passwords Checks | Configurable Min/Max Lenght, Strength WIP |\n| ✔️ | Check email is valid \u0026 exists | via [validate-email-address](https://pypi.org/project/validate-email-address/) package |\n| ✔️ | Failed Logins Count | - |\n| ❌ | Account Suspension for X failed logins | Limit in Config |\n| ✔️ | Page Compression | via [Flask-Minify](https://pypi.org/project/Flask-Minify/) |\n| ✔️ | Deployment | [uWSGI](https://uwsgi-docs.readthedocs.io/en/latest/) / Nginx (reverse proxy) | \n| ✔️ | HEROKU integration | TODO add secrets to git repo | \n| ✔️ | Docker | - |\n\n\u003cbr /\u003e\n\n## ✨ Build from sources\n\n```bash\n$ # Clone the sources\n$ git clone https://github.com/app-generator/sample-flask-best-practices.git\n$ cd sample-flask-best-practices\n$\n$ # Virtualenv modules installation (Unix based systems)\n$ virtualenv env\n$ source env/bin/activate\n$\n$ # Virtualenv modules installation (Windows based systems)\n$ # virtualenv env\n$ # .\\env\\Scripts\\activate\n$\n$ # Install requirements\n$ pip3 install -r requirements.txt\n$\n$ # Set the FLASK_APP environment variable\n$ (Unix/Mac) export FLASK_APP=run.py\n$ (Windows) set FLASK_APP=run.py\n$ (Powershell) $env:FLASK_APP = \".\\run.py\"\n$\n$ # Set up the DEBUG environment\n$ # (Unix/Mac) export FLASK_ENV=development\n$ # (Windows) set FLASK_ENV=development\n$ # (Powershell) $env:FLASK_ENV = \"development\"\n$\n$ # Run the application\n$ # --host=0.0.0.0 - expose the app on all network interfaces (default 127.0.0.1)\n$ # --port=5000    - specify the app port (default 5000)  \n$ flask run --host=0.0.0.0 --port=5000\n$\n$ # Access the app in browser: http://127.0.0.1:5000/\n```\n\n\u003e Note: To use the app, please access the registration page and create a new user. After authentication, the app will unlock the private pages.\n\n\u003cbr /\u003e\n\n## ✨ Build from docker\n```bash\n$ # Run using docker-compose\n$ docker-compose build  # This will build the containers\n$ docker-compose up     # This will bring up the application\n$ # Open the application on you browser using you IPv4 Address on your browser i.e., only 2 routes available for auth /login ,/register\n$ # To find IPv4 Address\n$ # (Windows) ipconfig\n$ # (Unix/Mac) ifconfig\n```\n\n## ✨ Deploy on github workflow\n```bash\n$ # First set the git secrets using this https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository\n$ # Add the following keys to the secrets : HEROKU_APP_NAME , HEROKU_EMAIL , HEROKU_API_KEY\n$ # In the Dockerfile comment the line `CMD [ \"uwsgi\", \"--socket\", \"0.0.0.0:5000\", \"--protocol\", \"http\", \"--wsgi\", \"run:app\" ]`\n$ # Use the direct flask application run by uncommenting/adding the line `CMD [ \"python\", \"run.py\"]`\n$ # on push to the master/main the GH workflow will automatically create and push the image to your heroku\n```\n\n## ✨ Code-base structure\nThe project has a super simple structure, represented as below:\n```\n\u003c PROJECT ROOT \u003e\n   |\n   |-- app/\n   |    |\n   |    |-- __init__.py                 # Initialization of app\n   |    |-- config.py                   # Handlers for the front end routes\n   |    |-- setup_security.py                      \n   |    |-- auth/\n   |    |\n   |    |   |-- __init__.py\n   |    |   |-- email.py\n   |    |   |-- forms.py\n   |    |   |-- models.py               # Database models for storing data\n   |    |   |-- routes.py               # REST API hanlder\n   |    |\n   |    |-- static/                     # CSS files, Javascripts files\n   |    |   \n   |    |   |-- css/\n   |    |   |\n   |    |   |   |-- bootstrap.min.css\n   |    |   |   |-- bootstrap.min.css.map\n   |    |   |   |-- style.css\n   |    |   |\n   |    |   |-- js/\n   |    |   |\n   |    |   |   |-- bootstrap.min.js\n   |    |   |   |-- jquery.min.js\n   |    |   |\n   |    |-- templates/\n   |    |\n   |    |    |-- auth/                    # Auth related pages login/register\n   |    |    |\n   |    |    |    |-- login.html\n   |    |    |    |-- register.html\n   |    |    |    |-- reset_password.html\n   |    |    |    |-- reset_password_request.html\n   |    |    |\n   |    |    |-- bootstrap/\n   |    |    |\n   |    |    |    |-- bs5_base.html\n   |    |    |\n   |    |    |-- email/\n   |    |    |  \n   |    |    |    |-- reset_password.html\n   |    |    |    |-- reset_password.txt\n   |    |    |\n   |    |    |-- forms/\n   |    |    |\n   |    |    |    |-- forms.html\n   |    |    |\n   |    |    |-- navbar/\n   |    |    |  \n   |    |    |    |-- messages.html\n   |    |    |    |-- navbar.html\n   |    |    |-- base.html\n   |    |\n   |    |-- utils/\n   |    |\n   |    |    |-- __init__.py\n   |    |    |-- app_logger.py\n   |    |    |-- decorators.py\n   |    |    |-- mailer.py\n   |    |\n   |-- requirements.txt\n   |-- run.py\n   |\n   |-- ************************************************************************\n```\n  \n\u003e **@ToDo**\n\n\u003cbr /\u003e\n\n## ✨ Recompile CSS\n\nTo recompile SCSS files, follow this setup:\n\n\u003e **@ToDo**\n\n\u003cbr /\u003e\n\n--- \n**Flask Best Practices** - Provided by AppSeed\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapp-generator%2Fsample-flask-best-practices","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fapp-generator%2Fsample-flask-best-practices","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fapp-generator%2Fsample-flask-best-practices/lists"}