Python 3 Demo API is a JSON/REST API written in Python using the Flask web application framework with Marshmallow for JSON marshaling and SQLAlchemy with Alembic for database access and management. The API was tested with MariaDB and SQLite.
The API has a minimal OAuth2/
OpenID Connect
implementation based on
Flask-JWT-Extended. It does
email verification using AWS SES and the email
must be verified before the user can authentication to get an access_token
.
Phone numbers are optional when adding a user and they are validated using the
phonenumbers Python Library
but they are not verified. In addition to getting a token and verifying an
email, callers can reset passwords and get user information about themselves and
other public users.
The API itself has REST methods to get, set and list "thingy" types.
Install Python 3.7 and pip before you start.
The API uses Pipenv so setting up a (venv-based) environment is quick and easy:
-
Install or upgrade Pipenv
pip install --user --upgrade pipenv
-
Clone the repo and setup the virtual environment:
git clone git@github.com:amigus/python3-demo-app.git cd python3-demo-app pipenv install -d
-
Create an
instance
folder,settings.py
,test_settings.py
:Linux/UN*X shell:
mkdir -p instance cd instance cat <<EOF>>settings.py import os base_dir = os.path.dirname(os.path.abspath(__file__)) SECRET_KEY = "arandomsecret" CLIENT_ID = "arandomstring" RATELIMIT_ENABLED = False SQLALCHEMY_DATABASE_URI = os.environ.get( "SQLALCHEMY_DATABASE_URI", f"sqlite:///{os.path.sep.join([base_dir, 'db.sqlite3'])}" ) # DEBUG and testing features # SQLAlchemy will log all of the queries it execute SQLALCHEMY_ECHO = True # Flask will propagate exceptions; extensions test and use the setting too TESTING = True EOF cat <<EOF>>test_settings.py SECRET_KEY = "arandomsecret" CLIENT_ID = "arandomstring" RATELIMIT_ENABLED = False SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:" TESTING = True EOF cd ..
Windows
Powershell
:mkdir "instance" cd "instance" New-Item "settings.py" -Value @" import os base_dir = os.path.dirname(os.path.abspath(__file__)) SECRET_KEY = "arandomsecret" CLIENT_ID = "arandomstring" RATELIMIT_ENABLED = False SQLALCHEMY_DATABASE_URI = os.environ.get( "SQLALCHEMY_DATABASE_URI", f"sqlite:///{os.path.sep.join([base_dir, 'db.sqlite3'])}" ) # DEBUG and testing features # SQLAlchemy will log all of the queries it execute SQLALCHEMY_ECHO = True # Flask will propagate exceptions; extensions test and use the setting too TESTING = True "@ New-Item "test_settings.py" -Value @" SECRET_KEY = "arandomsecret" CLIENT_ID = "arandomstring" RATELIMIT_ENABLED = False SQLALCHEMY_DATABASE_URI = "sqlite:///:memory:" TESTING = True "@ cd ..
-
Create a
logging.yml
(required whenapp.testing != True
):Add
LOGGING_YAML
tosettings.py
:LOGGING_YAML = os.path.sep.join([base_dir, "logging.yml"])
Create
instance/logging.yml
:Linux/UN*X shell:
cat <<EOF>>instance/logging.yml version: 1 formatters: detailed: format: "[%(asctime)s] [%(process)d] [%(levelname)s] [%(filename)s:%(lineno)d] [%(funcName)s] %(message)s" handlers: stdout: class: logging.StreamHandler formatter: detailed stream: ext://sys.stdout root: handlers: [stdout] level: INFO loggers: app: level: DEBUG db: level: DEBUG emailer: level: DEBUG EOF
Windows
Powershell
:New-Item .\instance\logging.yml -Value @" version: 1 formatters: detailed: format: "[%(asctime)s] [%(process)d] [%(levelname)s] [%(filename)s:%(lineno)d] [%(funcName)s] %(message)s" handlers: stdout: class: logging.StreamHandler formatter: detailed stream: ext://sys.stdout root: handlers: [stdout] level: INFO loggers: app: level: DEBUG db: level: DEBUG emailer: level: DEBUG "@
-
Start the pipenv shell:
pipenv shell
-
Create the SQLite development database:
flask db upgrade
NOTE: the database will now exist as
db.sqlite3
in theinstance
folder. -
Run the server:
flask run --no-reload
If the changes include changes to the
Alembic migrations, be
sure to run flask db upgrade
within the virtual environment.
If the changes include changes to the Pipfile or Pipfile.lock, be sure to run
pipenv sync
.