Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .env
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
PYTHON_VERSION=3.13
33 changes: 33 additions & 0 deletions .github/workflows/ci.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,33 @@
name: CI

on:
push:
paths:
- '**/*.py'
- '**/*.html'
- '**/*.yaml'
- '**/*.yml'
- requirements*.txt
pull_request:
paths:
- '**/*.py'
- '**/*.html'
- '**/*.yaml'
- '**/*.yml'
- requirements*.txt

jobs:
test:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install dependencies
run: make dev
- name: Run pylint
run: make lint
- name: Run tests
run: make test
43 changes: 43 additions & 0 deletions .github/workflows/publish.yml
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
name: Publish package

on:
push:
tags:
- 'v*'
- 'test-v*'
workflow_dispatch:

permissions:
contents: read

jobs:
build:
runs-on: ubuntu-latest
steps:
- uses: actions/checkout@v4
- name: Set up Python
uses: actions/setup-python@v5
with:
python-version: '3.13'
- name: Install build tools
run: |
python -m pip install --upgrade pip
python -m pip install build twine
- name: Build package
run: |
python -m build
- name: Publish to PyPI
if: startsWith(github.ref, 'refs/tags/v')
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.PYPI_API_TOKEN }}
skip-existing: true
- name: Publish to TestPyPI
if: startsWith(github.ref, 'refs/tags/test-v')
uses: pypa/gh-action-pypi-publish@release/v1
with:
user: __token__
password: ${{ secrets.TEST_PYPI_API_TOKEN }}
repository-url: https://test.pypi.org/legacy/
skip-existing: true
11 changes: 11 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
# Python cache and bytecode
__pycache__/

# Virtual environments
.dev-venv/

# Test and coverage outputs
.coverage
coverage.xml

.vscode/
9 changes: 9 additions & 0 deletions .trunk/.gitignore
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
*out
*logs
*actions
*notifications
*tools
plugins
user_trunk.yaml
user.yaml
tmp
4 changes: 4 additions & 0 deletions .trunk/configs/.hadolint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
# Following source doesn't work in most setups
ignored:
- SC1090
- SC1091
2 changes: 2 additions & 0 deletions .trunk/configs/.isort.cfg
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
[settings]
profile=black
2 changes: 2 additions & 0 deletions .trunk/configs/.markdownlint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
# Prettier friendly markdownlint config (all formatting rules disabled)
extends: markdownlint/style/prettier
7 changes: 7 additions & 0 deletions .trunk/configs/.yamllint.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,7 @@
rules:
quoted-strings:
required: only-when-needed
extra-allowed: ["{|}"]
key-duplicates: {}
octal-values:
forbid-implicit-octal: true
6 changes: 6 additions & 0 deletions .trunk/configs/ruff.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1,6 @@
# Generic, formatter-friendly config.
[lint]
select = ["B", "D3", "E", "F"]

# Never enforce `E501` (line length violations). This should be handled by formatters.
ignore = ["E501"]
32 changes: 32 additions & 0 deletions .trunk/trunk.yaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
# This file controls the behavior of Trunk: https://docs.trunk.io/cli
# To learn more about the format of this file, see https://docs.trunk.io/reference/trunk-yaml
version: 0.1
cli:
version: 1.24.0
# Trunk provides extensibility via plugins. (https://docs.trunk.io/plugins)
plugins:
sources:
- id: trunk
ref: v1.7.1
uri: https://github.com/trunk-io/plugins
# Many linters and tools depend on runtimes - configure them here. (https://docs.trunk.io/runtimes)
runtimes:
enabled:
- node@22.16.0
- python@3.10.8
# This is the section where you manage your linters. (https://docs.trunk.io/check/configuration)
lint:
enabled:
- actionlint@1.7.7
- bandit@1.8.5
- black@25.1.0
- checkov@3.2.446
- git-diff-check
- hadolint@2.12.1-beta
- isort@6.0.1
- markdownlint@0.45.0
- osv-scanner@2.0.3
- prettier@3.6.0
- taplo@0.9.3
- trufflehog@3.89.2
- yamllint@1.37.1
15 changes: 15 additions & 0 deletions Dockerfile
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@

ARG PYTHON_VERSION=3.13
FROM python:${PYTHON_VERSION}-slim

ENV PYTHONUNBUFFERED=1

WORKDIR /app

COPY requirements-demo.txt .
RUN pip install --no-cache-dir -r requirements-demo.txt \
&& playwright install --with-deps chromium || true

COPY . .

CMD ["uvicorn", "demo.main:app", "--host", "0.0.0.0", "--port", "8000"]
3 changes: 3 additions & 0 deletions MANIFEST.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
include README.md
include LICENSE
recursive-include pyformatic/templates *.html
51 changes: 51 additions & 0 deletions Makefile
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
.PHONY: venv deps-txt-update dev-venv run build test test-docker
.ONESHELL:

ENV_FILE := $(realpath .env)
ENV_VARS := $(shell set -a && . $(ENV_FILE) && env | grep '=')
$(foreach v,$(ENV_VARS),$(eval export $(v)))

IMAGE ?= pyformatic-demo

venv:
python${PYTHON_VERSION} -m venv .dev-venv

deps-update: venv
.dev-venv/bin/pip3 install --upgrade pip
.dev-venv/bin/pip3 install pip-tools
.dev-venv/bin/pip-compile -r -v --all-extras --upgrade --emit-find-links \
--cache-dir .dev-venv/.cache/pip-tools --resolver backtracking --emit-index-url \
--color requirements.in
.dev-venv/bin/pip-compile -r -v --all-extras --upgrade --emit-find-links \
--cache-dir .dev-venv/.cache/pip-tools --resolver backtracking --emit-index-url \
--color requirements-demo.in
.dev-venv/bin/pip-compile -r -v --all-extras --upgrade --emit-find-links \
--cache-dir .dev-venv/.cache/pip-tools --resolver backtracking --emit-index-url \
--color requirements-dev.in

dev: venv
.dev-venv/bin/pip3 install --upgrade pip
.dev-venv/bin/pip3 --cache-dir .dev-venv/.cache/pip-tools install -r requirements-dev.txt
.dev-venv/bin/playwright install

build:
docker build -t $(IMAGE) .

run: build
docker compose up

test-docker: build
docker compose up -d
docker compose exec demo pytest -vv
docker compose down

test: dev
.dev-venv/bin/uvicorn demo.main:app --host 127.0.0.1 --port 8000 & \
server_pid=$$!; \
sleep 2; \
PYTHONPATH=. DEMO_BASE_URL=http://127.0.0.1:8000 .dev-venv/bin/pytest -v --tb=short --color=yes --cov=pyformatic --cov-report=xml --cov-report=term; \
kill $$server_pid && sleep 1; \
echo "Tests completed."

lint: dev
.dev-venv/bin/pylint --fail-under=9.5 pyformatic tests demo
Loading