Starter project template for running a Flask-based application as a Web API on Google App Engine Standard (Python 3.7 Runtime).
The application structure of this starter kit is loosely inspired by the API chapter of Miguel Grinberg's Flask Web Development (Second Edition) book, with the companion repo at https://github.com/miguelgrinberg/flasky
The scope of this starter kit is fairly small, punting on the front-end UI implementation to avoid bloating the code and keeping the list of opinionated choices fairly minimal.
This starter kit includes the following:
- Minimal Flask API blueprint, with a sample "hello world" handler at
app/api/hello.py
- Production-ready App Engine configuration (in
app.yaml
) with Flask WSGI app running via gunicorn and gevent - Continuous Integration (CI) workflow via GitHub Actions (see
.github/workflows/continous-integration.yaml
) - Unit tests via pytest (see
tests/test_api.py
)
The starter kit does not yet include the following (PRs are welcome):
- Continous deployment (CD) workflow via GitHub Actions, leveraging https://github.com/GoogleCloudPlatform/github-actions
- Acceptance/smoke tests hitting API endpoints on App Engine post-deployment
- Sample integration with Cloud Firestore
- Sample auth integration
- Python 3.7 or later
- Windows, macOS, and Linux development environments are supported
Assuming the development setup requirements above have been satisfied, run the following in a terminal (git-bash is recommended on Windows) after cloning the repo to set up your local development environment.
# Install local dev requirements, ideally in an isolated Python 3.7 (or later) environment
pip install -r requirements-dev.txt
If you're on Linux or macOS you can run the app via gunicorn
, which offers a --reload
option and
more closely emulates the App Engine production runtime, which uses gunicorn by default.
# Linux and macOS only, use --reload flag to automatically reload on code changes
gunicorn app:application --reload
# Cross-platform, works on Windows, macOS and Linux, albeit without a --reload option available
waitress-serve app:application
The app is viewable at http://localhost:8000 (for gunicorn) or at http://localhost:8080 (for Waitress).
The sample hello endpoint is at http://$HOST:$PORT/api/v1/hello/world
The app runs on port 8000 (for gunicorn) and 8080 (for waitress) by default.
To customize the port, pass the --bind
option (for gunicorn)
or the --port
option (for Waitress) as in the following examples...
# Set gunicorn port to 9000
gunicorn --bind=:9000 app:application --reload
# Set Waitress port to 9000
waitress-serve --port=9000 app:application
The tests are run via pytest
, with the configuration file at pytest.ini
.
# Run all tests
pytest
# Run only a particular test
pytest tests/test_api.py::test_hello
The following steps only need to be performed once per local development environment...
- Create an App Engine Project at https://console.cloud.google.com/appengine
- Download and install the Google Cloud SDK
- If on Windows, run the "Google Cloud SDK Shell" application
- Type
gcloud init
in a terminal or in the Cloud SDK Shell - Log in via
gcloud auth login
in a terminal or in Cloud SDK Shell as needed - Set the active project (created in step 1) via
gcloud config set project PROJECT_ID
- If on Windows or macOS, install the App Engine components via
gcloud components install app-engine-python
Ensure the project you want to deploy is selected via gcloud config set project PROJECT_ID
, then
run the following command at the repo root (where the app.yaml
config file is located) to deploy to App Engine...
# Deploy to App Engine
gcloud app deploy
A GitHub Actions continuous integration (CI) workflow is provided in the .github/workflows
folder, running
unit tests when a non-master branch is pushed to GitHub.
Perform the following steps to configure the CI workflow to be enforced on GitHub pull requests (PRs) against the repo's master branch:
- In the GitHub UI for your forked repo, click the
Settings
tab at top and click theBranches
nav item at left. - In the
Branch protection rules
section, click theAdd rule
button if there is no rule for the master branch. - If there is a protection rule for the master branch, click the
Edit
button for that rule. - Enable the checkbox for the
Require status checks to pass before merging
. - If
Run unit tests
is a visible option for theStatus checks found in the last week for this repository
, enable that option. - If the
Run unit tests
option isn't displayed yet, it will display after a non-master branch has been pushed. - Create a branch with a test commit to confirm the above has enabled status checks for PRs in your repo.
A Continuous Deployment (CD) pipeline via GitHub Actions will likely land in this starter kit to complement the CI workflow noted above.
This repo is the successor of https://github.com/kamalgill/flask-appengine-template , now archived due to legacy technology choices and the end-of-life of Python 2 on Jan 1 2020.