Skip to content

pydatacharlotte/effortless_rest_flask

Folders and files

NameName
Last commit message
Last commit date

Latest commit

 

History

21 Commits
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 

Repository files navigation

Effortless REST w/ FLask

There are 5 chapter folders. CD into each one and follow the below Chapter outline.

Pre-requisites

  1. pip install requirements
pip install -r requirements.txt
  1. (Optional) to work with a Heroku DB, create an application and attach PostgreSQL to the application. See chapters 2-5 in task.py and set the application name

    • You may use a local sqlLite DB instead of a Heroku deployed DB.

Getting Started

  • cd into each chapter and run the invoke commands to start such as:
invoke start
invoke init-db
invoke seed-db

Chapter 1: "Say Hello to the REAL world"

A word about dependencies

  • Python uses pip as a package manager
  • Many data scientist use conda to install packages.
example dependency export
pip freeze > requirements.txt
example dependency import/load
pip install -r requirements.txt

app/__init__.py

  • The main Flask application
  • Application factory
    • Allows for easier testing

Q: How do you configure a Flask application?

app/config.py

  • Place configs for Flask and its plugins here

Q: How do you start the server?

export FLASK_APP="app:create_app('dev')"
export FLASK_ENV="development" &&
flask run

⚠️ DO NOT USE 'flask' cli for produciton

Q: How do you start the server for PRODUCTION?

gunicorn --bind 0.0.0.0 --workers 2 "app:create_app('prod')"
  • 0.0.0.0: An alias IP to say expose on all network interfaces.
  • workers: number of unique web application processes to spin up.

Q: Do I have to type that EVERY TIME?

  • Check out Invoke
  • Build pre-defined tasks with easy configuration for options
  • see ./tasks.py

Example

invoke start

Chapter 2: Database: SQLAlchemy

app/__init__.py

  • Add SQLAlchemy INIT
  • Add route to get users

app/models/user.py

  • Create a model for the user table

app/config.py

  • Add the SQLALCHEMY_DATABASE_URI config

app/tasks.py

  • Add task to init db tables
  • Add task to seed users
  • run the seed on both local SQLite and PSQL

Q: Why does the /uhoh route not return?

jsonify() doesn’t know how to convert a SQLAlchemy class to JSON.

If only there were a way to convert a serialized Python class into a deserialized dict. Then we could convert the dict with jsonify()…

In comes...![marshmallow](https://marshmallow.readthedocs.io/en/stable/_static/marshmallow-logo.png =200x200)

app/__init__.py

  • The /marsh route uses a marshmallow Schema to deserialize a Python class.
  • We can control what’s being deserialized with the different Schemas. (UserSchema vs UserSchemaWithPassword)
  • Marshmallow can also serialize and validate a dict with .load()
    • e.g. an ISO date time stamp can be converted to a datetime object easily

Chapter 3: Security: FlaskPraetorian

FlaskPraetorian

app/config.py

  • Add the proper configs: JWT_ACCESS_LIFESPAN JWT_REFRESH_LIFESPAN

app/__init__.py

  • INIT Praetorian()
  • Add login() route
  • Protect routes with @auth_required decorator

tasks.py

  • Use utils for password hashing

Chapter 4: Documentation & API Scale

app/__init__.py

  • INIT Flask Rest Plus
  • Define prefix for all routes
  • Convert routes to Flask Rest Plus
  • Add Namespaces for segmenting API routes within swagger
  • Define authorizations section to easily add a JWT header to requests

Open up Swagger docs!


Chapter 5: Flask-Accepts

app/schemas/user.py

  • Add UserLoginSchema

app/__init__.py

  • Flask_accepts allows for easy Marshmallow schema conversion to JSON as well as adding Schema to Swagger docs
  • Decorate endpoints with @accepts & @responds