Giter Site home page Giter Site logo

app-generator / sample-flask-best-practices Goto Github PK

View Code? Open in Web Editor NEW
21.0 7.0 6.0 244 KB

Flask Best Practices for Deployment | AppSeed

Home Page: https://appseed.us

License: MIT License

Python 43.05% HTML 31.10% Dockerfile 0.95% JavaScript 24.02% Procfile 0.06% SCSS 0.29% CSS 0.52%
appseed-sample flask-sample

sample-flask-best-practices's Introduction

Flask Best Practices

A simple Flask codebase that provides best practices for a secure production deployment.

Status: WIP (not stable)



Checklist

Status Item info
✔️ Up-to-date Dependencies -
✔️ Flask-Login, Flask-SqlAlchemy -
✔️ BS5 for styling Local path (latest BS5 stable version)
✔️ Simple Custom Login / Register pages -
✔️ Password Recovery -
✔️ Unitary tests -
✔️ SCSS to CSS compilation via pyScss
✔️ Rate Limiter for Login & Register via Flask-RateLimiter
✔️ Flask-Talisman Default policy
✔️ Passwords Checks Configurable Min/Max Lenght, Strength WIP
✔️ Check email is valid & exists via validate-email-address package
✔️ Failed Logins Count -
Account Suspension for X failed logins Limit in Config
✔️ Page Compression via Flask-Minify
✔️ Deployment uWSGI / Nginx (reverse proxy)
✔️ HEROKU integration TODO add secrets to git repo
✔️ Docker -

✨ Build from sources

$ # Clone the sources
$ git clone https://github.com/app-generator/sample-flask-best-practices.git
$ cd sample-flask-best-practices
$
$ # Virtualenv modules installation (Unix based systems)
$ virtualenv env
$ source env/bin/activate
$
$ # Virtualenv modules installation (Windows based systems)
$ # virtualenv env
$ # .\env\Scripts\activate
$
$ # Install requirements
$ pip3 install -r requirements.txt
$
$ # Set the FLASK_APP environment variable
$ (Unix/Mac) export FLASK_APP=run.py
$ (Windows) set FLASK_APP=run.py
$ (Powershell) $env:FLASK_APP = ".\run.py"
$
$ # Set up the DEBUG environment
$ # (Unix/Mac) export FLASK_ENV=development
$ # (Windows) set FLASK_ENV=development
$ # (Powershell) $env:FLASK_ENV = "development"
$
$ # Run the application
$ # --host=0.0.0.0 - expose the app on all network interfaces (default 127.0.0.1)
$ # --port=5000    - specify the app port (default 5000)  
$ flask run --host=0.0.0.0 --port=5000
$
$ # Access the app in browser: http://127.0.0.1:5000/

Note: To use the app, please access the registration page and create a new user. After authentication, the app will unlock the private pages.


✨ Build from docker

$ # Run using docker-compose
$ docker-compose build  # This will build the containers
$ docker-compose up     # This will bring up the application
$ # Open the application on you browser using you IPv4 Address on your browser i.e., only 2 routes available for auth /login ,/register
$ # To find IPv4 Address
$ # (Windows) ipconfig
$ # (Unix/Mac) ifconfig

✨ Deploy on github workflow

$ # First set the git secrets using this https://docs.github.com/en/actions/security-guides/encrypted-secrets#creating-encrypted-secrets-for-a-repository
$ # Add the following keys to the secrets : HEROKU_APP_NAME , HEROKU_EMAIL , HEROKU_API_KEY
$ # In the Dockerfile comment the line `CMD [ "uwsgi", "--socket", "0.0.0.0:5000", "--protocol", "http", "--wsgi", "run:app" ]`
$ # Use the direct flask application run by uncommenting/adding the line `CMD [ "python", "run.py"]`
$ # on push to the master/main the GH workflow will automatically create and push the image to your heroku

✨ Code-base structure

The project has a super simple structure, represented as below:

