From 176bd18e54862e33594e1ddb7358bfd18fc1243c Mon Sep 17 00:00:00 2001 From: George Hickman Date: Tue, 31 Oct 2023 09:45:00 +0000 Subject: [PATCH] Initial commit --- .dockerignore | 14 + .github/dependabot.yml | 13 + .../workflows/auto-merge-dependabot-prs.yml | 9 + .github/workflows/main.yml | 40 +++ .gitignore | 104 ++++++++ .pre-commit-config.yaml | 35 +++ DEVELOPERS.md | 34 +++ Dockerfile | 3 + LICENSE | 15 ++ README.md | 29 +++ justfile | 168 ++++++++++++ pyproject.toml | 46 ++++ requirements.dev.in | 13 + requirements.dev.txt | 240 ++++++++++++++++++ requirements.prod.in | 4 + requirements.prod.txt | 6 + tests/__init__.py | 0 17 files changed, 773 insertions(+) create mode 100644 .dockerignore create mode 100644 .github/dependabot.yml create mode 100644 .github/workflows/auto-merge-dependabot-prs.yml create mode 100644 .github/workflows/main.yml create mode 100644 .gitignore create mode 100644 .pre-commit-config.yaml create mode 100644 DEVELOPERS.md create mode 100644 Dockerfile create mode 100644 LICENSE create mode 100644 README.md create mode 100644 justfile create mode 100644 pyproject.toml create mode 100644 requirements.dev.in create mode 100644 requirements.dev.txt create mode 100644 requirements.prod.in create mode 100644 requirements.prod.txt create mode 100644 tests/__init__.py diff --git a/.dockerignore b/.dockerignore new file mode 100644 index 00000000..ecf9ad20 --- /dev/null +++ b/.dockerignore @@ -0,0 +1,14 @@ +.git/ + +**/*~ +**/.#* +**/*# +**/htmlcov +**/__pycache__ +**/*.pyc +**/.python-version +**/.env +**/.venv +**/venv +**/.coverage +**/*.egg-info/ diff --git a/.github/dependabot.yml b/.github/dependabot.yml new file mode 100644 index 00000000..5a60f87a --- /dev/null +++ b/.github/dependabot.yml @@ -0,0 +1,13 @@ +version: 2 + +updates: + - package-ecosystem: "pip" + directory: "/" + schedule: + interval: "weekly" + open-pull-requests-limit: 20 + + - package-ecosystem: "github-actions" + directory: "/" + schedule: + interval: "monthly" diff --git a/.github/workflows/auto-merge-dependabot-prs.yml b/.github/workflows/auto-merge-dependabot-prs.yml new file mode 100644 index 00000000..7b01deac --- /dev/null +++ b/.github/workflows/auto-merge-dependabot-prs.yml @@ -0,0 +1,9 @@ +name: Auto merge Dependabot PRs + +on: pull_request + +jobs: + auto-merge-dependabot-prs: + uses: opensafely-core/.github/.github/workflows/auto-merge-dependabot-prs.yml@main + secrets: + token: ${{ secrets.GITHUB_TOKEN }} diff --git a/.github/workflows/main.yml b/.github/workflows/main.yml new file mode 100644 index 00000000..b55dce0d --- /dev/null +++ b/.github/workflows/main.yml @@ -0,0 +1,40 @@ +--- +name: CI + +on: + push: + +jobs: + check: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: "opensafely-core/setup-action@v1" + with: + python-version: "3.11" + install-just: true + - name: Check formatting, linting and import sorting + run: just check + + test: + runs-on: ubuntu-latest + + steps: + - uses: actions/checkout@v4 + - uses: "opensafely-core/setup-action@v1" + with: + python-version: "3.11" + install-just: true + - name: Run tests +# env: # Add environment variables required for tests + run: | + just test + + lint-dockerfile: + runs-on: ubuntu-latest + steps: + - uses: actions/checkout@v4 + - uses: hadolint/hadolint-action@54c9adbab1582c2ef04b2016b760714a4bfde3cf # v3.1.0 + with: + failure-threshold: error diff --git a/.gitignore b/.gitignore new file mode 100644 index 00000000..13b2aaa4 --- /dev/null +++ b/.gitignore @@ -0,0 +1,104 @@ +# Created by https://www.toptal.com/developers/gitignore/api/osx,macos,linux,windows +# Edit at https://www.toptal.com/developers/gitignore?templates=osx,macos,linux,windows + +### Linux ### +*~ + +# temporary files which can be created if a process still has a handle open of a deleted file +.fuse_hidden* + +# KDE directory preferences +.directory + +# Linux trash folder which might appear on any partition or disk +.Trash-* + +# .nfs files are created when an open file is removed but is still being accessed +.nfs* + +### macOS ### +# General +.DS_Store +.AppleDouble +.LSOverride + +# Icon must end with two \r +Icon + + +# Thumbnails +._* + +# Files that might appear in the root of a volume +.DocumentRevisions-V100 +.fseventsd +.Spotlight-V100 +.TemporaryItems +.Trashes +.VolumeIcon.icns +.com.apple.timemachine.donotpresent + +# Directories potentially created on remote AFP share +.AppleDB +.AppleDesktop +Network Trash Folder +Temporary Items +.apdisk + +### OSX ### +# General + +# Icon must end with two \r + +# Thumbnails + +# Files that might appear in the root of a volume + +# Directories potentially created on remote AFP share + +### Windows ### +# Windows thumbnail cache files +Thumbs.db +Thumbs.db:encryptable +ehthumbs.db +ehthumbs_vista.db + +# Dump file +*.stackdump + +# Folder config file +[Dd]esktop.ini + +# Recycle Bin used on file shares +$RECYCLE.BIN/ + +# Windows Installer files +*.cab +*.msi +*.msix +*.msm +*.msp + +# Windows shortcuts +*.lnk + +# End of https://www.toptal.com/developers/gitignore/api/osx,macos,linux,windows + +# Python +__pycache__ +.python-version +*.pyc + +# Coverage +.coverage +htmlcov + +# IDEs +.idea/ + + +# Virtual environments +.venv/ +venv/ + +.pytest-cache/ diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml new file mode 100644 index 00000000..a9dd67e9 --- /dev/null +++ b/.pre-commit-config.yaml @@ -0,0 +1,35 @@ +default_language_version: + python: python3.11 + +repos: + - repo: local + hooks: + - id: black + name: black + entry: just black + language: system + types: [python] + require_serial: true + - id: ruff + name: ruff + entry: just ruff + language: system + types: [python] + require_serial: true + + - repo: https://github.com/pre-commit/pre-commit-hooks + rev: v4.1.0 + hooks: + - id: trailing-whitespace + - id: end-of-file-fixer + - id: debug-statements + - id: check-ast + - id: check-json + - id: check-toml + - id: check-yaml + - id: detect-private-key + + - repo: https://github.com/stratasan/hadolint-pre-commit + rev: cdefcb0 + hooks: + - id: hadolint diff --git a/DEVELOPERS.md b/DEVELOPERS.md new file mode 100644 index 00000000..c955e07d --- /dev/null +++ b/DEVELOPERS.md @@ -0,0 +1,34 @@ +# Notes for developers + +## System requirements + +### just + +```sh +# macOS +brew install just + +# Linux +# Install from https://github.com/casey/just/releases + +# Add completion for your shell. E.g. for bash: +source <(just --completions bash) + +# Show all available commands +just # shortcut for just --list +``` + + +## Local development environment + + +Set up a local development environment with: +``` +just dev_setup +``` + +## Tests +Run the tests with: +``` +just test +``` diff --git a/Dockerfile b/Dockerfile new file mode 100644 index 00000000..a8888250 --- /dev/null +++ b/Dockerfile @@ -0,0 +1,3 @@ +# All Dockerfiles should start from this base image +# Provide the TAG environment variable, or replace with the image version required +FROM ghcr.io/opensafely-core/base-docker:$TAG diff --git a/LICENSE b/LICENSE new file mode 100644 index 00000000..c7901370 --- /dev/null +++ b/LICENSE @@ -0,0 +1,15 @@ +${GITHUB_REPOSITORY_NAME} +Copyright (C) University of Oxford + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . diff --git a/README.md b/README.md new file mode 100644 index 00000000..46ad3153 --- /dev/null +++ b/README.md @@ -0,0 +1,29 @@ +# metrics + +This is a template for an OpenSAFELY Core repository. + +Put your project description here. + +New repo checklist: +- [ ] Does the repo require a Dockerfile? + If not, delete: + - Dockerfile - + - .dockerignore + - hadolint pre-commit hook from `.pre-commit-config.yaml` + - `lint-dockerfile` action from `.github/workflows/main.yml` +- [ ] Is this a Django project? + If so, you probably need to add the following per-file ignores to `.flake8` + ``` + per-file-ignores = + manage.py:INP001 + gunicorn.conf.py:INP001 + ``` +- [ ] Will this project be installed with pip? + If so, delete `requirements.prod.in` and switch references in the `justfile` to `pyproject.toml` +- [ ] Update DEVELOPERS.md with any project-specific requirements and commands +- [ ] Update commands in `justfile` + + +## Developer docs + +Please see the [additional information](DEVELOPERS.md). diff --git a/justfile b/justfile new file mode 100644 index 00000000..982695ee --- /dev/null +++ b/justfile @@ -0,0 +1,168 @@ +export VIRTUAL_ENV := env_var_or_default("VIRTUAL_ENV", ".venv") + +export BIN := VIRTUAL_ENV + if os_family() == "unix" { "/bin" } else { "/Scripts" } +export PIP := BIN + if os_family() == "unix" { "/python -m pip" } else { "/python.exe -m pip" } + +export DEFAULT_PYTHON := if os_family() == "unix" { "python3.11" } else { "python" } + + +# list available commands +default: + @"{{ just_executable() }}" --list + + +# clean up temporary files +clean: + rm -rf .venv + + +# ensure valid virtualenv +virtualenv: + #!/usr/bin/env bash + set -euo pipefail + + # allow users to specify python version in .env + PYTHON_VERSION=${PYTHON_VERSION:-$DEFAULT_PYTHON} + + # create venv and upgrade pip + test -d $VIRTUAL_ENV || { $PYTHON_VERSION -m venv $VIRTUAL_ENV && $PIP install --upgrade pip; } + + # ensure we have pip-tools so we can run pip-compile + test -e $BIN/pip-compile || $PIP install pip-tools + + +_compile src dst *args: virtualenv + #!/usr/bin/env bash + set -euo pipefail + + # exit if src file is older than dst file (-nt = 'newer than', but we negate with || to avoid error exit code) + test "${FORCE:-}" = "true" -o {{ src }} -nt {{ dst }} || exit 0 + $BIN/pip-compile --allow-unsafe --generate-hashes --output-file={{ dst }} {{ src }} {{ args }} + + +# update requirements.prod.txt if requirements.prod.in has changed +requirements-prod *args: + "{{ just_executable() }}" _compile requirements.prod.in requirements.prod.txt {{ args }} + + +# update requirements.dev.txt if requirements.dev.in has changed +requirements-dev *args: requirements-prod + "{{ just_executable() }}" _compile requirements.dev.in requirements.dev.txt {{ args }} + + +# ensure prod requirements installed and up to date +prodenv: requirements-prod + #!/usr/bin/env bash + set -euo pipefail + + # exit if .txt file has not changed since we installed them (-nt == "newer than', but we negate with || to avoid error exit code) + test requirements.prod.txt -nt $VIRTUAL_ENV/.prod || exit 0 + + $PIP install -r requirements.prod.txt + touch $VIRTUAL_ENV/.prod + + +# && dependencies are run after the recipe has run. Needs just>=0.9.9. This is +# a killer feature over Makefiles. +# +# ensure dev requirements installed and up to date +devenv: prodenv requirements-dev && install-precommit + #!/usr/bin/env bash + set -euo pipefail + + # exit if .txt file has not changed since we installed them (-nt == "newer than', but we negate with || to avoid error exit code) + test requirements.dev.txt -nt $VIRTUAL_ENV/.dev || exit 0 + + $PIP install -r requirements.dev.txt + touch $VIRTUAL_ENV/.dev + + +# ensure precommit is installed +install-precommit: + #!/usr/bin/env bash + set -euo pipefail + + BASE_DIR=$(git rev-parse --show-toplevel) + test -f $BASE_DIR/.git/hooks/pre-commit || $BIN/pre-commit install + + +# upgrade dev or prod dependencies (specify package to upgrade single package, all by default) +upgrade env package="": virtualenv + #!/usr/bin/env bash + set -euo pipefail + + opts="--upgrade" + test -z "{{ package }}" || opts="--upgrade-package {{ package }}" + FORCE=true "{{ just_executable() }}" requirements-{{ env }} $opts + + +# *args is variadic, 0 or more. This allows us to do `just test -k match`, for example. +# Run the tests +test *args: devenv + $BIN/coverage run --module pytest {{ args }} + $BIN/coverage report || $BIN/coverage html + + +black *args=".": devenv + $BIN/black --check {{ args }} + +ruff *args=".": devenv + $BIN/ruff check {{ args }} + +# run the various dev checks but does not change any files +check: black ruff + + +# fix formatting and import sort ordering +fix: devenv + $BIN/black . + $BIN/ruff --fix . + + +# Run the dev project +run: devenv + echo "Not implemented yet" + + + +# Remove built assets and collected static files +assets-clean: + rm -rf assets/dist + rm -rf staticfiles + + +# Install the Node.js dependencies +assets-install: + #!/usr/bin/env bash + set -euo pipefail + + # exit if lock file has not changed since we installed them. -nt == "newer than", + # but we negate with || to avoid error exit code + test package-lock.json -nt node_modules/.written || exit 0 + + npm ci + touch node_modules/.written + + +# Build the Node.js assets +assets-build: + #!/usr/bin/env bash + set -euo pipefail + + # find files which are newer than dist/.written in the src directory. grep + # will exit with 1 if there are no files in the result. We negate this + # with || to avoid error exit code + # we wrap the find in an if in case dist/.written is missing so we don't + # trigger a failure prematurely + if test -f assets/dist/.written; then + find assets/src -type f -newer assets/dist/.written | grep -q . || exit 0 + fi + + npm run build + touch assets/dist/.written + + +assets: assets-install assets-build + + +assets-rebuild: assets-clean assets diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..02730826 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,46 @@ +[tool.coverage.run] +branch = true +dynamic_context = "test_function" +omit = [ + ".venv/*", +] + +[tool.coverage.report] +fail_under = 100 +skip_covered = true +show_missing = true + +[tool.coverage.html] +show_contexts = true + +[tool.pytest.ini_options] + +[tool.ruff] +line-length = 88 +exclude = [ + ".direnv", + ".git", + ".github", + ".ipynb_checkpoints", + ".pytest_cache", + ".venv", + "__pycache__", + "docker", + "htmlcov", + "venv", +] +extend-select = [ + "A", # flake8-builtins + "I", # isort + "INP", # flake8-no-pep420 + "ISC", # flake8-implicit-str-concat + "UP", # pyupgrade + "W", # pycodestyle warning +] +extend-ignore = [ + "E501", + "E731", +] + +[tool.ruff.isort] +lines-after-imports = 2 diff --git a/requirements.dev.in b/requirements.dev.in new file mode 100644 index 00000000..a0d01151 --- /dev/null +++ b/requirements.dev.in @@ -0,0 +1,13 @@ +--constraint requirements.prod.txt + +# Additional dev requirements +# To generate a requirements file that includes both prod and dev requirements, run: +# pip-compile --generate-hashes --output-file=requirements.dev.txt requirements.dev.in + +black +coverage +pip-tools +pre-commit +pytest +pyyaml==6.0.1 +ruff diff --git a/requirements.dev.txt b/requirements.dev.txt new file mode 100644 index 00000000..1ebdd3e5 --- /dev/null +++ b/requirements.dev.txt @@ -0,0 +1,240 @@ +# +# This file is autogenerated by pip-compile with Python 3.11 +# by the following command: +# +# pip-compile --allow-unsafe --generate-hashes --output-file=requirements.dev.txt requirements.dev.in +# +black==23.10.1 \ + --hash=sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884 \ + --hash=sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916 \ + --hash=sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258 \ + --hash=sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1 \ + --hash=sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce \ + --hash=sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d \ + --hash=sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982 \ + --hash=sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7 \ + --hash=sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173 \ + --hash=sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9 \ + --hash=sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb \ + --hash=sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad \ + --hash=sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc \ + --hash=sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0 \ + --hash=sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a \ + --hash=sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe \ + --hash=sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace \ + --hash=sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69 + # via -r requirements.dev.in +build==0.8.0 \ + --hash=sha256:19b0ed489f92ace6947698c3ca8436cb0556a66e2aa2d34cd70e2a5d27cd0437 \ + --hash=sha256:887a6d471c901b1a6e6574ebaeeebb45e5269a79d095fe9a8f88d6614ed2e5f0 + # via pip-tools +cfgv==3.3.0 \ + --hash=sha256:9e600479b3b99e8af981ecdfc80a0296104ee610cab48a5ae4ffd0b668650eb1 \ + --hash=sha256:b449c9c6118fe8cca7fa5e00b9ec60ba08145d281d52164230a69211c5d597a1 + # via pre-commit +click==8.0.1 \ + --hash=sha256:8c04c11192119b1ef78ea049e0a6f0463e4c48ef00a30160c704337586f3ad7a \ + --hash=sha256:fba402a4a47334742d782209a7c79bc448911afe1149d07bdabdf480b3e2f4b6 + # via + # black + # pip-tools +coverage==7.3.2 \ + --hash=sha256:0cbf38419fb1a347aaf63481c00f0bdc86889d9fbf3f25109cf96c26b403fda1 \ + --hash=sha256:12d15ab5833a997716d76f2ac1e4b4d536814fc213c85ca72756c19e5a6b3d63 \ + --hash=sha256:149de1d2401ae4655c436a3dced6dd153f4c3309f599c3d4bd97ab172eaf02d9 \ + --hash=sha256:1981f785239e4e39e6444c63a98da3a1db8e971cb9ceb50a945ba6296b43f312 \ + --hash=sha256:2443cbda35df0d35dcfb9bf8f3c02c57c1d6111169e3c85fc1fcc05e0c9f39a3 \ + --hash=sha256:289fe43bf45a575e3ab10b26d7b6f2ddb9ee2dba447499f5401cfb5ecb8196bb \ + --hash=sha256:2f11cc3c967a09d3695d2a6f03fb3e6236622b93be7a4b5dc09166a861be6d25 \ + --hash=sha256:307adb8bd3abe389a471e649038a71b4eb13bfd6b7dd9a129fa856f5c695cf92 \ + --hash=sha256:310b3bb9c91ea66d59c53fa4989f57d2436e08f18fb2f421a1b0b6b8cc7fffda \ + --hash=sha256:315a989e861031334d7bee1f9113c8770472db2ac484e5b8c3173428360a9148 \ + --hash=sha256:3a4006916aa6fee7cd38db3bfc95aa9c54ebb4ffbfc47c677c8bba949ceba0a6 \ + --hash=sha256:3c7bba973ebee5e56fe9251300c00f1579652587a9f4a5ed8404b15a0471f216 \ + --hash=sha256:4175e10cc8dda0265653e8714b3174430b07c1dca8957f4966cbd6c2b1b8065a \ + --hash=sha256:43668cabd5ca8258f5954f27a3aaf78757e6acf13c17604d89648ecc0cc66640 \ + --hash=sha256:4cbae1051ab791debecc4a5dcc4a1ff45fc27b91b9aee165c8a27514dd160836 \ + --hash=sha256:5c913b556a116b8d5f6ef834038ba983834d887d82187c8f73dec21049abd65c \ + --hash=sha256:5f7363d3b6a1119ef05015959ca24a9afc0ea8a02c687fe7e2d557705375c01f \ + --hash=sha256:630b13e3036e13c7adc480ca42fa7afc2a5d938081d28e20903cf7fd687872e2 \ + --hash=sha256:72c0cfa5250f483181e677ebc97133ea1ab3eb68645e494775deb6a7f6f83901 \ + --hash=sha256:7dbc3ed60e8659bc59b6b304b43ff9c3ed858da2839c78b804973f613d3e92ed \ + --hash=sha256:88ed2c30a49ea81ea3b7f172e0269c182a44c236eb394718f976239892c0a27a \ + --hash=sha256:89a937174104339e3a3ffcf9f446c00e3a806c28b1841c63edb2b369310fd074 \ + --hash=sha256:9028a3871280110d6e1aa2df1afd5ef003bab5fb1ef421d6dc748ae1c8ef2ebc \ + --hash=sha256:99b89d9f76070237975b315b3d5f4d6956ae354a4c92ac2388a5695516e47c84 \ + --hash=sha256:9f805d62aec8eb92bab5b61c0f07329275b6f41c97d80e847b03eb894f38d083 \ + --hash=sha256:a889ae02f43aa45032afe364c8ae84ad3c54828c2faa44f3bfcafecb5c96b02f \ + --hash=sha256:aa72dbaf2c2068404b9870d93436e6d23addd8bbe9295f49cbca83f6e278179c \ + --hash=sha256:ac8c802fa29843a72d32ec56d0ca792ad15a302b28ca6203389afe21f8fa062c \ + --hash=sha256:ae97af89f0fbf373400970c0a21eef5aa941ffeed90aee43650b81f7d7f47637 \ + --hash=sha256:af3d828d2c1cbae52d34bdbb22fcd94d1ce715d95f1a012354a75e5913f1bda2 \ + --hash=sha256:b4275802d16882cf9c8b3d057a0839acb07ee9379fa2749eca54efbce1535b82 \ + --hash=sha256:b4767da59464bb593c07afceaddea61b154136300881844768037fd5e859353f \ + --hash=sha256:b631c92dfe601adf8f5ebc7fc13ced6bb6e9609b19d9a8cd59fa47c4186ad1ce \ + --hash=sha256:be32ad29341b0170e795ca590e1c07e81fc061cb5b10c74ce7203491484404ef \ + --hash=sha256:beaa5c1b4777f03fc63dfd2a6bd820f73f036bfb10e925fce067b00a340d0f3f \ + --hash=sha256:c0ba320de3fb8c6ec16e0be17ee1d3d69adcda99406c43c0409cb5c41788a611 \ + --hash=sha256:c9eacf273e885b02a0273bb3a2170f30e2d53a6d53b72dbe02d6701b5296101c \ + --hash=sha256:cb536f0dcd14149425996821a168f6e269d7dcd2c273a8bff8201e79f5104e76 \ + --hash=sha256:d1bc430677773397f64a5c88cb522ea43175ff16f8bfcc89d467d974cb2274f9 \ + --hash=sha256:d1c88ec1a7ff4ebca0219f5b1ef863451d828cccf889c173e1253aa84b1e07ce \ + --hash=sha256:d3d9df4051c4a7d13036524b66ecf7a7537d14c18a384043f30a303b146164e9 \ + --hash=sha256:d51ac2a26f71da1b57f2dc81d0e108b6ab177e7d30e774db90675467c847bbdf \ + --hash=sha256:d872145f3a3231a5f20fd48500274d7df222e291d90baa2026cc5152b7ce86bf \ + --hash=sha256:d8f17966e861ff97305e0801134e69db33b143bbfb36436efb9cfff6ec7b2fd9 \ + --hash=sha256:dbc1b46b92186cc8074fee9d9fbb97a9dd06c6cbbef391c2f59d80eabdf0faa6 \ + --hash=sha256:e10c39c0452bf6e694511c901426d6b5ac005acc0f78ff265dbe36bf81f808a2 \ + --hash=sha256:e267e9e2b574a176ddb983399dec325a80dbe161f1a32715c780b5d14b5f583a \ + --hash=sha256:f47d39359e2c3779c5331fc740cf4bce6d9d680a7b4b4ead97056a0ae07cb49a \ + --hash=sha256:f6e9589bd04d0461a417562649522575d8752904d35c12907d8c9dfeba588faf \ + --hash=sha256:f94b734214ea6a36fe16e96a70d941af80ff3bfd716c141300d95ebc85339738 \ + --hash=sha256:fa28e909776dc69efb6ed975a63691bc8172b64ff357e663a1bb06ff3c9b589a \ + --hash=sha256:fe494faa90ce6381770746077243231e0b83ff3f17069d748f645617cefe19d4 + # via -r requirements.dev.in +distlib==0.3.6 \ + --hash=sha256:14bad2d9b04d3a36127ac97f30b12a19268f211063d8f8ee4f47108896e11b46 \ + --hash=sha256:f35c4b692542ca110de7ef0bea44d73981caeb34ca0b9b6b2e6d7790dda8f80e + # via virtualenv +filelock==3.9.0 \ + --hash=sha256:7b319f24340b51f55a2bf7a12ac0755a9b03e718311dac567a0f4f7fabd2f5de \ + --hash=sha256:f58d535af89bb9ad5cd4df046f741f8553a418c01a7856bf0d173bbc9f6bd16d + # via virtualenv +identify==2.2.11 \ + --hash=sha256:7abaecbb414e385752e8ce02d8c494f4fbc780c975074b46172598a28f1ab839 \ + --hash=sha256:a0e700637abcbd1caae58e0463861250095dfe330a8371733a471af706a4a29a + # via pre-commit +iniconfig==1.1.1 \ + --hash=sha256:011e24c64b7f47f6ebd835bb12a743f2fbe9a26d4cecaa7f53bc4f35ee9da8b3 \ + --hash=sha256:bc3af051d7d14b2ee5ef9969666def0cd1a000e121eaea580d4a313df4b37f32 + # via pytest +mypy-extensions==0.4.3 \ + --hash=sha256:090fedd75945a69ae91ce1303b5824f428daf5a028d2f6ab8a299250a846f15d \ + --hash=sha256:2d82818f5bb3e369420cb3c4060a7970edba416647068eb4c5343488a6c604a8 + # via black +nodeenv==1.6.0 \ + --hash=sha256:3ef13ff90291ba2a4a7a4ff9a979b63ffdd00a464dbe04acf0ea6471517a4c2b \ + --hash=sha256:621e6b7076565ddcacd2db0294c0381e01fd28945ab36bcf00f41c5daf63bef7 + # via pre-commit +packaging==23.0 \ + --hash=sha256:714ac14496c3e68c99c29b00845f7a2b85f3bb6f1078fd9f72fd20f0570002b2 \ + --hash=sha256:b6ad297f8907de0fa2fe1ccbd26fdaf387f5f47c7275fedf8cce89f99446cf97 + # via + # black + # build + # pytest +pathspec==0.9.0 \ + --hash=sha256:7d15c4ddb0b5c802d161efc417ec1a2558ea2653c2e8ad9c19098201dc1c993a \ + --hash=sha256:e564499435a2673d586f6b2130bb5b95f04a3ba06f81b8f895b651a3c76aabb1 + # via black +pep517==0.11.0 \ + --hash=sha256:3fa6b85b9def7ba4de99fb7f96fe3f02e2d630df8aa2720a5cf3b183f087a738 \ + --hash=sha256:e1ba5dffa3a131387979a68ff3e391ac7d645be409216b961bc2efe6468ab0b2 + # via build +pip-tools==7.3.0 \ + --hash=sha256:8717693288720a8c6ebd07149c93ab0be1fced0b5191df9e9decd3263e20d85e \ + --hash=sha256:8e9c99127fe024c025b46a0b2d15c7bd47f18f33226cf7330d35493663fc1d1d + # via -r requirements.dev.in +platformdirs==2.6.2 \ + --hash=sha256:83c8f6d04389165de7c9b6f0c682439697887bca0aa2f1c87ef1826be3584490 \ + --hash=sha256:e1fea1fe471b9ff8332e229df3cb7de4f53eeea4998d3b6bfff542115e998bd2 + # via + # black + # virtualenv +pluggy==0.13.1 \ + --hash=sha256:15b2acde666561e1298d71b523007ed7364de07029219b604cf808bfa1c765b0 \ + --hash=sha256:966c145cd83c96502c3c3868f50408687b38434af77734af1e9ca461a4081d2d + # via pytest +pre-commit==3.5.0 \ + --hash=sha256:5804465c675b659b0862f07907f96295d490822a450c4c40e747d0b1c6ebcb32 \ + --hash=sha256:841dc9aef25daba9a0238cd27984041fa0467b4199fc4852e27950664919f660 + # via -r requirements.dev.in +pytest==7.4.3 \ + --hash=sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac \ + --hash=sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5 + # via -r requirements.dev.in +pyyaml==6.0.1 \ + --hash=sha256:062582fca9fabdd2c8b54a3ef1c978d786e0f6b3a1510e0ac93ef59e0ddae2bc \ + --hash=sha256:1635fd110e8d85d55237ab316b5b011de701ea0f29d07611174a1b42f1444741 \ + --hash=sha256:184c5108a2aca3c5b3d3bf9395d50893a7ab82a38004c8f61c258d4428e80206 \ + --hash=sha256:18aeb1bf9a78867dc38b259769503436b7c72f7a1f1f4c93ff9a17de54319b27 \ + --hash=sha256:1d4c7e777c441b20e32f52bd377e0c409713e8bb1386e1099c2415f26e479595 \ + --hash=sha256:1e2722cc9fbb45d9b87631ac70924c11d3a401b2d7f410cc0e3bbf249f2dca62 \ + --hash=sha256:1fe35611261b29bd1de0070f0b2f47cb6ff71fa6595c077e42bd0c419fa27b98 \ + --hash=sha256:28c119d996beec18c05208a8bd78cbe4007878c6dd15091efb73a30e90539696 \ + --hash=sha256:42f8152b8dbc4fe7d96729ec2b99c7097d656dc1213a3229ca5383f973a5ed6d \ + --hash=sha256:4fb147e7a67ef577a588a0e2c17b6db51dda102c71de36f8549b6816a96e1867 \ + --hash=sha256:50550eb667afee136e9a77d6dc71ae76a44df8b3e51e41b77f6de2932bfe0f47 \ + --hash=sha256:510c9deebc5c0225e8c96813043e62b680ba2f9c50a08d3724c7f28a747d1486 \ + --hash=sha256:5773183b6446b2c99bb77e77595dd486303b4faab2b086e7b17bc6bef28865f6 \ + --hash=sha256:596106435fa6ad000c2991a98fa58eeb8656ef2325d7e158344fb33864ed87e3 \ + --hash=sha256:6965a7bc3cf88e5a1c3bd2e0b5c22f8d677dc88a455344035f03399034eb3007 \ + --hash=sha256:69b023b2b4daa7548bcfbd4aa3da05b3a74b772db9e23b982788168117739938 \ + --hash=sha256:704219a11b772aea0d8ecd7058d0082713c3562b4e271b849ad7dc4a5c90c13c \ + --hash=sha256:7e07cbde391ba96ab58e532ff4803f79c4129397514e1413a7dc761ccd755735 \ + --hash=sha256:81e0b275a9ecc9c0c0c07b4b90ba548307583c125f54d5b6946cfee6360c733d \ + --hash=sha256:9046c58c4395dff28dd494285c82ba00b546adfc7ef001486fbf0324bc174fba \ + --hash=sha256:9eb6caa9a297fc2c2fb8862bc5370d0303ddba53ba97e71f08023b6cd73d16a8 \ + --hash=sha256:a0cd17c15d3bb3fa06978b4e8958dcdc6e0174ccea823003a106c7d4d7899ac5 \ + --hash=sha256:afd7e57eddb1a54f0f1a974bc4391af8bcce0b444685d936840f125cf046d5bd \ + --hash=sha256:b1275ad35a5d18c62a7220633c913e1b42d44b46ee12554e5fd39c70a243d6a3 \ + --hash=sha256:b786eecbdf8499b9ca1d697215862083bd6d2a99965554781d0d8d1ad31e13a0 \ + --hash=sha256:ba336e390cd8e4d1739f42dfe9bb83a3cc2e80f567d8805e11b46f4a943f5515 \ + --hash=sha256:baa90d3f661d43131ca170712d903e6295d1f7a0f595074f151c0aed377c9b9c \ + --hash=sha256:bc1bf2925a1ecd43da378f4db9e4f799775d6367bdb94671027b73b393a7c42c \ + --hash=sha256:bd4af7373a854424dabd882decdc5579653d7868b8fb26dc7d0e99f823aa5924 \ + --hash=sha256:bf07ee2fef7014951eeb99f56f39c9bb4af143d8aa3c21b1677805985307da34 \ + --hash=sha256:bfdf460b1736c775f2ba9f6a92bca30bc2095067b8a9d77876d1fad6cc3b4a43 \ + --hash=sha256:c8098ddcc2a85b61647b2590f825f3db38891662cfc2fc776415143f599bb859 \ + --hash=sha256:d2b04aac4d386b172d5b9692e2d2da8de7bfb6c387fa4f801fbf6fb2e6ba4673 \ + --hash=sha256:d858aa552c999bc8a8d57426ed01e40bef403cd8ccdd0fc5f6f04a00414cac2a \ + --hash=sha256:f003ed9ad21d6a4713f0a9b5a7a0a79e08dd0f221aff4525a2be4c346ee60aab \ + --hash=sha256:f22ac1c3cac4dbc50079e965eba2c1058622631e526bd9afd45fedd49ba781fa \ + --hash=sha256:faca3bdcf85b2fc05d06ff3fbc1f83e1391b3e724afa3feba7d13eeab355484c \ + --hash=sha256:fca0e3a251908a499833aa292323f32437106001d436eca0e6e7833256674585 \ + --hash=sha256:fd1592b3fdf65fff2ad0004b5e363300ef59ced41c2e6b3a99d4089fa8c5435d \ + --hash=sha256:fd66fc5d0da6d9815ba2cebeb4205f95818ff4b79c3ebe268e75d961704af52f + # via + # -r requirements.dev.in + # pre-commit +ruff==0.1.3 \ + --hash=sha256:0b6c55f5ef8d9dd05b230bb6ab80bc4381ecb60ae56db0330f660ea240cb0d4a \ + --hash=sha256:0f75e670d529aa2288cd00fc0e9b9287603d95e1536d7a7e0cafe00f75e0dd9d \ + --hash=sha256:12fd53696c83a194a2db7f9a46337ce06445fb9aa7d25ea6f293cf75b21aca9f \ + --hash=sha256:1c595193881922cc0556a90f3af99b1c5681f0c552e7a2a189956141d8666fe8 \ + --hash=sha256:2e3de9ed2e39160800281848ff4670e1698037ca039bda7b9274f849258d26ce \ + --hash=sha256:3ba6145369a151401d5db79f0a47d50e470384d0d89d0d6f7fab0b589ad07c34 \ + --hash=sha256:3e7afcbdcfbe3399c34e0f6370c30f6e529193c731b885316c5a09c9e4317eef \ + --hash=sha256:4874c165f96c14a00590dcc727a04dca0cfd110334c24b039458c06cf78a672e \ + --hash=sha256:76dd49f6cd945d82d9d4a9a6622c54a994689d8d7b22fa1322983389b4892e20 \ + --hash=sha256:7a18df6638cec4a5bd75350639b2bb2a2366e01222825562c7346674bdceb7ea \ + --hash=sha256:918b454bc4f8874a616f0d725590277c42949431ceb303950e87fef7a7d94cb3 \ + --hash=sha256:b46d43d51f7061652eeadb426a9e3caa1e0002470229ab2fc19de8a7b0766901 \ + --hash=sha256:b8afeb9abd26b4029c72adc9921b8363374f4e7edb78385ffaa80278313a15f9 \ + --hash=sha256:ca3cf365bf32e9ba7e6db3f48a4d3e2c446cd19ebee04f05338bc3910114528b \ + --hash=sha256:d8859605e729cd5e53aa38275568dbbdb4fe882d2ea2714c5453b678dca83784 \ + --hash=sha256:dc3ec4edb3b73f21b4aa51337e16674c752f1d76a4a543af56d7d04e97769613 \ + --hash=sha256:eec2dd31eed114e48ea42dbffc443e9b7221976554a504767ceaee3dd38edeb8 + # via -r requirements.dev.in +tomli==1.1.0 \ + --hash=sha256:33d7984738f8bb699c9b0a816eb646a8178a69eaa792d258486776a5d21b8ca5 \ + --hash=sha256:f4a182048010e89cbec0ae4686b21f550a7f2903f665e34a6de58ec15424f919 + # via pep517 +virtualenv==20.17.1 \ + --hash=sha256:ce3b1684d6e1a20a3e5ed36795a97dfc6af29bc3970ca8dab93e11ac6094b3c4 \ + --hash=sha256:f8b927684efc6f1cc206c9db297a570ab9ad0e51c16fa9e45487d36d1905c058 + # via pre-commit +wheel==0.38.1 \ + --hash=sha256:7a95f9a8dc0924ef318bd55b616112c70903192f524d120acc614f59547a9e1f \ + --hash=sha256:ea041edf63f4ccba53ad6e035427997b3bb10ee88a4cd014ae82aeb9eea77bb9 + # via pip-tools + +# The following packages are considered to be unsafe in a requirements file: +pip==23.0.1 \ + --hash=sha256:236bcb61156d76c4b8a05821b988c7b8c35bf0da28a4b614e8d6ab5212c25c6f \ + --hash=sha256:cd015ea1bfb0fcef59d8a286c1f8bebcb983f6317719d415dc5351efb7cd7024 + # via pip-tools +setuptools==67.6.1 \ + --hash=sha256:257de92a9d50a60b8e22abfcbb771571fde0dbf3ec234463212027a4eeecbe9a \ + --hash=sha256:e728ca814a823bf7bf60162daf9db95b93d532948c4c0bea762ce62f60189078 + # via pip-tools diff --git a/requirements.prod.in b/requirements.prod.in new file mode 100644 index 00000000..06b80caa --- /dev/null +++ b/requirements.prod.in @@ -0,0 +1,4 @@ +# Main prod requirements + +# To generate requirements file, run: +# pip-compile --generate-hashes --output-file=requirements.prod.txt requirements.prod.in diff --git a/requirements.prod.txt b/requirements.prod.txt new file mode 100644 index 00000000..2a042f59 --- /dev/null +++ b/requirements.prod.txt @@ -0,0 +1,6 @@ +# +# This file is autogenerated by pip-compile with python 3.11 +# To update, run: +# +# pip-compile --allow-unsafe --generate-hashes --output-file=requirements.prod.txt requirements.prod.in +# diff --git a/tests/__init__.py b/tests/__init__.py new file mode 100644 index 00000000..e69de29b