Skip to content

Commit

Permalink
init
Browse files Browse the repository at this point in the history
  • Loading branch information
the-infinity committed Oct 18, 2023
0 parents commit ac2ba67
Show file tree
Hide file tree
Showing 143 changed files with 5,903 additions and 0 deletions.
19 changes: 19 additions & 0 deletions .coveragerc
Original file line number Diff line number Diff line change
@@ -0,0 +1,19 @@
[run]
# Enable branch coverage
branch = True

[report]
show_missing = True
skip_empty = True
exclude_lines =
pragma: no ?cover
@abstractmethod
@overload
if TYPE_CHECKING:

[html]
directory = reports/coverage_html/
show_contexts = True

# Enable this to only see files in the report that don't have 100% coverage yet.
#skip_covered = True
6 changes: 6 additions & 0 deletions .dockerignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Keep the Docker build context small to speed up builds. This is really all we need in the Dockerfile.
*
!webapp
!runsocketioserverproduction.py
!requirements.txt
!requirements-dev.txt
1 change: 1 addition & 0 deletions .flaskenv
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
FLASK_APP="webapp:launch()"
14 changes: 14 additions & 0 deletions .github/dependabot.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
version: 2
updates:
- package-ecosystem: github-actions
directory: '/'
schedule:
interval: weekly
- package-ecosystem: pip
directory: '/'
schedule:
interval: weekly
- package-ecosystem: docker
directory: '/'
schedule:
interval: weekly
35 changes: 35 additions & 0 deletions .github/workflows/build-publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
name: build & publish Docker image

on:
push:
branches:
- main

jobs:
build-publish:
runs-on: ubuntu-latest
steps:
- name: checkout
uses: actions/checkout@v4

- name: set up Docker buildx
uses: docker/setup-buildx-action@v2

- name: log into the GitHub Container Registry
uses: docker/login-action@v2
with:
registry: ghcr.io
username: ${{ github.actor }}
password: ${{ github.token }}

- name: build and push Docker image
uses: docker/build-push-action@v4
with:
push: true
tags: |
ghcr.io/${{ github.repository }}:latest
platforms: linux/amd64,linux/arm64
# https://docs.docker.com/build/ci/github-actions/cache/#cache-backend-api
cache-from: type=gha
cache-to: type=gha,mode=max
file: Dockerfile.prod
29 changes: 29 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
.idea/
.vscode/

__pycache__/
*.py[cod]
.pip/
.pytest_cache
.coverage
/htmlcov
/reports
/*.sql

/venv
/logs/*
/temp
/.env

!/**/.gitkeep

/config.yaml
/dev/api_tests/http-client.env.json

/Makefile.env
/docker-compose_local.yml
coverage.xml

.ruff_cache/
.mypy_cache/
.betterer_cache/
3 changes: 3 additions & 0 deletions .gitmodules
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
[submodule "webapp/converter"]
path = webapp/converter
url = https://github.com/ParkenDD/ParkAPI2-sources/
44 changes: 44 additions & 0 deletions Dockerfile.dev
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
FROM ubuntu:22.04

ENV DEBIAN_FRONTEND=noninteractive

# Upgrade packages and install locales
RUN echo "locales locales/default_environment_locale select en_US.UTF-8" | debconf-set-selections && \
echo "locales locales/locales_to_be_generated select en_US.UTF-8 UTF-8" | debconf-set-selections && \
apt-get update && \
apt-get upgrade -y && \
apt-get install -y locales

ENV LANG=en_US.UTF-8 \
LC_ALL=en_US.UTF-8 \
LANGUAGE=en_US:en

ENV PYTHONUNBUFFERED=1 \
PYTHONDONTWRITEBYTECODE=1

# Install commonly used packages
# - libssl-dev, libffi-dev: required for Python cryptography module
RUN apt-get install -y \
python3-pip \
python3-dev \
build-essential \
libssl-dev \
libffi-dev \
inotify-tools \
wait-for-it \
git \
wget

# Create symlinks /usr/bin/python and /usr/bin/pip, but only if these files don't exist yet
RUN { [ -e /usr/bin/python ] || ln -s /usr/bin/python3 /usr/bin/python; } && \
{ [ -e /usr/bin/pip ] || ln -s /usr/bin/pip3 /usr/bin/pip; }

RUN mkdir -p /app
WORKDIR /app

COPY ./requirements.txt requirements-dev.txt .
RUN pip install --upgrade pip && \
pip install -r requirements.txt -r requirements-dev.txt

CMD ["python3", "runserver.py"]
EXPOSE 5000
14 changes: 14 additions & 0 deletions Dockerfile.prod
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
FROM python:3.11-alpine

ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

WORKDIR /app

COPY ./requirements.txt /app/requirements.txt
RUN pip install -r requirements.txt

COPY . /app

EXPOSE 5000
CMD ["gunicorn", "--bind", "0.0.0.0:5000", "app:app"]
21 changes: 21 additions & 0 deletions LICENCE.txt
Original file line number Diff line number Diff line change
@@ -0,0 +1,21 @@
MIT License

Copyright (c) [year] [fullname]

Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
in the Software without restriction, including without limitation the rights
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all
copies or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
SOFTWARE.
188 changes: 188 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,188 @@
DOCKER_COMPOSE = docker compose
FLASK_RUN = $(DOCKER_COMPOSE) run --rm flask

DOCKER_REGISTRY = ghcr.io

# Separate environment for running integration tests
TESTING_COMPOSE_PROJECT_NAME = park-api_integrationtests
TESTING_DOCKER_COMPOSE = $(DOCKER_COMPOSE) -p $(TESTING_COMPOSE_PROJECT_NAME)

# Include local file with custom variables/rules (only if the file exists)
-include Makefile.env