< PROJECT ROOT >
   |
   |-- app/
   |    |
   |    |-- __init__.py                 # Initialization of app
   |    |-- config.py                   # Handlers for the front end routes
   |    |-- setup_security.py                      
   |    |-- auth/
   |    |
   |    |   |-- __init__.py
   |    |   |-- email.py
   |    |   |-- forms.py
   |    |   |-- models.py               # Database models for storing data
   |    |   |-- routes.py               # REST API hanlder
   |    |
   |    |-- static/                     # CSS files, Javascripts files
   |    |   
   |    |   |-- css/
   |    |   |
   |    |   |   |-- bootstrap.min.css
   |    |   |   |-- bootstrap.min.css.map
   |    |   |   |-- style.css
   |    |   |
   |    |   |-- js/
   |    |   |
   |    |   |   |-- bootstrap.min.js
   |    |   |   |-- jquery.min.js
   |    |   |
   |    |-- templates/
   |    |
   |    |    |-- auth/                    # Auth related pages login/register
   |    |    |
   |    |    |    |-- login.html
   |    |    |    |-- register.html
   |    |    |    |-- reset_password.html
   |    |    |    |-- reset_password_request.html
   |    |    |
   |    |    |-- bootstrap/
   |    |    |
   |    |    |    |-- bs5_base.html
   |    |    |
   |    |    |-- email/
   |    |    |  
   |    |    |    |-- reset_password.html
   |    |    |    |-- reset_password.txt
   |    |    |
   |    |    |-- forms/
   |    |    |
   |    |    |    |-- forms.html
   |    |    |
   |    |    |-- navbar/
   |    |    |  
   |    |    |    |-- messages.html
   |    |    |    |-- navbar.html
   |    |    |-- base.html
   |    |
   |    |-- utils/
   |    |
   |    |    |-- __init__.py
   |    |    |-- app_logger.py
   |    |    |-- decorators.py
   |    |    |-- mailer.py
   |    |
   |-- requirements.txt
   |-- run.py
   |
   |-- ************************************************************************

@ToDo


✨ Recompile CSS

To recompile SCSS files, follow this setup:

@ToDo



Flask Best Practices - Provided by AppSeed

sample-flask-best-practices's People

Contributors

app-generator avatar raviwrk-official avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

sample-flask-best-practices's Issues

uWSGI - compilation error on Windows

The modules Installation fails on Windows for uWSGI (see the error log).

Patch: Replace uWSGI with Gunicorn

err log

Collecting uwsgi
  Downloading uwsgi-2.0.20.tar.gz (804 kB)
     ━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━━ 804.9/804.9 KB 5.6 MB/s eta 0:00:00
  Preparing metadata (setup.py) ... error
  error: subprocess-exited-with-error

  × python setup.py egg_info did not run successfully.
  │ exit code: 1
  ╰─> [8 lines of output]
      Traceback (most recent call last):
        File "<string>", line 2, in <module>
        File "<pip-setuptools-caller>", line 34, in <module>
        File "C:\Users\Sm0ke\AppData\Local\Temp\pip-install-umluqnaj\uwsgi_9b6e155339de40caa380227bbf6e1840\setup.py", line 3, in <module>
          import uwsgiconfig as uc
        File "C:\Users\Sm0ke\AppData\Local\Temp\pip-install-umluqnaj\uwsgi_9b6e155339de40caa380227bbf6e1840\uwsgiconfig.py", line 8, in <module>
          uwsgi_os = os.uname()[0]
      AttributeError: module 'os' has no attribute 'uname'
      [end of output]

  note: This error originates from a subprocess, and is likely not a problem with pip.
error: metadata-generation-failed

× Encountered error while generating package metadata.
╰─> See above for output.

Docker Ports

Hello @raviwrk-official

Please configure Docker to use the below ports:

  • 5005 for the uWSGI (not exposed)
  • 85 for the Nginx (exposed)

As for all other AppSeed kits, once the user type docker-compose up --build the app should be LIVE at:

http://localhost:85

P.S. Usually ports 5000, and 80 are taken by other services.

ty!

Runtime Errors - @security[talisman] / SyntaxError: invalid syntax

