Boilerplate setup for SaaS JSONAPI in Python using Flask & SQLAlchemy
Document how I like to setup a Python API Project.
The .sublime-project file should be checked into version control.
Add *.sublime-workspace
to .gitignore
.
Exclude some cache files from the project by excluding some folder from the sublime-project
settings:
"folder_exclude_patterns": [".cache", ".mypy_cache", ".pytest_cache", "__pycache__"]
SublimeLinter has integrated support for pipenv now so we can fully use pipenv's virtualenv creation.
brew install pyenv pipenv
cd "${PROJECT_DIR}"
pipenv --three
Errors like zipimport.ZipImportError: can't decompress data; zlib not available
can be resolved by installing xcode tools: xcode-select --install
Using pipenv
the project and development dependencies are tracked in Pipfile
and Pipfile.lock
. The requirements files for pip have been migrated and moved.
Since the Pipfile loses comments on each pipenv install
this list documents the
reason for certain dependencies:
- bcrypt # Password Hashing for Login
- # Flask-REST-JSONAPI # JSONAPI in Flask (seems abandoned or just slow to develop, we can do better.)
- Flask # Flask web server
- future # Python3 Compatibility (import builtins)
- gunicorn # Server for deployed app
- marshmallow-jsonapi # Handle the JSONAPI Envelope for API Schemas
- marshmallow-sqlalchemy # Map DB Models to API Schemas
- mypy # Not a development requirement because we may need to import from mypy
- psycopg2 # PostgreSQL library
- PyMySQL # PDO for MySQL appropriate for Google Cloud SQL DB
- SQLAlchemy # ORM
- SQLAlchemy-Continuum # Audit log/versioning
Install the same requirements as locked by pipenv: pipenv sync --dev
For PostgreSQL:
brew install postgresql
sed -i '' -e "s/timezone = 'US\\/Eastern'/timezone = 'UTC'/" /usr/local//var/postgres/postgresql.conf
pg_ctl --pgdata=/usr/local/var/postgres --log=/dev/null start # start postgresql
createuser api --createdb
createdb "${PROJECT_NAME}_dev" -U api
For MySQL:
brew install mariadb
echo -e "[mysqld]\\ndefault-time-zone='+00:00'" > /usr/local/etc/my.cnf.d/default-time-zone.cnf
mysql.server start
mysql -u root -e 'CREATE DATABASE `'"${PROJECT_NAME}_dev"'` /*!40100 DEFAULT CHARACTER SET utf8 */'
pipenv update --outdated --dev # Look for updates allowed by Pipfile
pipenv update --dev # Actually install updates to dependencies
Because we are using pipenv all the python commands need to be run using
pipenv run
. The three commands below are configured in the Pipfile scripts.
Linting the code: pipenv run lint
Type checking: pipenv run mypy
Run tests: pipenv run test
I don't like pipenv shell
and I haven't setup an automatic activation of the
virtualenv
so for now we need to remember to use pipenv run
.
- common
- Module catchall for shared code (log and utilities)
- models
- Resource models, don't use flask-sqlalchemy so the models can be used by scripts outside of flask context.