# Default target when running `make`
.PHONY: all
all: docker-up


# Configuration
# -------------

.PHONY: config
config: .env config.yaml

# Create .env file to set the UID/GID for the docker containers to run as to the current user
.env:
echo "DOCKER_LOCAL_USER=$(shell id -u):$(shell id -g)" >> .env

# Create config file from config_dist_dev.yaml if it does not exist yet
config.yaml:
cp config_dist_dev.yaml config.yaml


# Container management
# --------------------

.PHONY: first-start
first-start: config docker-login docker-build apply-migrations
$(DOCKER_COMPOSE) down
@echo
@echo 'Database is all set up! \o/'
@echo 'You can now start the project with "make docker-up"'

# Login to Docker registry
.PHONY: docker-login
docker-login:
docker login $(DOCKER_REGISTRY)

# Builds and starts all docker containers
.PHONY: docker-up
docker-up: config docker-build
$(DOCKER_COMPOSE) up

# Start containers in background (or recreate containers while they are running attached to another terminal)
.PHONY: docker-up-detached
docker-up-detached: config docker-build
$(DOCKER_COMPOSE) up --detach

.PHONY: docker-down
docker-down: .env
$(DOCKER_COMPOSE) down --remove-orphans
$(TESTING_DOCKER_COMPOSE) down --remove-orphans

.PHONY: docker-testing-down
docker-testing-down: .env
$(TESTING_DOCKER_COMPOSE) down --remove-orphans --volumes

# Restart all containers (default) or only the containers specified by SERVICE (e.g. `make docker-restart SERVICE=flask`)
.PHONY: docker-restart
docker-restart: .env
$(DOCKER_COMPOSE) restart $(SERVICE)

# Tear down all containers and delete all volumes
.PHONY: docker-purge
docker-purge: .env
$(DOCKER_COMPOSE) down --remove-orphans --volumes
$(TESTING_DOCKER_COMPOSE) down --remove-orphans --volumes

# Build the Docker image for the flask service
.PHONY: docker-build
docker-build: .env
$(DOCKER_COMPOSE) build flask

# Force a rebuild of all images (including pulling the base images)
.PHONY: docker-rebuild
docker-rebuild: .env
$(DOCKER_COMPOSE) build --no-cache --pull flask

# Pull all images except for locally built images
.PHONY: docker-pull
docker-pull: .env
$(DOCKER_COMPOSE) pull --ignore-buildable

# Show application logs, optionally with `make docker-logs SERVICE=flask` only for specified containers
.PHONY: docker-logs
docker-logs: .env
$(DOCKER_COMPOSE) logs -f $(SERVICE)

# Run arbitrary commands in the flask docker container
.PHONY: docker-run
docker-run: config
@test -n "$(CMD)" || ( echo 'Usage: make docker-run CMD="insert command here"'; exit 1 )
$(FLASK_RUN) $(CMD)

# Start a shell (bash) in the flask docker container
.PHONY: docker-shell
docker-shell: config
$(FLASK_RUN) bash

# Start an interactive Python shell with Flask application context in a docker container
.PHONY: flask-shell
flask-shell: config
$(FLASK_RUN) flask shell


# Database management
# -------------------

# Runs database migrations to upgrade the database to the current version (with "migrate" as an shorter alias)
.PHONY: apply-migrations migrate
migrate: apply-migrations
apply-migrations: config
$(FLASK_RUN) flask db upgrade

# Runs database migrations to DOWNGRADE the database to the previous version
.PHONY: downgrade-migrations
downgrade-migrations: config
$(FLASK_RUN) flask db downgrade

# Auto-generates a new database migration (requires a revision message as MSG)
.PHONY: generate-migration
generate-migration: config
@test -n "$(MSG)" || ( echo 'Usage: make generate-migration MSG="Example revision message"'; exit 1 )
$(FLASK_RUN) flask db migrate -m "$(MSG)"


# Cleanup
# -------

# Clean up "volatile" files (caches, test reports, venv, generated assets, ...)
.PHONY: clean
clean: docker-down
rm -rf node_modules/ logs/ venv/ static/js/ static/webpack-assets.json reports/ .pytest_cache .coverage .npm

# Clean up whole environment (like "clean", but also removes config files and database files)
.PHONY: clean-all
clean-all: docker-purge clean
rm config.yaml .env


# Test suites
# -----------

# Run unit tests only
.PHONY: test
test: test-unit

# Run all test suites (unit and integration tests)
.PHONY: test-all
test-all: test-unit test-integration

# Run unit tests only and generate coverage report in HTML format
.PHONY: test-unit
test-unit: config
$(FLASK_RUN) python -m pytest tests/unit --cov=webapp --cov-report=html

# Run integration tests in a separate environment
.PHONY: test-integration
test-integration: config
$(TESTING_DOCKER_COMPOSE) run --rm flask python -m pytest tests/integration
$(TESTING_DOCKER_COMPOSE) down

# Open coverage report in browser (determined by BROWSER env variable, defaults to firefox)
.PHONY: open-coverage
open-coverage:
@test -f ./reports/coverage_html/index.html || make test-unit
$(or $(BROWSER),firefox) ./reports/coverage_html/index.html


.PHONY: lint-fix
lint-fix:
$(FLASK_RUN) ruff --exclude webapp/converters --fix ./webapp
$(FLASK_RUN) black ./webapp

.PHONY: lint-check
lint-check:

$(FLASK_RUN) ruff --exclude webapp/converter ./webapp
$(FLASK_RUN) black -S --check --diff webapp
1 change: 1 addition & 0 deletions README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
# ParkAPI v3
Loading

0 comments on commit ac2ba67

Please sign in to comment.