During the runtime, the app crashes with SyntaxError: invalid syntax caused by the version of Python (3.9 or greater required).

Would be great to support the usage of the App for earlier versions of Python, starting with 3.6.0.
Sometimes, the deployment servers use old versions.

Error Log

(env) PS D:\work\repo-samples\sample-flask-best-practices> flask run
 * Serving Flask app 'run.py' (lazy loading)
 * Environment: development
 * Debug mode: on
Traceback (most recent call last):
  File "c:\python38\lib\runpy.py", line 194, in _run_module_as_main
    return _run_code(code, main_globals, None,
  File "c:\python38\lib\runpy.py", line 87, in _run_code
    exec(code, run_globals)
  File "D:\work\repo-samples\sample-flask-best-practices\env\Scripts\flask.exe\__main__.py", line 7, in <module>
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\flask\cli.py", line 985, in main
    cli.main()
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\flask\cli.py", line 579, in main
    return super().main(*args, **kwargs)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\click\core.py", line 1055, in main
    rv = self.invoke(ctx)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\click\core.py", line 1657, in invoke
    return _process_result(sub_ctx.command.invoke(sub_ctx))
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\click\core.py", line 1404, in invoke
    return ctx.invoke(self.callback, **ctx.params)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\click\core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\click\decorators.py", line 84, in new_func
    return ctx.invoke(f, obj, *args, **kwargs)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\click\core.py", line 760, in invoke
    return __callback(*args, **kwargs)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\flask\cli.py", line 847, in run_command
    app = DispatchingApp(info.load_app, use_eager_loading=eager_loading)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\flask\cli.py", line 299, in __init__
    self._load_unlocked()
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\flask\cli.py", line 333, in _load_unlocked
    self._app = rv = self.loader()
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\flask\cli.py", line 389, in load_app
    app = locate_app(import_name, name)
  File "D:\work\repo-samples\sample-flask-best-practices\env\lib\site-packages\flask\cli.py", line 234, in locate_app
    __import__(module_name)
  File "D:\work\repo-samples\sample-flask-best-practices\run.py", line 4, in <module>
    app = create_app(config_name='development')
  File "D:\work\repo-samples\sample-flask-best-practices\app\__init__.py", line 58, in create_app
    from app.auth.routes import auth
  File "D:\work\repo-samples\sample-flask-best-practices\app\auth\routes.py", line 24
    @security["talisman"](frame_options=ALLOW_FROM,
             ^
SyntaxError: invalid syntax

Unitary Tests

Hello @raviwrk-official

Please add a minimal test suite for the existing features:

  • register ok
  • login ok
  • registration with existing email
  • registration using a week password
  • login using an unexisting user
  • login using the wrong password.

All test data should be deleted at the end of the test suite.

P.S. The tests section should be also mentioned on the README.

Ty!

App is unusable - The index shows 404

How to reproduce:

  • fresh clone
  • install dependencies
  • set up the environment
  • start the app
  • access the app in the browser:

App Console

(env) PS D:\work\repo-samples\sample-flask-best-practices> flask run --port=5003
 * Serving Flask app 'run.py' (lazy loading)
 * Environment: development
 * Debug mode: on
2022-05-27 11:46:47,478 | INFO |  * Running on http://127.0.0.1:5003 (Press CTRL+C to quit)
2022-05-27 11:46:47,481 | INFO |  * Restarting with stat
 * Debugger is active!
 * Debugger PIN: 669-056-847
127.0.0.1 - - [27/May/2022 11:46:58] "GET / HTTP/1.1" 404 -
2022-05-27 11:46:58,848 | INFO | 127.0.0.1 - - [27/May/2022 11:46:58] "GET / HTTP/1.1" 404 -
127.0.0.1 - - [27/May/2022 11:46:58] "GET /favicon.ico HTTP/1.1" 404 -
2022-05-27 11:46:58,956 | INFO | 127.0.0.1 - - [27/May/2022 11:46:58] "GET /favicon.ico HTTP/1.1" 404 -

App Screen

image

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.