Skip to content
Snippets Groups Projects

Compare revisions

Changes are shown as if the source revision was being merged into the target revision. Learn more about comparing revisions.

Source

Select target project
No results found
Select Git revision
Loading items

Target

Select target project
  • hub/hub
  • cyroxx/hub
  • myigel/hub
  • thomasdotwtf/hub
4 results
Select Git revision
Loading items
Show changes
Commits on Source (244)
......@@ -10,3 +10,9 @@ src/hub/.settings.secret
# local media files
src/media/
.tools/
.vscode/
.venv*/
**/*_cache
......@@ -13,5 +13,5 @@ trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.py]
[*.py, *.toml]
indent_size = 4
......@@ -83,15 +83,6 @@ db.sqlite3-journal
profile_default/
ipython_config.py
# pdm
# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control.
#pdm.lock
# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it
# in version control.
# https://pdm.fming.dev/#use-with-ide
.pdm.toml
.pdm-python
# Environments
.env
.venv
......
......@@ -29,10 +29,14 @@ workflow:
# Use build cache to speed up CI
default:
cache:
- key:
files:
- uv.lock
paths:
- $UV_CACHE_DIR
- key: "python-default"
paths:
- .cache/pip
- .cache/pdm
- key:
files:
- src/plainui/yarn.lock
......@@ -68,6 +72,7 @@ default:
POSTGRES_USER: ci
SSO_SECRET_GENERATE: "True"
STORAGE_TYPE: local
UV_CACHE_DIR: .uv-cache
# Kaniko build setup
.build:
......@@ -111,6 +116,8 @@ default:
"ci": true
}
EOF
after_script:
- uv cache prune --ci
# Crane setup
.crane:
......@@ -122,29 +129,32 @@ default:
before_script:
- '[ -n "$DOCKER_CONFIG" ] || export DOCKER_CONFIG=$HOME/.docker'
- crane auth login -u $CI_REGISTRY_USER -p $CI_REGISTRY_PASSWORD $CI_REGISTRY
meta_build:
stage: prepare
extends: .build
variables:
PIP_CACHE_DIR: "$CI_PROJECT_DIR/.cache/pip"
UV_CACHE_DIR: .uv-cache
script:
- /kaniko/executor
$KANIKO_ARGS
$KANIKO_CACHE_ARGS
--dockerfile $CI_PROJECT_DIR/Dockerfile
--target base
--destination $CI_REGISTRY_IMAGE/build_image:bi-$CI_PIPELINE_ID
--target meta
--destination $CI_REGISTRY_IMAGE/meta_image:mi-$CI_PIPELINE_ID
rules:
- when: always
.test:
extends:
- .django_runner_settings
image: $CI_REGISTRY_IMAGE/build_image:bi-$CI_PIPELINE_ID
image: $CI_REGISTRY_IMAGE/meta_image:mi-$CI_PIPELINE_ID
variables:
PDM_CACHE_DIR: .cache/pdm
UV_CACHE_DIR: .uv-cache
needs:
- meta_build
after_script:
- uv cache prune --ci
app_version:
stage: test
......@@ -155,8 +165,8 @@ app_version:
DATABASE_URL: "postgis://ci:runner@db_server/migrations"
script:
- python3 -V
- pdm sync -d --no-editable -G dev
- pdm app_version
- uv sync
- uv run task app_version
allow_failure: true
rules:
- when: always
......@@ -166,8 +176,7 @@ lint:
extends: .test
script:
- python3 -V
- pdm sync -d --no-editable -G dev
- pdm run lint
- tox -e py-lint,html-lint
allow_failure: true
rules:
- when: always
......@@ -177,8 +186,7 @@ format:
extends: .test
script:
- python3 -V
- pdm sync -d --no-editable -G dev
- pdm run format
- tox -e py-format,html-format
- git diff --exit-code -- . ':!src/version.json'
allow_failure: true
rules:
......@@ -191,11 +199,11 @@ format_prettier:
before_script:
- apk add --no-cache git
- corepack enable
- 'echo "cacheFolder: \".yarn/cache/\"" > .yarnrc.yml'
- 'echo "cacheFolder: \".yarn/cache/\"" >> .yarnrc.yml'
- yarn install --immutable
script:
- yarn format
- git diff --exit-code -- . ':!src/version.json'
- git diff --exit-code -- . ':!src/version.json' ':!.yarnrc.yml'
allow_failure: true
rules:
- when: always
......@@ -209,8 +217,8 @@ migration_check:
DATABASE_URL: "postgis://ci:runner@db_server/migrations"
script:
- python3 -V
- pdm sync -d --no-editable -G dev
- pdm run check-migrations
- uv run task manage makemigrations --check
- uv run task manage makemigrations --dry-run
translations_check:
stage: test
......@@ -222,8 +230,8 @@ translations_check:
allow_failure: true
script:
- python3 -V
- pdm install --no-editable --prod
- pdm manage makemessages
- uv sync
- uv run task manage makemessages
- git diff --exit-code -- . ':!src/version.json'
requirements_export:
......@@ -231,16 +239,16 @@ requirements_export:
extends: .test
script:
- python3 -V
- pdm lock --check
- pdm export --no-hashes -o requirements.txt --prod
- pdm export --no-hashes -o requirements.dev.txt --de
- uv lock --check
- uv export --frozen -o=requirements.dev.txt --no-hashes --all-groups
- uv export --frozen -o=requirements.txt --no-hashes --no-dev
- git diff --exit-code -- . ':!src/version.json'
rules:
- changes:
- requirements.txt
- requirements.dev.txt
- project.toml
- pdm.lock
- uv.lock
django-tests:
stage: test
......@@ -256,16 +264,18 @@ django-tests:
DATABASE_URL: "postgis://ci:runner@db_server/self_test"
script:
- python3 -V
- pdm sync -d --no-editable -G dev
- pdm run test
- pdm run coverage xml -i
- pdm run coverage report
- tox -e django-test
- tox -e coverage-report
coverage: '/(?i)total(?:\s+\d+){4}\s+(\d+)%/'
artifacts:
reports:
coverage_report:
coverage_format: cobertura
path: .tools/coverage/coverage.xml
path: .tools/coverage/report.xml
paths:
- .tools/coverage/html_report/
expire_in: 1 week
expose_as: "HTML Coverage Report"
build_nginx:
stage: build
......@@ -515,7 +525,7 @@ cleanup-ci-images:
- crane delete $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID}
- crane delete $CI_REGISTRY_IMAGE/ci/nginx:ci-${CI_PIPELINE_ID}
- crane delete $CI_REGISTRY_IMAGE/ci/hub:ci-${CI_PIPELINE_ID}-test
- crane delete $CI_REGISTRY_IMAGE/build_image:bi-$CI_PIPELINE_ID
- crane delete $CI_REGISTRY_IMAGE/meta_image:mi-$CI_PIPELINE_ID
needs:
- job: publish-production
optional: true
......
......@@ -9,7 +9,7 @@ repos:
- id: check-merge-conflict
- id: check-ast
- repo: https://github.com/astral-sh/ruff-pre-commit
rev: v0.8.0
rev: v0.9.7
hooks:
- id: ruff
args: [--fix]
......@@ -18,37 +18,40 @@ repos:
rev: v1.0.0
hooks:
- id: check-json5
- repo: https://github.com/pdm-project/pdm
rev: 2.20.1
hooks:
- name: check production requirements
id: pdm-export
args: ["-o", "requirements.txt", "--without-hashes", "--prod"]
files: ^pdm.lock$
- repo: https://github.com/pdm-project/pdm
rev: 2.20.1
hooks:
- name: check development requirements
id: pdm-export
args: ["-o", "requirements.dev.txt", "--without-hashes", "--dev"]
files: ^pdm.lock$
- repo: https://github.com/pdm-project/pdm
rev: 2.20.1
hooks:
- id: pdm-lock-check
- repo: https://github.com/djlint/djLint
rev: v1.36.2
rev: v1.36.4
hooks:
- id: djlint-reformat-django
- id: djlint-reformat-jinja
- id: djlint-django
- id: djlint-jinja
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.6.2
hooks:
- id: uv-lock
- repo: https://github.com/astral-sh/uv-pre-commit
rev: 0.6.2
hooks:
- name: uv-export-prod
id: uv-export
args:
- --frozen
- -o=requirements.txt
- --no-hashes
- --no-dev
- name: uv-export-dev
id: uv-export
args:
- --frozen
- -o=requirements.dev.txt
- --no-hashes
- --all-groups
- repo: local
hooks:
- name: Check for uncreated migrations.
id: migrations-check
language: system
entry: sh -c "pdm manage makemigrations --check --dry-run"
entry: sh -c "uv run task manage makemigrations --check --dry-run"
files: "models/.*.py$"
types:
- python
......
**/*.html
**/*.j2
.yarn
.yarnrc.yml
.venv*
static.dist/
**/vendor/**/*
......
......@@ -2,8 +2,6 @@ activitypub
Andi
ASGI
backoffice
bigbluebutton
BIGBLUEBUTTON
blocktranslate
clonbares
CLUBFRIENDS
......
File suppressed by a .gitattributes entry or the file's encoding is unsupported.
yarnPath: .yarn/releases/yarn-4.6.0.cjs
......@@ -50,11 +50,10 @@ Um eine andere Demo Datei zu laden kann die Umgebungsvariable `DJANGO_LOAD_FIXTU
- Linux: Pakete `python3`, `postgresql` und `gettext`
- Mac: `brew install python3 postgresql gettext` bzw. https://postgresapp.com/
- Windows: [latest stable Python 3 release](https://www.python.org/downloads/windows/) und [PostgreSQL Installer](https://www.postgresql.org/download/windows/) und [gettext binaries](https://mlocati.github.io/articles/gettext-iconv-windows.html)
- Python Paketmanager: `pdm`:
Kann mit OS Installationsmitteln, mit `pip install pdm` oder `pipx install pdm` installiert werden.
- Python Paketmanager: `uv`:
Kann mit OS Installationsmitteln, mit `pip install uv` oder `pipx install uv` installiert werden. (Siehe die [Offizielle Dokumentation](https://docs.astral.sh/uv/getting-started/installation/))
1. Klone dieses Repository an beliebigen Ort.
1. Erstelle die virtuelle Umgebung mit `pdm info`
1. Installiere die python dependencies mit `pdm install`
1. Installiere die python dependencies mit `uv sync`
1. (falls nicht bereits vorhanden) lege einen PostgreSQL-User an (`createuser -P hub_app`) sowie eine Datenbank (`createdb -O hub_app hub`) - unter Linux ggf. via `sudo -u postgres`
1. Konfiguriere deine Instanz mittels:
- Umgebungsvariablen (z.B. direnv, oder env Datei)
......@@ -84,18 +83,17 @@ DATABASES = {
}
```
8. Lege die Datenbanktabellen an: `pdm manage migrate`
9. Richte einen Admin-Nutzer (für die Anwendung) ein: `pdm manage createsuperuser`
10. optional: Import von Demo-Daten: `pdm manage.py loaddata .src/core/fixtures/rc3_2021.json`
8. Lege die Datenbanktabellen an: `uv run task manage migrate`
9. Richte einen Admin-Nutzer (für die Anwendung) ein: `uv run task manage createsuperuser`
10. optional: Import von Demo-Daten: `uv run task.py loaddata .src/core/fixtures/rc3_2021.json`
11. optional: Für deinen Adminuser via [Admin-Seite](http://localhost:8000/c3admin/) einen `ConferenceMember` anlegen um den User für das Frontend freizuschalten
## Nutzung
1. Aktiviere das virtual env `pdm venv activate`
2. Wende ggf. vorhandene DB-Migrations an (wenn du gerade aus dem Git geupdatet hast): `pdm manage migrate`
3. Stelle sicher dass alle Translations aktuell sind: `pdm manage compilemessages`
4. Lasse alle staticfiles einsammeln: `pdm manage collectstatic --noinput`
5. Starte den Dev-Server: `pdm manage runserver`
2. Wende ggf. vorhandene DB-Migrations an (wenn du gerade aus dem Git geupdatet hast): `uv run task manage migrate`
3. Stelle sicher dass alle Translations aktuell sind: `uv run task manage compilemessages`
4. Lasse alle staticfiles einsammeln: `uv run task manage collectstatic --noinput`
5. Starte den Dev-Server: `uv run task manage runserver`
6. Besuche die lokale Instanz: [Admin-Seite](http://localhost:8000/c3admin/), [API](http://localhost:8000/api/) und [plainui-Frontend](http://localhost:8000/)
## PlainUI Development Tipps
......@@ -136,26 +134,26 @@ Wiederverwendbare Elemente können als Komponenten integriert werden. Dafür gib
### Abhängigkeitsverwaltung
Zur Verwaltung der verwendeten python Abhängigkeiten wir der [Paketmanager PDM](https://pdm-project.org/en/latest/) verwendet.
Zur Verwaltung der verwendeten python Abhängigkeiten wir der [Paketmanager UV](https://docs.astral.sh/uv/) verwendet.
Mittels diesem werden die `requirements.txt` und die `requirements.dev.txt` erzeugt.
#### Installation der aktuellen Abhängigkeiten
Um die aktuellen python Abhängigkeiten zu installieren kann das Kommando `pdm install` verwendet werden.
Mit dem Kommando `pdm sync --clean` kann sichergestellt werden, dass genau die Versionen aus dem pdm lock file installiert werden.
Um die aktuellen python Abhängigkeiten zu installieren kann das Kommando `uv sync` verwendet werden.
Mit dem Kommando `ur sync --frozen` kann sichergestellt werden, dass genau die Versionen aus dem uv lock file installiert werden.
_Achtung_: **Nicht in der Lock Datei enthaltene python Pakete werden deinstalliert!**
#### Hinzufügen von neuen Abhängigkeiten
Um neue Abhängigkeiten hinzuzufügen kann das Kommando `pdm add` verwendet werden. Mit dem Parameter `--dev` kann eine Abhängigkeit als Entwicklungs-Abhängigkeit deklariert werden. Diese wird dann in den Produktivinstanzen nicht installiert.
Um neue Abhängigkeiten hinzuzufügen kann das Kommando `uv add` verwendet werden. Mit dem Parameter `--dev` kann eine Abhängigkeit als Entwicklungs-Abhängigkeit deklariert werden. Diese wird dann in den Produktivinstanzen nicht installiert.
Anschließend müssen die `requirements.txt` und `requirements.dev.txt` angepasst werden.
Wenn `pre-commit` verwendet wird, passiert dies automatisch beim commit.
Alternativ können die folgenden Kommandos verwendet werden
```bash
pdm export --no-hashes -o requirements.txt --prod
pdm export --no-hashes -o requirements.dev.txt --dev
uv export --format requirements-txt --no-hashes -o requirements.txt --no-dev
uv export --format requirements-txt --no-hashes -o requirements.dev.txt --all-groups
```
### Debugging DJANGO
......@@ -177,9 +175,9 @@ oder:
### Übersetzungen extrahieren & compilieren
- `pdm manage makemessages`
- `uv run task manage makemessages`
- Die Übersetzungsdateien in `<app>/locale/<sprache>/LC_MESSAGES/django.po` wurden um alle neuen Übersetzungsstrings erweitert. Bearbeiten und jeweils bei `msgstr` die Übersetzungen einfügen!
- `pdm manage compilemessages`
- `uv run task manage compilemessages`
- Zum Ausprobieren müsst ihr django neu starten um die neuen Übersetzungsdateien zu laden
### Übersetzungen definineren
......@@ -189,7 +187,7 @@ oder:
### Static Files einsammeln lassen
- `pdm manage collectstatic`
- `uv run task manage collectstatic`
- ohne dies brechen u.a. Unittests mit Fehlern wie "Missing staticfiles manifest entry" ab
### Tests
......@@ -216,8 +214,8 @@ self.assertEqual(translation, "NoTIcket_trans")
Um die Tests ausführen zu können muss der Datenbanknutzer das Recht haben neue Datenbaken anzulegen.
Dafür mit `psql postgres` die Datenbankkonsole starten. Dort `ALTER USER hub_app CREATEDB;` ausführen (ggf. `hub_app` durch den gewählten Nutzernamen ersetzen). Am Ende mit `Strg-D` Konsole wieder schließen.
Um die Django Tests auszuführen kann das Kommando `pdm test` verwendet werden. \
Um nur die Tests einer App auszuführen stattdessen `pdm test -- <app>.tests` ausführen. \
Um die Django Tests auszuführen kann das Kommando `uv run tox -e django-test` verwendet werden. \
Um nur die Tests einer App auszuführen stattdessen `uv run tox -e django-test -- <app>.tests` ausführen. \
Hilfreiche Argumente sind `-v 2` um die ausgeführten Tests anzuzeigen, `--failfast` um nach dem ersten Fehler abzubrechen, und `--keepdb` um nicht jedes mal die Migrationen durchführen zu müssen. \
Für weitere Infos zu dem Befehl ist https://docs.djangoproject.com/en/3.1/ref/django-admin/#django-admin-test hilfreich.
......@@ -244,7 +242,7 @@ Dieses hat die folgenden Kommandos:
- `ruff check`: Diess Kommando checkt auf häufige Fehler in python code und hat auch teilweise Möglichkeiten diese zu beheben
- `ruff format`: Dieses Kommando re-formatiert alle python dateien nach einem voregebenen Code-Style
### djLink
### djLint
**Leider ist es nicht möglich djLint so zu konfigurieren, dass es automatisch die richtigen Profile verwendet.**
**Wenn eine Integration in einen Editor gewünscht ist, muss dies berücksichtigt werden!**
......
ARG REGISTRY=""
FROM ${REGISTRY}python:3.13-bookworm AS base
COPY --from=ghcr.io/astral-sh/uv:0.5.21 /uv /uvx /bin/
ENV DEBIAN_FRONTEND=noninteractive
ENV PDM_CHECK_UPDATE=false
# Set up uv environment
ENV UV_LINK_MODE=copy UV_COMPILE_BYTECODE=1 UV_TOOL_BIN_DIR=/opt/uv-bin/
RUN echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/99-unattended-minimal && \
echo 'APT::Install-Suggests "false";' >> /etc/apt/apt.conf.d/99-unattended-minimal && \
......@@ -10,7 +12,6 @@ RUN echo 'APT::Install-Recommends "false";' > /etc/apt/apt.conf.d/99-unattended-
RUN --mount=target=/var/lib/apt/lists/,type=cache,sharing=locked \
--mount=target=/var/cache/apt/archives/,type=cache,sharing=locked \
--mount=target=/root/.cache/pip,type=cache,sharing=locked \
# Prevent apt cache cleaning
rm -f /etc/apt/apt.conf.d/docker-clean && \
apt-get update && \
......@@ -21,12 +22,16 @@ RUN --mount=target=/var/lib/apt/lists/,type=cache,sharing=locked \
dpkg-reconfigure locales && \
locale-gen C.UTF-8 && \
/usr/sbin/update-locale LANG=C.UTF-8 && \
pip install -U pdm && \
# Fix caching issue with kaniko see: https://github.com/GoogleContainerTools/kaniko/issues/3246
mkdir -p /app/plainui
# Add path for future pdm location
ENV PATH="/install/.venv/bin:$PATH"
# Add path for future uv location
ENV PATH="/install/.venv/bin:/opt/uv-bin:$PATH"
######################################### [meta] #############################
FROM base AS meta
RUN uv tool install tox --with tox-uv
######################################### [build] #############################
......@@ -38,25 +43,24 @@ RUN --mount=target=/var/lib/apt/lists/,type=cache,sharing=locked \
--mount=target=/var/cache/apt/archives/,type=cache,sharing=locked \
apt-get update && \
apt-get install \
build-essential \
yarnpkg && \
/usr/bin/yarnpkg global bin corepack enable &&\
build-essential && \
mkdir /install
WORKDIR /install
COPY pyproject.toml pdm.lock README.md /install/
RUN --mount=target=/root/.cache/pdm,type=cache,sharing=locked \
pdm install --check --prod --no-editable
COPY pyproject.toml uv.lock README.md /install/
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-editable
######################################### [build-dev] #########################
FROM build AS build-dev
WORKDIR /install
RUN --mount=target=/root/.cache/pdm,type=cache,sharing=locked \
pdm install --check --dev --no-editable
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --frozen --no-install-project --no-editable
######################################### [node-build] ########################
FROM ${REGISTRY}node:20-alpine AS node-base
RUN mkdir -p /app/plainui/
......@@ -68,16 +72,6 @@ RUN corepack enable && \
/usr/local/bin/yarnpkg set version stable && \
/usr/local/bin/yarnpkg install
######################################### [nginx-forwarder] ###################
FROM ${REGISTRY}nginx:1-alpine-slim AS nginx-forwarder
ENV APP_SOCKET="/run/hub/app.sock"
ENV SCRIPT_NAME=""
COPY deployment/docker/index.html deployment/docker/error_*.html /www/default/
COPY deployment/docker/nginx.conf /etc/nginx/templates/default.conf.template
######################################### [webworker-base] ####################
FROM base AS webworker-base
......@@ -96,7 +90,6 @@ COPY deployment/docker/app.sh /usr/local/bin/app
COPY deployment/docker/check_django.sh /usr/local/bin/hub_healthcheck
COPY deployment/docker/check_psql.py /usr/local/bin/postgres_healthcheck
COPY --from=build /install/.venv /install/.venv
ENV PATH="/install/.venv/bin:$PATH"
RUN install -d -m 0755 -o appuser -g appuser /app/hub /data /app/media /run/hub && \
......@@ -133,7 +126,12 @@ RUN export DJANGO_SETTINGS_MODULE='hub.settings.build' && \
######################################### [nginx] #############################
FROM nginx-forwarder AS nginx
FROM ${REGISTRY}nginx:1-alpine-slim AS nginx
ENV APP_SOCKET="/run/hub/app.sock"
ENV SCRIPT_NAME=""
COPY deployment/docker/index.html deployment/docker/error_*.html /www/default/
COPY deployment/docker/nginx.conf /etc/nginx/templates/default.conf.template
COPY --from=build-static /app/static.dist /www/static
......@@ -141,6 +139,7 @@ COPY --from=build-static /app/static.dist /www/static
FROM webworker-base AS webworker
COPY --from=build /install/.venv /install/.venv
COPY --from=build-static --chown=appuser /app /app
USER appuser
......
......@@ -39,9 +39,18 @@ Prodinstanz: <https://api.events.ccc.de/congress/2024/>
| Kategorie | Endpunkt | GET | POST | PUT | DEL | Beschreibung |
| ---------- | ---------------------------------------- | --- | ---- | --- | --- | ----------------------------------------------------- |
| Auth | `/auth/get-token` | | x | | | Ausstellen eines API-Tokens |
| Persönlich | `/me` | x | | x | | eigenes Profil / Settings |
| Persönlich | `/me/friends` | x | | x | x | Liste der Buddies |
| Persönlich | `/me/badges` | x | | | | Liste aller Badges/Achievements |
| Persönlich | `/me/events` | x | | | | Favorisierte Events |
| Persönlich | `/me/events/<uuid>/` | | | x | x | Events (ent-)favorisieren |
| Persönlich | `/me/friends` | x | | x | x | Liste der Buddies |
| Persönlich | `/me/received-messages/` | x | | | | Übersicht empfangener PN |
| Persönlich | `/me/received-messages/<uuid>` | x | | | | Details einer empfangenen PN |
| Persönlich | `/me/send-message` | | x | | | Send a new PN |
| Persönlich | `/me/sent-messages/` | x | | | | Übersicht gesendeter PN |
| Persönlich | `/me/sent-messages/<uuid>` | x | | | | Details einer gesendeten PN |
| Persönlich | `/me/delete-message/<uuid>` | x | | | | PN löschen |
| Konferenz | `/` | x | | | | Metadaten des Konferenz |
| Konferenz | `/tags` | x | | | | Liste aller Tags auf der Konferenz |
| Konferenz | `/tracks` | x | x | | | Liste der Tracks |
......@@ -64,6 +73,20 @@ Prodinstanz: <https://api.events.ccc.de/congress/2024/>
Per POST werden neue Einträge angelegt, per PUT bestehende verändert.
Details zu den einzelnen Endpunkten folgen in Kürze™.
### API-Beispiel mit cURL
Zuerst einen Token generieren:
```bash
curl https://{API_URL}/api/auth/get-token -H "Content-Type: application/json" -X POST --data '{"username": "{USERNAME}", "password": "{PASSWORD}"}'
```
Mit diesem Token können dann Endpunkte aufgerufen werden die eine Authentifizierung erfordern:
```bash
curl https://{API_URL}/api/me -H "Content-Type: application/json" -H "Authorization: Token {API_TOKEN}"
```
## Development
see [Development.md](./Development.md)
......@@ -45,6 +45,8 @@ if [ ! -e "$HOME/$ADMIN_CREATED" -a -n "$DJANGO_CREATE_ADMIN_PASSWORD" ]; then
touch $HOME/$ADMIN_CREATED
fi
touch $HOME/PREPARATION_DONE
if [ "$1" == "webworker" -o "$STARTMODE" == "webworker" ]; then
# start gunicorn (might be called indirectly via supervisor when started with 'all')
gunicorn_params=()
......@@ -75,12 +77,7 @@ if [ "$1" == "shell" -o "$1" == "createsuperuser" -o "$1" == "test" ]; then
fi
if [ "$1" == "housekeeping" ]; then
interval="${HOUSEKEEPING_SLEEP_SECONDS:-300}"
if [ "$interval" -gt 0 ]; then
python3 $APP_HOME/manage.py housekeeping --forever --forever-delay="$interval"
else
python3 $APP_HOME/manage.py housekeeping
fi
python3 $APP_HOME/manage.py housekeeping --forever
fi
cat <<EOD
......
......@@ -21,7 +21,7 @@ TOKEN = env('API_TOKEN')
PER_PAGE = 100
DELETE_ALL = datetime.now(tz=UTC) - timedelta(weeks=env('THRESHOLD_ALL'))
DELETE_FAILED = datetime.now(tz=UTC) - timedelta(weeks=env('THRESHOLD_FAILED'))
BASE_URL = f'{env('CI_API_V4_URL')}/projects/{env("CI_PROJECT_ID")}'
BASE_URL = f'{env("CI_API_V4_URL")}/projects/{env("CI_PROJECT_ID")}'
if TOKEN is None:
raise ValueError('API_TOKEN is required')
......
{
"name": "hub",
"packageManager": "yarn@4.5.0",
"packageManager": "yarn@4.6.0",
"devDependencies": {
"@cspell/dict-de-de": "^4.0.3",
"@cspell/dict-python": "^4.2.12",
......
# This file is @generated by PDM.
# It is not intended for manual editing.
[metadata]
groups = ["default", "dev", "lint", "local", "static-analysis", "typing", "watchfiles"]
strategy = ["inherit_metadata"]
lock_version = "4.5.0"
content_hash = "sha256:43da701dd7bbc3d2e5cc1f4f75912657fd1030067769f5ad070832b790edc0e8"
[[metadata.targets]]
requires_python = "==3.13.*"
[[package]]
name = "annotated-types"
version = "0.7.0"
requires_python = ">=3.8"
summary = "Reusable constraint types to use with typing.Annotated"
groups = ["default"]
dependencies = [
"typing-extensions>=4.0.0; python_version < \"3.9\"",
]
files = [
{file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"},
{file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"},
]
[[package]]
name = "anyio"
version = "4.6.2.post1"
requires_python = ">=3.9"
summary = "High level compatibility layer for multiple asynchronous event loop implementations"
groups = ["default", "watchfiles"]
dependencies = [
"exceptiongroup>=1.0.2; python_version < \"3.11\"",
"idna>=2.8",
"sniffio>=1.1",
"typing-extensions>=4.1; python_version < \"3.11\"",
]
files = [
{file = "anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d"},
{file = "anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c"},
]
[[package]]
name = "asgiref"
version = "3.8.1"
requires_python = ">=3.8"
summary = "ASGI specs, helper code, and adapters"
groups = ["default", "typing", "watchfiles"]
dependencies = [
"typing-extensions>=4; python_version < \"3.11\"",
]
files = [
{file = "asgiref-3.8.1-py3-none-any.whl", hash = "sha256:3e1e3ecc849832fe52ccf2cb6686b7a55f82bb1d6aee72a58826471390335e47"},
{file = "asgiref-3.8.1.tar.gz", hash = "sha256:c343bd80a0bec947a9860adb4c432ffa7db769836c64238fc34bdc3fec84d590"},
]
[[package]]
name = "astroid"
version = "3.3.5"
requires_python = ">=3.9.0"
summary = "An abstract syntax tree for Python with inference support."
groups = ["static-analysis"]
dependencies = [
"typing-extensions>=4.0.0; python_version < \"3.11\"",
]
files = [
{file = "astroid-3.3.5-py3-none-any.whl", hash = "sha256:a9d1c946ada25098d790e079ba2a1b112157278f3fb7e718ae6a9252f5835dc8"},
{file = "astroid-3.3.5.tar.gz", hash = "sha256:5cfc40ae9f68311075d27ef68a4841bdc5cc7f6cf86671b49f00607d30188e2d"},
]
[[package]]
name = "asttokens"
version = "2.4.1"
summary = "Annotate AST trees with source code positions"
groups = ["local"]
dependencies = [
"six>=1.12.0",
"typing; python_version < \"3.5\"",
]
files = [
{file = "asttokens-2.4.1-py2.py3-none-any.whl", hash = "sha256:051ed49c3dcae8913ea7cd08e46a606dba30b79993209636c4875bc1d637bc24"},
{file = "asttokens-2.4.1.tar.gz", hash = "sha256:b03869718ba9a6eb027e134bfdf69f38a236d681c83c160d510768af11254ba0"},
]
[[package]]
name = "babel"
version = "2.16.0"
requires_python = ">=3.8"
summary = "Internationalization utilities"
groups = ["default"]
dependencies = [
"pytz>=2015.7; python_version < \"3.9\"",
]
files = [
{file = "babel-2.16.0-py3-none-any.whl", hash = "sha256:368b5b98b37c06b7daf6696391c3240c938b37767d4584413e8438c5c435fa8b"},
{file = "babel-2.16.0.tar.gz", hash = "sha256:d1f3554ca26605fe173f3de0c65f750f5a42f924499bf134de6423582298e316"},
]
[[package]]
name = "beautifulsoup4"
version = "4.12.3"
requires_python = ">=3.6.0"
summary = "Screen-scraping library"
groups = ["default"]
dependencies = [
"soupsieve>1.2",
]
files = [
{file = "beautifulsoup4-4.12.3-py3-none-any.whl", hash = "sha256:b80878c9f40111313e55da8ba20bdba06d8fa3969fc68304167741bbf9e082ed"},
{file = "beautifulsoup4-4.12.3.tar.gz", hash = "sha256:74e3d1928edc070d21748185c46e3fb33490f22f52a3addee9aee0f4f7781051"},
]
[[package]]
name = "bleach"
version = "6.2.0"
requires_python = ">=3.9"
summary = "An easy safelist-based HTML-sanitizing tool."
groups = ["default"]
dependencies = [
"webencodings",
]
files = [
{file = "bleach-6.2.0-py3-none-any.whl", hash = "sha256:117d9c6097a7c3d22fd578fcd8d35ff1e125df6736f554da4e432fdd63f31e5e"},
{file = "bleach-6.2.0.tar.gz", hash = "sha256:123e894118b8a599fd80d3ec1a6d4cc7ce4e5882b1317a7e1ba69b56e95f991f"},
]
[[package]]
name = "blinker"
version = "1.9.0"
requires_python = ">=3.9"
summary = "Fast, simple object-to-object and broadcast signaling"
groups = ["default"]
files = [
{file = "blinker-1.9.0-py3-none-any.whl", hash = "sha256:ba0efaa9080b619ff2f3459d1d500c57bddea4a6b424b60a91141db6fd2f08bc"},
{file = "blinker-1.9.0.tar.gz", hash = "sha256:b4ce2265a7abece45e7cc896e98dbebe6cead56bcf805a3d23136d145f5445bf"},
]
[[package]]
name = "boto3"
version = "1.35.71"
requires_python = ">=3.8"
summary = "The AWS SDK for Python"
groups = ["default"]
dependencies = [
"botocore<1.36.0,>=1.35.71",
"jmespath<2.0.0,>=0.7.1",
"s3transfer<0.11.0,>=0.10.0",
]
files = [
{file = "boto3-1.35.71-py3-none-any.whl", hash = "sha256:e2969a246bb3208122b3c349c49cc6604c6fc3fc2b2f65d99d3e8ccd745b0c16"},
{file = "boto3-1.35.71.tar.gz", hash = "sha256:3ed7172b3d4fceb6218bb0ec3668c4d40c03690939c2fca4f22bb875d741a07f"},
]
[[package]]
name = "botocore"
version = "1.35.71"
requires_python = ">=3.8"
summary = "Low-level, data-driven core of boto 3."
groups = ["default"]
dependencies = [
"jmespath<2.0.0,>=0.7.1",
"python-dateutil<3.0.0,>=2.1",
"urllib3!=2.2.0,<3,>=1.25.4; python_version >= \"3.10\"",
"urllib3<1.27,>=1.25.4; python_version < \"3.10\"",
]
files = [
{file = "botocore-1.35.71-py3-none-any.whl", hash = "sha256:fc46e7ab1df3cef66dfba1633f4da77c75e07365b36f03bd64a3793634be8fc1"},
{file = "botocore-1.35.71.tar.gz", hash = "sha256:f9fa058e0393660c3fe53c1e044751beb64b586def0bd2212448a7c328b0cbba"},
]
[[package]]
name = "cachetools"
version = "5.5.0"
requires_python = ">=3.7"
summary = "Extensible memoizing collections and decorators"
groups = ["dev"]
files = [
{file = "cachetools-5.5.0-py3-none-any.whl", hash = "sha256:02134e8439cdc2ffb62023ce1debca2944c3f289d66bb17ead3ab3dede74b292"},
{file = "cachetools-5.5.0.tar.gz", hash = "sha256:2cc24fb4cbe39633fb7badd9db9ca6295d766d9c2995f245725a46715d050f2a"},
]
[[package]]
name = "certifi"
version = "2024.8.30"
requires_python = ">=3.6"
summary = "Python package for providing Mozilla's CA Bundle."
groups = ["default"]
files = [
{file = "certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8"},
{file = "certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9"},
]
[[package]]
name = "cffi"
version = "1.17.1"
requires_python = ">=3.8"
summary = "Foreign Function Interface for Python calling C code."
groups = ["default"]
marker = "platform_python_implementation != \"PyPy\""
dependencies = [
"pycparser",
]
files = [
{file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"},
{file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"},
{file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"},
{file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"},
{file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"},
{file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"},
{file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"},
{file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"},
]
[[package]]
name = "cfgv"
version = "3.4.0"
requires_python = ">=3.8"
summary = "Validate configuration and produce human readable error messages."
groups = ["dev"]
files = [
{file = "cfgv-3.4.0-py2.py3-none-any.whl", hash = "sha256:b7265b1f29fd3316bfcd2b330d63d024f2bfd8bcb8b0272f8e19a504856c48f9"},
{file = "cfgv-3.4.0.tar.gz", hash = "sha256:e52591d4c5f5dead8e0f673fb16db7949d2cfb3f7da4582893288f0ded8fe560"},
]
[[package]]
name = "chardet"
version = "5.2.0"
requires_python = ">=3.7"
summary = "Universal encoding detector for Python 3"
groups = ["dev"]
files = [
{file = "chardet-5.2.0-py3-none-any.whl", hash = "sha256:e1cf59446890a00105fe7b7912492ea04b6e6f06d4b742b2c788469e34c82970"},
{file = "chardet-5.2.0.tar.gz", hash = "sha256:1b3b6ff479a8c414bc3fa2c0852995695c4a026dcd6d0633b2dd092ca39c1cf7"},
]
[[package]]
name = "charset-normalizer"
version = "3.4.0"
requires_python = ">=3.7.0"
summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
groups = ["default"]
files = [
{file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:dd4eda173a9fcccb5f2e2bd2a9f423d180194b1bf17cf59e3269899235b2a114"},
{file = "charset_normalizer-3.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9e3c4c9e1ed40ea53acf11e2a386383c3304212c965773704e4603d589343ed"},
{file = "charset_normalizer-3.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92a7e36b000bf022ef3dbb9c46bfe2d52c047d5e3f3343f43204263c5addc250"},
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:54b6a92d009cbe2fb11054ba694bc9e284dad30a26757b1e372a1fdddaf21920"},
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1ffd9493de4c922f2a38c2bf62b831dcec90ac673ed1ca182fe11b4d8e9f2a64"},
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:35c404d74c2926d0287fbd63ed5d27eb911eb9e4a3bb2c6d294f3cfd4a9e0c23"},
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4796efc4faf6b53a18e3d46343535caed491776a22af773f366534056c4e1fbc"},
{file = "charset_normalizer-3.4.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e7fdd52961feb4c96507aa649550ec2a0d527c086d284749b2f582f2d40a2e0d"},
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:92db3c28b5b2a273346bebb24857fda45601aef6ae1c011c0a997106581e8a88"},
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:ab973df98fc99ab39080bfb0eb3a925181454d7c3ac8a1e695fddfae696d9e90"},
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4b67fdab07fdd3c10bb21edab3cbfe8cf5696f453afce75d815d9d7223fbe88b"},
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:aa41e526a5d4a9dfcfbab0716c7e8a1b215abd3f3df5a45cf18a12721d31cb5d"},
{file = "charset_normalizer-3.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:ffc519621dce0c767e96b9c53f09c5d215578e10b02c285809f76509a3931482"},
{file = "charset_normalizer-3.4.0-cp313-cp313-win32.whl", hash = "sha256:f19c1585933c82098c2a520f8ec1227f20e339e33aca8fa6f956f6691b784e67"},
{file = "charset_normalizer-3.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:707b82d19e65c9bd28b81dde95249b07bf9f5b90ebe1ef17d9b57473f8a64b7b"},
{file = "charset_normalizer-3.4.0-py3-none-any.whl", hash = "sha256:fe9f97feb71aa9896b81973a7bbada8c49501dc73e58a10fcef6663af95e5079"},
{file = "charset_normalizer-3.4.0.tar.gz", hash = "sha256:223217c3d4f82c3ac5e29032b3f1c2eb0fb591b72161f86d93f5719079dae93e"},
]
[[package]]
name = "click"
version = "8.1.7"
requires_python = ">=3.7"
summary = "Composable command line interface toolkit"
groups = ["lint"]
dependencies = [
"colorama; platform_system == \"Windows\"",
"importlib-metadata; python_version < \"3.8\"",
]
files = [
{file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"},
{file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"},
]
[[package]]
name = "colorama"
version = "0.4.6"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
summary = "Cross-platform colored terminal text."
groups = ["dev", "lint", "local", "static-analysis"]
files = [
{file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"},
{file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"},
]
[[package]]
name = "coverage"
version = "7.6.8"
requires_python = ">=3.9"
summary = "Code coverage measurement for Python"
groups = ["dev"]
files = [
{file = "coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb"},
{file = "coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63"},
{file = "coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365"},
{file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002"},
{file = "coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3"},
{file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022"},
{file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e"},
{file = "coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b"},
{file = "coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146"},
{file = "coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28"},
{file = "coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d"},
{file = "coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451"},
{file = "coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764"},
{file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf"},
{file = "coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5"},
{file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4"},
{file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83"},
{file = "coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b"},
{file = "coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71"},
{file = "coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc"},
{file = "coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc"},
]
[[package]]
name = "cryptography"
version = "43.0.3"
requires_python = ">=3.7"
summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
groups = ["default"]
dependencies = [
"cffi>=1.12; platform_python_implementation != \"PyPy\"",
]
files = [
{file = "cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e"},
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e"},
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f"},
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6"},
{file = "cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18"},
{file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd"},
{file = "cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73"},
{file = "cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2"},
{file = "cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd"},
{file = "cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984"},
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5"},
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4"},
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7"},
{file = "cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405"},
{file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16"},
{file = "cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73"},
{file = "cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995"},
{file = "cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362"},
{file = "cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805"},
]
[[package]]
name = "cssbeautifier"
version = "1.15.1"
summary = "CSS unobfuscator and beautifier."
groups = ["lint"]
dependencies = [
"editorconfig>=0.12.2",
"jsbeautifier",
"six>=1.13.0",
]
files = [
{file = "cssbeautifier-1.15.1.tar.gz", hash = "sha256:9f7064362aedd559c55eeecf6b6bed65e05f33488dcbe39044f0403c26e1c006"},
]
[[package]]
name = "debugpy"
version = "1.8.9"
requires_python = ">=3.8"
summary = "An implementation of the Debug Adapter Protocol for Python"
groups = ["local"]
files = [
{file = "debugpy-1.8.9-cp313-cp313-macosx_14_0_universal2.whl", hash = "sha256:957ecffff80d47cafa9b6545de9e016ae8c9547c98a538ee96ab5947115fb3dd"},
{file = "debugpy-1.8.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1efbb3ff61487e2c16b3e033bc8595aea578222c08aaf3c4bf0f93fadbd662ee"},
{file = "debugpy-1.8.9-cp313-cp313-win32.whl", hash = "sha256:7c4d65d03bee875bcb211c76c1d8f10f600c305dbd734beaed4077e902606fee"},
{file = "debugpy-1.8.9-cp313-cp313-win_amd64.whl", hash = "sha256:e46b420dc1bea64e5bbedd678148be512442bc589b0111bd799367cde051e71a"},
{file = "debugpy-1.8.9-py2.py3-none-any.whl", hash = "sha256:cc37a6c9987ad743d9c3a14fa1b1a14b7e4e6041f9dd0c8abf8895fe7a97b899"},
{file = "debugpy-1.8.9.zip", hash = "sha256:1339e14c7d980407248f09824d1b25ff5c5616651689f1e0f0e51bdead3ea13e"},
]
[[package]]
name = "defusedxml"
version = "0.7.1"
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*"
summary = "XML bomb protection for Python stdlib modules"
groups = ["default"]
files = [
{file = "defusedxml-0.7.1-py2.py3-none-any.whl", hash = "sha256:a352e7e428770286cc899e2542b6cdaedb2b4953ff269a210103ec58f6198a61"},
{file = "defusedxml-0.7.1.tar.gz", hash = "sha256:1bb3032db185915b62d7c6209c5a8792be6a32ab2fedacc84e01b52c51aa3e69"},
]
[[package]]
name = "dep-logic"
version = "0.4.9"
requires_python = ">=3.8"
summary = "Python dependency specifications supporting logical operations"
groups = ["default"]
dependencies = [
"packaging>=22",
]
files = [
{file = "dep_logic-0.4.9-py3-none-any.whl", hash = "sha256:06faa33814e5ff881922f644284a608d7da7946462760f710217d829ae864a0e"},
{file = "dep_logic-0.4.9.tar.gz", hash = "sha256:5d455ea2a3da4fea2be6186d886905c57eeeebe3ea7fa967f599cb8e0f01d5c9"},
]
[[package]]
name = "dill"
version = "0.3.9"
requires_python = ">=3.8"
summary = "serialize all of Python"
groups = ["static-analysis"]
marker = "python_version >= \"3.11\""
files = [
{file = "dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a"},
{file = "dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c"},
]
[[package]]
name = "distlib"
version = "0.3.9"
summary = "Distribution utilities"
groups = ["default", "dev"]
files = [
{file = "distlib-0.3.9-py2.py3-none-any.whl", hash = "sha256:47f8c22fd27c27e25a65601af709b38e4f0a45ea4fc2e710f65755fa8caaaf87"},
{file = "distlib-0.3.9.tar.gz", hash = "sha256:a60f20dea646b8a33f3e7772f74dc0b2d0772d2837ee1342a00645c81edf9403"},
]
[[package]]
name = "django"
version = "5.1.3"
requires_python = ">=3.10"
summary = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
groups = ["default", "typing", "watchfiles"]
dependencies = [
"asgiref<4,>=3.8.1",
"sqlparse>=0.3.1",
"tzdata; sys_platform == \"win32\"",
]
files = [
{file = "Django-5.1.3-py3-none-any.whl", hash = "sha256:8b38a9a12da3ae00cb0ba72da985ec4b14de6345046b1e174b1fd7254398f818"},
{file = "Django-5.1.3.tar.gz", hash = "sha256:c0fa0e619c39325a169208caef234f90baa925227032ad3f44842ba14d75234a"},
]
[[package]]
name = "django-bootstrap5"
version = "24.3"
requires_python = ">=3.8"
summary = "Bootstrap 5 for Django"
groups = ["default"]
dependencies = [
"Django>=4.2",
]
files = [
{file = "django_bootstrap5-24.3-py3-none-any.whl", hash = "sha256:98f7916f9f7f9c34dfe157f7c062a28ebf6d17ff95307bef260ba794ba34e2a0"},
{file = "django_bootstrap5-24.3.tar.gz", hash = "sha256:ca5ec5568fc2a3fc239f0cb8ce41a7df3802b8c4af930d7f64451784ec7ddc16"},
]
[[package]]
name = "django-cors-headers"
version = "4.6.0"
requires_python = ">=3.9"
summary = "django-cors-headers is a Django application for handling the server headers required for Cross-Origin Resource Sharing (CORS)."
groups = ["default"]
dependencies = [
"asgiref>=3.6",
"django>=4.2",
]
files = [
{file = "django_cors_headers-4.6.0-py3-none-any.whl", hash = "sha256:8edbc0497e611c24d5150e0055d3b178c6534b8ed826fb6f53b21c63f5d48ba3"},
{file = "django_cors_headers-4.6.0.tar.gz", hash = "sha256:14d76b4b4c8d39375baeddd89e4f08899051eeaf177cb02a29bd6eae8cf63aa8"},
]
[[package]]
name = "django-csp"
version = "3.8"
summary = "Django Content Security Policy support."
groups = ["default"]
dependencies = [
"Django>=3.2",
]
files = [
{file = "django_csp-3.8-py3-none-any.whl", hash = "sha256:19b2978b03fcd73517d7d67acbc04fbbcaec0facc3e83baa502965892d1e0719"},
{file = "django_csp-3.8.tar.gz", hash = "sha256:ef0f1a9f7d8da68ae6e169c02e9ac661c0ecf04db70e0d1d85640512a68471c0"},
]
[[package]]
name = "django-debug-toolbar"
version = "4.4.6"
requires_python = ">=3.8"
summary = "A configurable set of panels that display various debug information about the current request/response."
groups = ["default"]
dependencies = [
"django>=4.2.9",
"sqlparse>=0.2",
]
files = [
{file = "django_debug_toolbar-4.4.6-py3-none-any.whl", hash = "sha256:3beb671c9ec44ffb817fad2780667f172bd1c067dbcabad6268ce39a81335f45"},
{file = "django_debug_toolbar-4.4.6.tar.gz", hash = "sha256:36e421cb908c2f0675e07f9f41e3d1d8618dc386392ec82d23bcfcd5d29c7044"},
]
[[package]]
name = "django-environ"
version = "0.11.2"
requires_python = ">=3.6,<4"
summary = "A package that allows you to utilize 12factor inspired environment variables to configure your Django application."
groups = ["default"]
files = [
{file = "django-environ-0.11.2.tar.gz", hash = "sha256:f32a87aa0899894c27d4e1776fa6b477e8164ed7f6b3e410a62a6d72caaf64be"},
{file = "django_environ-0.11.2-py2.py3-none-any.whl", hash = "sha256:0ff95ab4344bfeff693836aa978e6840abef2e2f1145adff7735892711590c05"},
]
[[package]]
name = "django-modeltranslation"
version = "0.19.11"
summary = "Translates Django models using a registration approach."
groups = ["default"]
dependencies = [
"Django>=4.2",
"typing-extensions>=4.0.1; python_version < \"3.11\"",
]
files = [
{file = "django_modeltranslation-0.19.11-py3-none-any.whl", hash = "sha256:fe36ecb8d943aaa406e4045d34e2160e90b170b0c71c8d0b5336e5031030b202"},
{file = "django_modeltranslation-0.19.11.tar.gz", hash = "sha256:c65a2652554c22bbe11f5db2e81e0c66d58434077d31dce7089cc7bd3ce4e79c"},
]
[[package]]
name = "django-oauth-toolkit"
version = "3.0.1"
requires_python = ">=3.8"
summary = "OAuth2 Provider for Django"
groups = ["default"]
dependencies = [
"django>=4.2",
"jwcrypto>=1.5.0",
"oauthlib>=3.2.2",
"requests>=2.13.0",
]
files = [
{file = "django_oauth_toolkit-3.0.1-py3-none-any.whl", hash = "sha256:3ef00b062a284f2031b0732b32dc899e3bbf0eac221bbb1cffcb50b8932e55ed"},
{file = "django_oauth_toolkit-3.0.1.tar.gz", hash = "sha256:7200e4a9fb229b145a6d808cbf0423b6d69a87f68557437733eec3c0cf71db02"},
]
[[package]]
name = "django-ratelimit"
version = "4.1.0"
requires_python = ">=3.7"
summary = "Cache-based rate-limiting for Django."
groups = ["default"]
files = [
{file = "django-ratelimit-4.1.0.tar.gz", hash = "sha256:555943b283045b917ad59f196829530d63be2a39adb72788d985b90c81ba808b"},
{file = "django_ratelimit-4.1.0-py2.py3-none-any.whl", hash = "sha256:d047a31cf94d83ef1465d7543ca66c6fc16695559b5f8d814d1b51df15110b92"},
]
[[package]]
name = "django-redis"
version = "5.4.0"
requires_python = ">=3.6"
summary = "Full featured redis cache backend for Django."
groups = ["default"]
dependencies = [
"Django>=3.2",
"redis!=4.0.0,!=4.0.1,>=3",
]
files = [
{file = "django-redis-5.4.0.tar.gz", hash = "sha256:6a02abaa34b0fea8bf9b707d2c363ab6adc7409950b2db93602e6cb292818c42"},
{file = "django_redis-5.4.0-py3-none-any.whl", hash = "sha256:ebc88df7da810732e2af9987f7f426c96204bf89319df4c6da6ca9a2942edd5b"},
]
[[package]]
name = "django-rich"
version = "1.13.0"
requires_python = ">=3.9"
summary = "Extensions for using Rich with Django."
groups = ["default"]
dependencies = [
"django>=4.2",
"rich>=10",
]
files = [
{file = "django_rich-1.13.0-py3-none-any.whl", hash = "sha256:9146dc0e0134bb970f156e8ba3015abd8982c35418fbab45004c561b521ee509"},
{file = "django_rich-1.13.0.tar.gz", hash = "sha256:2a59a81ca3ba25202db7b6047aa322a8d5b866e1929f7fbea6059a3c8e4e420c"},
]
[[package]]
name = "django-storages"
version = "1.14.4"
requires_python = ">=3.7"
summary = "Support for many storage backends in Django"
groups = ["default"]
dependencies = [
"Django>=3.2",
]
files = [
{file = "django-storages-1.14.4.tar.gz", hash = "sha256:69aca94d26e6714d14ad63f33d13619e697508ee33ede184e462ed766dc2a73f"},
{file = "django_storages-1.14.4-py3-none-any.whl", hash = "sha256:d61930acb4a25e3aebebc6addaf946a3b1df31c803a6bf1af2f31c9047febaa3"},
]
[[package]]
name = "django-stubs"
version = "5.1.1"
requires_python = ">=3.8"
summary = "Mypy stubs for Django"
groups = ["typing"]
dependencies = [
"asgiref",
"django",
"django-stubs-ext>=5.1.1",
"tomli; python_version < \"3.11\"",
"types-PyYAML",
"typing-extensions>=4.11.0",
]
files = [
{file = "django_stubs-5.1.1-py3-none-any.whl", hash = "sha256:c4dc64260bd72e6d32b9e536e8dd0d9247922f0271f82d1d5132a18f24b388ac"},
{file = "django_stubs-5.1.1.tar.gz", hash = "sha256:126d354bbdff4906c4e93e6361197f6fbfb6231c3df6def85a291dae6f9f577b"},
]
[[package]]
name = "django-stubs-ext"
version = "5.1.1"
requires_python = ">=3.8"
summary = "Monkey-patching and extensions for django-stubs"
groups = ["typing"]
dependencies = [
"django",
"typing-extensions",
]
files = [
{file = "django_stubs_ext-5.1.1-py3-none-any.whl", hash = "sha256:3907f99e178c93323e2ce908aef8352adb8c047605161f8d9e5e7b4efb5a6a9c"},
{file = "django_stubs_ext-5.1.1.tar.gz", hash = "sha256:db7364e4f50ae7e5360993dbd58a3a57ea4b2e7e5bab0fbd525ccdb3e7975d1c"},
]
[[package]]
name = "django-stubs"
version = "5.1.1"
extras = ["mypy-compatible"]
requires_python = ">=3.8"
summary = "Mypy stubs for Django"
groups = ["typing"]
dependencies = [
"django-stubs==5.1.1",
]
files = [
{file = "django_stubs-5.1.1-py3-none-any.whl", hash = "sha256:c4dc64260bd72e6d32b9e536e8dd0d9247922f0271f82d1d5132a18f24b388ac"},
{file = "django_stubs-5.1.1.tar.gz", hash = "sha256:126d354bbdff4906c4e93e6361197f6fbfb6231c3df6def85a291dae6f9f577b"},
]
[[package]]
name = "django-timezone-field"
version = "7.0"
requires_python = "<4.0,>=3.8"
summary = "A Django app providing DB, form, and REST framework fields for zoneinfo and pytz timezone objects."
groups = ["default"]
dependencies = [
"Django<6.0,>=3.2",
"backports-zoneinfo<0.3.0,>=0.2.1; python_version < \"3.9\"",
]
files = [
{file = "django_timezone_field-7.0-py3-none-any.whl", hash = "sha256:3232e7ecde66ba4464abb6f9e6b8cc739b914efb9b29dc2cf2eee451f7cc2acb"},
{file = "django_timezone_field-7.0.tar.gz", hash = "sha256:aa6f4965838484317b7f08d22c0d91a53d64e7bbbd34264468ae83d4023898a7"},
]
[[package]]
name = "django-watchfiles"
version = "1.0.0"
requires_python = ">=3.9"
summary = "Use watchfiles in Django’s autoreloader."
groups = ["watchfiles"]
dependencies = [
"django>=4.2",
"watchfiles",
]
files = [
{file = "django_watchfiles-1.0.0-py3-none-any.whl", hash = "sha256:eaee798f908864f2a0b73d0362867c7d3a284398eaca82a0583b43969a37178d"},
{file = "django_watchfiles-1.0.0.tar.gz", hash = "sha256:e4aa8e910bee610dae2b586771e587072fd984fad8a17e83940e707cfe2ca427"},
]
[[package]]
name = "django-widget-tweaks"
version = "1.5.0"
requires_python = ">=3.8"
summary = "Tweak the form field rendering in templates, not in python-level form definitions."
groups = ["default"]
files = [
{file = "django-widget-tweaks-1.5.0.tar.gz", hash = "sha256:1c2180681ebb994e922c754804c7ffebbe1245014777ac47897a81f57cc629c7"},
{file = "django_widget_tweaks-1.5.0-py3-none-any.whl", hash = "sha256:a41b7b2f05bd44d673d11ebd6c09a96f1d013ee98121cb98c384fe84e33b881e"},
]
[[package]]
name = "djangorestframework"
version = "3.15.2"
requires_python = ">=3.8"
summary = "Web APIs for Django, made easy."
groups = ["default"]
dependencies = [
"backports-zoneinfo; python_version < \"3.9\"",
"django>=4.2",
]
files = [
{file = "djangorestframework-3.15.2-py3-none-any.whl", hash = "sha256:2b8871b062ba1aefc2de01f773875441a961fefbf79f5eed1e32b2f096944b20"},
{file = "djangorestframework-3.15.2.tar.gz", hash = "sha256:36fe88cd2d6c6bec23dca9804bab2ba5517a8bb9d8f47ebc68981b56840107ad"},
]
[[package]]
name = "djlint"
version = "1.36.2"
requires_python = ">=3.9"
summary = "HTML Template Linter and Formatter"
groups = ["lint"]
dependencies = [
"click>=8.0.1",
"colorama>=0.4.4",
"cssbeautifier>=1.14.4",
"jsbeautifier>=1.14.4",
"json5>=0.9.11",
"pathspec>=0.12",
"pyyaml>=6",
"regex>=2023",
"tomli>=2.0.1; python_version < \"3.11\"",
"tqdm>=4.62.2",
]
files = [
{file = "djlint-1.36.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:dbdffa74fed2fdd29c587f80179ae302247e51d3f78a617c4cde43b028bc161f"},
{file = "djlint-1.36.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:8bc05e3735960dad5b025037a0e5e823300224ac44d9d8c9cbae6fb962c77a84"},
{file = "djlint-1.36.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:f3e16b4d104d2aedc474c2da819fb2c09a5183e2867616fe4df2fa685d2c191f"},
{file = "djlint-1.36.2-cp313-cp313-win_amd64.whl", hash = "sha256:8e815b61a6f50eb55fd4c76cff6b3f447ecd5d063a714cd353fec47ce131e4c7"},
{file = "djlint-1.36.2-py3-none-any.whl", hash = "sha256:98193159b1563a8644b58b7adfcbad04246bb9078ad49c389ac586fec181c48d"},
{file = "djlint-1.36.2.tar.gz", hash = "sha256:00d1a79de3c43b50e46a0ce6f279535b88bbf203d3f50ada92f56740fca4f590"},
]
[[package]]
name = "docutils"
version = "0.21.2"
requires_python = ">=3.9"
summary = "Docutils -- Python Documentation Utilities"
groups = ["dev"]
files = [
{file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"},
{file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"},
]
[[package]]
name = "editorconfig"
version = "0.12.4"
summary = "EditorConfig File Locator and Interpreter for Python"
groups = ["lint"]
files = [
{file = "EditorConfig-0.12.4.tar.gz", hash = "sha256:24857fa1793917dd9ccf0c7810a07e05404ce9b823521c7dce22a4fb5d125f80"},
]
[[package]]
name = "et-xmlfile"
version = "2.0.0"
requires_python = ">=3.8"
summary = "An implementation of lxml.xmlfile for the standard library"
groups = ["default"]
files = [
{file = "et_xmlfile-2.0.0-py3-none-any.whl", hash = "sha256:7a91720bc756843502c3b7504c77b8fe44217c85c537d85037f0f536151b2caa"},
{file = "et_xmlfile-2.0.0.tar.gz", hash = "sha256:dab3f4764309081ce75662649be815c4c9081e88f0837825f90fd28317d4da54"},
]
[[package]]
name = "executing"
version = "2.1.0"
requires_python = ">=3.8"
summary = "Get the currently executing AST node of a frame, and other information"
groups = ["local"]
files = [
{file = "executing-2.1.0-py2.py3-none-any.whl", hash = "sha256:8d63781349375b5ebccc3142f4b30350c0cd9c79f921cde38be2be4637e98eaf"},
{file = "executing-2.1.0.tar.gz", hash = "sha256:8ea27ddd260da8150fa5a708269c4a10e76161e2496ec3e587da9e3c0fe4b9ab"},
]
[[package]]
name = "filelock"
version = "3.16.1"
requires_python = ">=3.8"
summary = "A platform independent file lock."
groups = ["default", "dev"]
files = [
{file = "filelock-3.16.1-py3-none-any.whl", hash = "sha256:2082e5703d51fbf98ea75855d9d5527e33d8ff23099bec374a134febee6946b0"},
{file = "filelock-3.16.1.tar.gz", hash = "sha256:c249fbfcd5db47e5e2d6d62198e565475ee65e4831e2561c8e313fa7eb961435"},
]
[[package]]
name = "findpython"
version = "0.6.2"
requires_python = ">=3.8"
summary = "A utility to find python versions on your system"
groups = ["default"]
dependencies = [
"packaging>=20",
]
files = [
{file = "findpython-0.6.2-py3-none-any.whl", hash = "sha256:bda62477f858ea623ef2269f5e734469a018104a5f6c0fd9317ba238464ddb76"},
{file = "findpython-0.6.2.tar.gz", hash = "sha256:e0c75ba9f35a7f9bb4423eb31bd17358cccf15761b6837317719177aeff46723"},
]
[[package]]
name = "freezegun"
version = "1.5.1"
requires_python = ">=3.7"
summary = "Let your Python tests travel through time"
groups = ["default"]
dependencies = [
"python-dateutil>=2.7",
]
files = [
{file = "freezegun-1.5.1-py3-none-any.whl", hash = "sha256:bf111d7138a8abe55ab48a71755673dbaa4ab87f4cff5634a4442dfec34c15f1"},
{file = "freezegun-1.5.1.tar.gz", hash = "sha256:b29dedfcda6d5e8e083ce71b2b542753ad48cfec44037b3fc79702e2980a89e9"},
]
[[package]]
name = "gunicorn"
version = "23.0.0"
requires_python = ">=3.7"
summary = "WSGI HTTP Server for UNIX"
groups = ["default"]
dependencies = [
"importlib-metadata; python_version < \"3.8\"",
"packaging",
]
files = [
{file = "gunicorn-23.0.0-py3-none-any.whl", hash = "sha256:ec400d38950de4dfd418cff8328b2c8faed0edb0d517d3394e457c317908ca4d"},
{file = "gunicorn-23.0.0.tar.gz", hash = "sha256:f014447a0101dc57e294f6c18ca6b40227a4c90e9bdb586042628030cba004ec"},
]
[[package]]
name = "h11"
version = "0.14.0"
requires_python = ">=3.7"
summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1"
groups = ["default"]
dependencies = [
"typing-extensions; python_version < \"3.8\"",
]
files = [
{file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"},
{file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"},
]
[[package]]
name = "hishel"
version = "0.0.33"
requires_python = ">=3.8"
summary = "Persistent cache implementation for httpx and httpcore"
groups = ["default"]
dependencies = [
"httpx>=0.22.0",
"typing-extensions>=4.8.0",
]
files = [
{file = "hishel-0.0.33-py3-none-any.whl", hash = "sha256:6e6c6cdaf432ff4c4981e7792ef7d1fa4c8ede58b9dbbcefb9ab3fc9770f2a07"},
{file = "hishel-0.0.33.tar.gz", hash = "sha256:ab5b2661d5e2252f305fd0fb20e8c76bfab3ea73458f20f2591c53c37b270089"},
]
[[package]]
name = "httpcore"
version = "1.0.7"
requires_python = ">=3.8"
summary = "A minimal low-level HTTP client."
groups = ["default"]
dependencies = [
"certifi",
"h11<0.15,>=0.13",
]
files = [
{file = "httpcore-1.0.7-py3-none-any.whl", hash = "sha256:a3fff8f43dc260d5bd363d9f9cf1830fa3a458b332856f34282de498ed420edd"},
{file = "httpcore-1.0.7.tar.gz", hash = "sha256:8551cb62a169ec7162ac7be8d4817d561f60e08eaa485234898414bb5a8a0b4c"},
]
[[package]]
name = "httpx"
version = "0.27.2"
requires_python = ">=3.8"
summary = "The next generation HTTP client."
groups = ["default"]
dependencies = [
"anyio",
"certifi",
"httpcore==1.*",
"idna",
"sniffio",
]
files = [
{file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"},
{file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"},
]
[[package]]
name = "httpx"
version = "0.27.2"
extras = ["socks"]
requires_python = ">=3.8"
summary = "The next generation HTTP client."
groups = ["default"]
dependencies = [
"httpx==0.27.2",
"socksio==1.*",
]
files = [
{file = "httpx-0.27.2-py3-none-any.whl", hash = "sha256:7bb2708e112d8fdd7829cd4243970f0c223274051cb35ee80c03301ee29a3df0"},
{file = "httpx-0.27.2.tar.gz", hash = "sha256:f7c2be1d2f3c3c3160d441802406b206c2b76f5947b11115e6df10c6c65e66c2"},
]
[[package]]
name = "icecream"
version = "2.1.3"
summary = "Never use print() to debug again; inspect variables, expressions, and program execution with a single, simple function call."
groups = ["local"]
dependencies = [
"asttokens>=2.0.1",
"colorama>=0.3.9",
"executing>=0.3.1",
"pygments>=2.2.0",
]
files = [
{file = "icecream-2.1.3-py2.py3-none-any.whl", hash = "sha256:757aec31ad4488b949bc4f499d18e6e5973c40cc4d4fc607229e78cfaec94c34"},
{file = "icecream-2.1.3.tar.gz", hash = "sha256:0aa4a7c3374ec36153a1d08f81e3080e83d8ac1eefd97d2f4fe9544e8f9b49de"},
]
[[package]]
name = "identify"
version = "2.6.2"
requires_python = ">=3.9"
summary = "File identification library for Python"
groups = ["dev"]
files = [
{file = "identify-2.6.2-py2.py3-none-any.whl", hash = "sha256:c097384259f49e372f4ea00a19719d95ae27dd5ff0fd77ad630aa891306b82f3"},
{file = "identify-2.6.2.tar.gz", hash = "sha256:fab5c716c24d7a789775228823797296a2994b075fb6080ac83a102772a98cbd"},
]
[[package]]
name = "idna"
version = "3.10"
requires_python = ">=3.6"
summary = "Internationalized Domain Names in Applications (IDNA)"
groups = ["default", "watchfiles"]
files = [
{file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
{file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
]
[[package]]
name = "installer"
version = "0.7.0"
requires_python = ">=3.7"
summary = "A library for installing Python wheels."
groups = ["default"]
files = [
{file = "installer-0.7.0-py3-none-any.whl", hash = "sha256:05d1933f0a5ba7d8d6296bb6d5018e7c94fa473ceb10cf198a92ccea19c27b53"},
{file = "installer-0.7.0.tar.gz", hash = "sha256:a26d3e3116289bb08216e0d0f7d925fcef0b0194eedfa0c944bcaaa106c4b631"},
]
[[package]]
name = "isort"
version = "5.13.2"
requires_python = ">=3.8.0"
summary = "A Python utility / library to sort Python imports."
groups = ["static-analysis"]
files = [
{file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"},
{file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"},
]
[[package]]
name = "jinja2"
version = "3.1.4"
requires_python = ">=3.7"
summary = "A very fast and expressive template engine."
groups = ["default"]
dependencies = [
"MarkupSafe>=2.0",
]
files = [
{file = "jinja2-3.1.4-py3-none-any.whl", hash = "sha256:bc5dd2abb727a5319567b7a813e6a2e7318c39f4f487cfe6c89c6f9c7d25197d"},
{file = "jinja2-3.1.4.tar.gz", hash = "sha256:4a3aee7acbbe7303aede8e9648d13b8bf88a429282aa6122a993f0ac800cb369"},
]
[[package]]
name = "jmespath"
version = "1.0.1"
requires_python = ">=3.7"
summary = "JSON Matching Expressions"
groups = ["default"]
files = [
{file = "jmespath-1.0.1-py3-none-any.whl", hash = "sha256:02e2e4cc71b5bcab88332eebf907519190dd9e6e82107fa7f83b1003a6252980"},
{file = "jmespath-1.0.1.tar.gz", hash = "sha256:90261b206d6defd58fdd5e85f478bf633a2901798906be2ad389150c5c60edbe"},
]
[[package]]
name = "jsbeautifier"
version = "1.15.1"
summary = "JavaScript unobfuscator and beautifier."
groups = ["lint"]
dependencies = [
"editorconfig>=0.12.2",
"six>=1.13.0",
]
files = [
{file = "jsbeautifier-1.15.1.tar.gz", hash = "sha256:ebd733b560704c602d744eafc839db60a1ee9326e30a2a80c4adb8718adc1b24"},
]
[[package]]
name = "json5"
version = "0.9.28"
requires_python = ">=3.8.0"
summary = "A Python implementation of the JSON5 data format."
groups = ["lint"]
files = [
{file = "json5-0.9.28-py3-none-any.whl", hash = "sha256:29c56f1accdd8bc2e037321237662034a7e07921e2b7223281a5ce2c46f0c4df"},
{file = "json5-0.9.28.tar.gz", hash = "sha256:1f82f36e615bc5b42f1bbd49dbc94b12563c56408c6ffa06414ea310890e9a6e"},
]
[[package]]
name = "jwcrypto"
version = "1.5.6"
requires_python = ">= 3.8"
summary = "Implementation of JOSE Web standards"
groups = ["default"]
dependencies = [
"cryptography>=3.4",
"typing-extensions>=4.5.0",
]
files = [
{file = "jwcrypto-1.5.6-py3-none-any.whl", hash = "sha256:150d2b0ebbdb8f40b77f543fb44ffd2baeff48788be71f67f03566692fd55789"},
{file = "jwcrypto-1.5.6.tar.gz", hash = "sha256:771a87762a0c081ae6166958a954f80848820b2ab066937dc8b8379d65b1b039"},
]
[[package]]
name = "lxml"
version = "5.3.0"
requires_python = ">=3.6"
summary = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API."
groups = ["default"]
files = [
{file = "lxml-5.3.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:8c72e9563347c7395910de6a3100a4840a75a6f60e05af5e58566868d5eb2d6a"},
{file = "lxml-5.3.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e92ce66cd919d18d14b3856906a61d3f6b6a8500e0794142338da644260595cd"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d04f064bebdfef9240478f7a779e8c5dc32b8b7b0b2fc6a62e39b928d428e51"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c2fb570d7823c2bbaf8b419ba6e5662137f8166e364a8b2b91051a1fb40ab8b"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0c120f43553ec759f8de1fee2f4794452b0946773299d44c36bfe18e83caf002"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:562e7494778a69086f0312ec9689f6b6ac1c6b65670ed7d0267e49f57ffa08c4"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:423b121f7e6fa514ba0c7918e56955a1d4470ed35faa03e3d9f0e3baa4c7e492"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c00f323cc00576df6165cc9d21a4c21285fa6b9989c5c39830c3903dc4303ef3"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:1fdc9fae8dd4c763e8a31e7630afef517eab9f5d5d31a278df087f307bf601f4"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:658f2aa69d31e09699705949b5fc4719cbecbd4a97f9656a232e7d6c7be1a367"},
{file = "lxml-5.3.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1473427aff3d66a3fa2199004c3e601e6c4500ab86696edffdbc84954c72d832"},
{file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a87de7dd873bf9a792bf1e58b1c3887b9264036629a5bf2d2e6579fe8e73edff"},
{file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:0d7b36afa46c97875303a94e8f3ad932bf78bace9e18e603f2085b652422edcd"},
{file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:cf120cce539453ae086eacc0130a324e7026113510efa83ab42ef3fcfccac7fb"},
{file = "lxml-5.3.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:df5c7333167b9674aa8ae1d4008fa4bc17a313cc490b2cca27838bbdcc6bb15b"},
{file = "lxml-5.3.0-cp313-cp313-win32.whl", hash = "sha256:c802e1c2ed9f0c06a65bc4ed0189d000ada8049312cfeab6ca635e39c9608957"},
{file = "lxml-5.3.0-cp313-cp313-win_amd64.whl", hash = "sha256:406246b96d552e0503e17a1006fd27edac678b3fcc9f1be71a2f94b4ff61528d"},
{file = "lxml-5.3.0.tar.gz", hash = "sha256:4e109ca30d1edec1ac60cdbe341905dc3b8f55b16855e03a54aaf59e51ec8c6f"},
]
[[package]]
name = "markdown-it-py"
version = "3.0.0"
requires_python = ">=3.8"
summary = "Python port of markdown-it. Markdown parsing, done right!"
groups = ["default"]
dependencies = [
"mdurl~=0.1",
]
files = [
{file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"},
{file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"},
]
[[package]]
name = "markdownify"
version = "0.13.1"
summary = "Convert HTML to markdown."
groups = ["default"]
dependencies = [
"beautifulsoup4<5,>=4.9",
"six<2,>=1.15",
]
files = [
{file = "markdownify-0.13.1-py3-none-any.whl", hash = "sha256:1d181d43d20902bcc69d7be85b5316ed174d0dda72ff56e14ae4c95a4a407d22"},
{file = "markdownify-0.13.1.tar.gz", hash = "sha256:ab257f9e6bd4075118828a28c9d02f8a4bfeb7421f558834aa79b2dfeb32a098"},
]
[[package]]
name = "markupsafe"
version = "3.0.2"
requires_python = ">=3.9"
summary = "Safely add untrusted strings to HTML/XML markup."
groups = ["default"]
files = [
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"},
{file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"},
{file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"},
{file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"},
{file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"},
{file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"},
{file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"},
]
[[package]]
name = "mccabe"
version = "0.7.0"
requires_python = ">=3.6"
summary = "McCabe checker, plugin for flake8"
groups = ["static-analysis"]
files = [
{file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"},
{file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"},
]
[[package]]
name = "mdurl"
version = "0.1.2"
requires_python = ">=3.7"
summary = "Markdown URL utilities"
groups = ["default"]
files = [
{file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"},
{file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"},
]
[[package]]
name = "mistletoe"
version = "1.4.0"
requires_python = "~=3.5"
summary = "A fast, extensible Markdown parser in pure Python."
groups = ["default"]
files = [
{file = "mistletoe-1.4.0-py3-none-any.whl", hash = "sha256:44a477803861de1237ba22e375c6b617690a31d2902b47279d1f8f7ed498a794"},
{file = "mistletoe-1.4.0.tar.gz", hash = "sha256:1630f906e5e4bbe66fdeb4d29d277e2ea515d642bb18a9b49b136361a9818c9d"},
]
[[package]]
name = "msgpack"
version = "1.1.0"
requires_python = ">=3.8"
summary = "MessagePack serializer"
groups = ["default"]
files = [
{file = "msgpack-1.1.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:071603e2f0771c45ad9bc65719291c568d4edf120b44eb36324dcb02a13bfddf"},
{file = "msgpack-1.1.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0f92a83b84e7c0749e3f12821949d79485971f087604178026085f60ce109330"},
{file = "msgpack-1.1.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a1964df7b81285d00a84da4e70cb1383f2e665e0f1f2a7027e683956d04b734"},
{file = "msgpack-1.1.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:59caf6a4ed0d164055ccff8fe31eddc0ebc07cf7326a2aaa0dbf7a4001cd823e"},
{file = "msgpack-1.1.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0907e1a7119b337971a689153665764adc34e89175f9a34793307d9def08e6ca"},
{file = "msgpack-1.1.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:65553c9b6da8166e819a6aa90ad15288599b340f91d18f60b2061f402b9a4915"},
{file = "msgpack-1.1.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:7a946a8992941fea80ed4beae6bff74ffd7ee129a90b4dd5cf9c476a30e9708d"},
{file = "msgpack-1.1.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:4b51405e36e075193bc051315dbf29168d6141ae2500ba8cd80a522964e31434"},
{file = "msgpack-1.1.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:b4c01941fd2ff87c2a934ee6055bda4ed353a7846b8d4f341c428109e9fcde8c"},
{file = "msgpack-1.1.0-cp313-cp313-win32.whl", hash = "sha256:7c9a35ce2c2573bada929e0b7b3576de647b0defbd25f5139dcdaba0ae35a4cc"},
{file = "msgpack-1.1.0-cp313-cp313-win_amd64.whl", hash = "sha256:bce7d9e614a04d0883af0b3d4d501171fbfca038f12c77fa838d9f198147a23f"},
{file = "msgpack-1.1.0.tar.gz", hash = "sha256:dd432ccc2c72b914e4cb77afce64aab761c1137cc698be3984eee260bcb2896e"},
]
[[package]]
name = "nodeenv"
version = "1.9.1"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7"
summary = "Node.js virtual environment builder"
groups = ["dev"]
files = [
{file = "nodeenv-1.9.1-py2.py3-none-any.whl", hash = "sha256:ba11c9782d29c27c70ffbdda2d7415098754709be8a7056d79a737cd901155c9"},
{file = "nodeenv-1.9.1.tar.gz", hash = "sha256:6ec12890a2dab7946721edbfbcd91f3319c6ccc9aec47be7c7e6b7011ee6645f"},
]
[[package]]
name = "numpy"
version = "2.1.3"
requires_python = ">=3.10"
summary = "Fundamental package for array computing in Python"
groups = ["default"]
marker = "python_version >= \"3.12\""
files = [
{file = "numpy-2.1.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:96fe52fcdb9345b7cd82ecd34547fca4321f7656d500eca497eb7ea5a926692f"},
{file = "numpy-2.1.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f653490b33e9c3a4c1c01d41bc2aef08f9475af51146e4a7710c450cf9761598"},
{file = "numpy-2.1.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:dc258a761a16daa791081d026f0ed4399b582712e6fc887a95af09df10c5ca57"},
{file = "numpy-2.1.3-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:016d0f6f5e77b0f0d45d77387ffa4bb89816b57c835580c3ce8e099ef830befe"},
{file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c181ba05ce8299c7aa3125c27b9c2167bca4a4445b7ce73d5febc411ca692e43"},
{file = "numpy-2.1.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5641516794ca9e5f8a4d17bb45446998c6554704d888f86df9b200e66bdcce56"},
{file = "numpy-2.1.3-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:ea4dedd6e394a9c180b33c2c872b92f7ce0f8e7ad93e9585312b0c5a04777a4a"},
{file = "numpy-2.1.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:b0df3635b9c8ef48bd3be5f862cf71b0a4716fa0e702155c45067c6b711ddcef"},
{file = "numpy-2.1.3-cp313-cp313-win32.whl", hash = "sha256:50ca6aba6e163363f132b5c101ba078b8cbd3fa92c7865fd7d4d62d9779ac29f"},
{file = "numpy-2.1.3-cp313-cp313-win_amd64.whl", hash = "sha256:747641635d3d44bcb380d950679462fae44f54b131be347d5ec2bce47d3df9ed"},
{file = "numpy-2.1.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:996bb9399059c5b82f76b53ff8bb686069c05acc94656bb259b1d63d04a9506f"},
{file = "numpy-2.1.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:45966d859916ad02b779706bb43b954281db43e185015df6eb3323120188f9e4"},
{file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:baed7e8d7481bfe0874b566850cb0b85243e982388b7b23348c6db2ee2b2ae8e"},
{file = "numpy-2.1.3-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:a9f7f672a3388133335589cfca93ed468509cb7b93ba3105fce780d04a6576a0"},
{file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7aac50327da5d208db2eec22eb11e491e3fe13d22653dce51b0f4109101b408"},
{file = "numpy-2.1.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4394bc0dbd074b7f9b52024832d16e019decebf86caf909d94f6b3f77a8ee3b6"},
{file = "numpy-2.1.3-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:50d18c4358a0a8a53f12a8ba9d772ab2d460321e6a93d6064fc22443d189853f"},
{file = "numpy-2.1.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:14e253bd43fc6b37af4921b10f6add6925878a42a0c5fe83daee390bca80bc17"},
{file = "numpy-2.1.3-cp313-cp313t-win32.whl", hash = "sha256:08788d27a5fd867a663f6fc753fd7c3ad7e92747efc73c53bca2f19f8bc06f48"},
{file = "numpy-2.1.3-cp313-cp313t-win_amd64.whl", hash = "sha256:2564fbdf2b99b3f815f2107c1bbc93e2de8ee655a69c261363a1172a79a257d4"},
{file = "numpy-2.1.3.tar.gz", hash = "sha256:aa08e04e08aaf974d4458def539dece0d28146d866a39da5639596f4921fd761"},
]
[[package]]
name = "oauthlib"
version = "3.2.2"
requires_python = ">=3.6"
summary = "A generic, spec-compliant, thorough implementation of the OAuth request-signing logic"
groups = ["default"]
files = [
{file = "oauthlib-3.2.2-py3-none-any.whl", hash = "sha256:8139f29aac13e25d502680e9e19963e83f16838d48a0d71c287fe40e7067fbca"},
{file = "oauthlib-3.2.2.tar.gz", hash = "sha256:9859c40929662bec5d64f34d01c99e093149682a3f38915dc0655d5a633dd918"},
]
[[package]]
name = "odfpy"
version = "1.4.1"
summary = "Python API and tools to manipulate OpenDocument files"
groups = ["default"]
dependencies = [
"defusedxml",
]
files = [
{file = "odfpy-1.4.1.tar.gz", hash = "sha256:db766a6e59c5103212f3cc92ec8dd50a0f3a02790233ed0b52148b70d3c438ec"},
]
[[package]]
name = "openpyxl"
version = "3.1.5"
requires_python = ">=3.8"
summary = "A Python library to read/write Excel 2010 xlsx/xlsm files"
groups = ["default"]
dependencies = [
"et-xmlfile",
]
files = [
{file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"},
{file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"},
]
[[package]]
name = "ordered-set"
version = "4.1.0"
requires_python = ">=3.7"
summary = "An OrderedSet is a custom MutableSet that remembers its order, so that every"
groups = ["default"]
files = [
{file = "ordered-set-4.1.0.tar.gz", hash = "sha256:694a8e44c87657c59292ede72891eb91d34131f6531463aab3009191c77364a8"},
{file = "ordered_set-4.1.0-py3-none-any.whl", hash = "sha256:046e1132c71fcf3330438a539928932caf51ddbc582496833e23de611de14562"},
]
[[package]]
name = "packaging"
version = "24.2"
requires_python = ">=3.8"
summary = "Core utilities for Python packages"
groups = ["default", "dev"]
files = [
{file = "packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759"},
{file = "packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f"},
]
[[package]]
name = "pandas"
version = "2.2.3"
requires_python = ">=3.9"
summary = "Powerful data structures for data analysis, time series, and statistics"
groups = ["default"]
dependencies = [
"numpy>=1.22.4; python_version < \"3.11\"",
"numpy>=1.23.2; python_version == \"3.11\"",
"numpy>=1.26.0; python_version >= \"3.12\"",
"python-dateutil>=2.8.2",
"pytz>=2020.1",
"tzdata>=2022.7",
]
files = [
{file = "pandas-2.2.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f00d1345d84d8c86a63e476bb4955e46458b304b9575dcf71102b5c705320015"},
{file = "pandas-2.2.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:3508d914817e153ad359d7e069d752cdd736a247c322d932eb89e6bc84217f28"},
{file = "pandas-2.2.3-cp313-cp313-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:22a9d949bfc9a502d320aa04e5d02feab689d61da4e7764b62c30b991c42c5f0"},
{file = "pandas-2.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f3a255b2c19987fbbe62a9dfd6cff7ff2aa9ccab3fc75218fd4b7530f01efa24"},
{file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:800250ecdadb6d9c78eae4990da62743b857b470883fa27f652db8bdde7f6659"},
{file = "pandas-2.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6374c452ff3ec675a8f46fd9ab25c4ad0ba590b71cf0656f8b6daa5202bca3fb"},
{file = "pandas-2.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:61c5ad4043f791b61dd4752191d9f07f0ae412515d59ba8f005832a532f8736d"},
{file = "pandas-2.2.3-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:3b71f27954685ee685317063bf13c7709a7ba74fc996b84fc6821c59b0f06468"},
{file = "pandas-2.2.3-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:38cf8125c40dae9d5acc10fa66af8ea6fdf760b2714ee482ca691fc66e6fcb18"},
{file = "pandas-2.2.3-cp313-cp313t-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:ba96630bc17c875161df3818780af30e43be9b166ce51c9a18c1feae342906c2"},
{file = "pandas-2.2.3-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1db71525a1538b30142094edb9adc10be3f3e176748cd7acc2240c2f2e5aa3a4"},
{file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:15c0e1e02e93116177d29ff83e8b1619c93ddc9c49083f237d4312337a61165d"},
{file = "pandas-2.2.3-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:ad5b65698ab28ed8d7f18790a0dc58005c7629f227be9ecc1072aa74c0c1d43a"},
{file = "pandas-2.2.3.tar.gz", hash = "sha256:4f18ba62b61d7e192368b84517265a99b4d7ee8912f8708660fb4a366cc82667"},
]
[[package]]
name = "pathspec"
version = "0.12.1"
requires_python = ">=3.8"
summary = "Utility library for gitignore style pattern matching of file paths."
groups = ["lint"]
files = [
{file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"},
{file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"},
]
[[package]]
name = "pbs-installer"
version = "2024.10.16"
requires_python = ">=3.8"
summary = "Installer for Python Build Standalone"
groups = ["default"]
files = [
{file = "pbs_installer-2024.10.16-py3-none-any.whl", hash = "sha256:043f157ae0939b403b98b410f92bcc1d52062c8ced46e52ff0fdb45d37320a25"},
{file = "pbs_installer-2024.10.16.tar.gz", hash = "sha256:d547d9a5bb564791102d138346bff609659c16acc0147fd701755a2eae8f2050"},
]
[[package]]
name = "pdm"
version = "2.21.0"
requires_python = ">=3.9"
summary = "A modern Python package and dependency manager supporting the latest PEP standards"
groups = ["default"]
dependencies = [
"blinker",
"certifi>=2024.8.30",
"dep-logic>=0.4.4",
"filelock>=3.13",
"findpython<1.0.0a0,>=0.6.0",
"hishel>=0.0.32",
"httpcore>=1.0.6",
"httpx[socks]<1,>0.20",
"importlib-metadata>=3.6; python_version < \"3.10\"",
"installer<0.8,>=0.7",
"msgpack>=1.0",
"packaging!=22.0,>=20.9",
"pbs-installer>=2024.4.18",
"platformdirs",
"pyproject-hooks",
"python-dotenv>=0.15",
"resolvelib>=1.1",
"rich>=12.3.0",
"shellingham>=1.3.2",
"tomli>=1.1.0; python_version < \"3.11\"",
"tomlkit<1,>=0.11.1",
"truststore>=0.9; python_version >= \"3.10\"",
"unearth>=0.17.0",
"virtualenv>=20",
]
files = [
{file = "pdm-2.21.0-py3-none-any.whl", hash = "sha256:c01a50622072a9529bd9c7f8c1ce8d050b7e340d25d051233bce9fcdd8449614"},
{file = "pdm-2.21.0.tar.gz", hash = "sha256:9c928d6db62d104ab86318fe09aaf9bdfc6f616176af407e4df00f59e001930f"},
]
[[package]]
name = "pillow"
version = "10.4.0"
requires_python = ">=3.8"
summary = "Python Imaging Library (Fork)"
groups = ["default"]
files = [
{file = "pillow-10.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:8bc1a764ed8c957a2e9cacf97c8b2b053b70307cf2996aafd70e91a082e70df3"},
{file = "pillow-10.4.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:6209bb41dc692ddfee4942517c19ee81b86c864b626dbfca272ec0f7cff5d9fb"},
{file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bee197b30783295d2eb680b311af15a20a8b24024a19c3a26431ff83eb8d1f70"},
{file = "pillow-10.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1ef61f5dd14c300786318482456481463b9d6b91ebe5ef12f405afbba77ed0be"},
{file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:297e388da6e248c98bc4a02e018966af0c5f92dfacf5a5ca22fa01cb3179bca0"},
{file = "pillow-10.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:e4db64794ccdf6cb83a59d73405f63adbe2a1887012e308828596100a0b2f6cc"},
{file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bd2880a07482090a3bcb01f4265f1936a903d70bc740bfcb1fd4e8a2ffe5cf5a"},
{file = "pillow-10.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4b35b21b819ac1dbd1233317adeecd63495f6babf21b7b2512d244ff6c6ce309"},
{file = "pillow-10.4.0-cp313-cp313-win32.whl", hash = "sha256:551d3fd6e9dc15e4c1eb6fc4ba2b39c0c7933fa113b220057a34f4bb3268a060"},
{file = "pillow-10.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:030abdbe43ee02e0de642aee345efa443740aa4d828bfe8e2eb11922ea6a21ea"},
{file = "pillow-10.4.0-cp313-cp313-win_arm64.whl", hash = "sha256:5b001114dd152cfd6b23befeb28d7aee43553e2402c9f159807bf55f33af8a8d"},
{file = "pillow-10.4.0.tar.gz", hash = "sha256:166c1cd4d24309b30d61f79f4a9114b7b2313d7450912277855ff5dfd7cd4a06"},
]
[[package]]
name = "platformdirs"
version = "4.3.6"
requires_python = ">=3.8"
summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`."
groups = ["default", "dev", "static-analysis"]
files = [
{file = "platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb"},
{file = "platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907"},
]
[[package]]
name = "pluggy"
version = "1.5.0"
requires_python = ">=3.8"
summary = "plugin and hook calling mechanisms for python"
groups = ["dev"]
files = [
{file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"},
{file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"},
]
[[package]]
name = "pre-commit"
version = "4.0.1"
requires_python = ">=3.9"
summary = "A framework for managing and maintaining multi-language pre-commit hooks."
groups = ["dev"]
dependencies = [
"cfgv>=2.0.0",
"identify>=1.0.0",
"nodeenv>=0.11.1",
"pyyaml>=5.1",
"virtualenv>=20.10.0",
]
files = [
{file = "pre_commit-4.0.1-py2.py3-none-any.whl", hash = "sha256:efde913840816312445dc98787724647c65473daefe420785f885e8ed9a06878"},
{file = "pre_commit-4.0.1.tar.gz", hash = "sha256:80905ac375958c0444c65e9cebebd948b3cdb518f335a091a670a89d652139d2"},
]
[[package]]
name = "psycopg"
version = "3.2.3"
requires_python = ">=3.8"
summary = "PostgreSQL database adapter for Python"
groups = ["default"]
dependencies = [
"backports-zoneinfo>=0.2.0; python_version < \"3.9\"",
"typing-extensions>=4.6; python_version < \"3.13\"",
"tzdata; sys_platform == \"win32\"",
]
files = [
{file = "psycopg-3.2.3-py3-none-any.whl", hash = "sha256:644d3973fe26908c73d4be746074f6e5224b03c1101d302d9a53bf565ad64907"},
{file = "psycopg-3.2.3.tar.gz", hash = "sha256:a5764f67c27bec8bfac85764d23c534af2c27b893550377e37ce59c12aac47a2"},
]
[[package]]
name = "psycopg-binary"
version = "3.2.3"
requires_python = ">=3.8"
summary = "PostgreSQL database adapter for Python -- C optimisation distribution"
groups = ["default"]
marker = "implementation_name != \"pypy\""
files = [
{file = "psycopg_binary-3.2.3-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:41fdec0182efac66b27478ac15ef54c9ebcecf0e26ed467eb7d6f262a913318b"},
{file = "psycopg_binary-3.2.3-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:07d019a786eb020c0f984691aa1b994cb79430061065a694cf6f94056c603d26"},
{file = "psycopg_binary-3.2.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4c57615791a337378fe5381143259a6c432cdcbb1d3e6428bfb7ce59fff3fb5c"},
{file = "psycopg_binary-3.2.3-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e8eb9a4e394926b93ad919cad1b0a918e9b4c846609e8c1cfb6b743683f64da0"},
{file = "psycopg_binary-3.2.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5905729668ef1418bd36fbe876322dcb0f90b46811bba96d505af89e6fbdce2f"},
{file = "psycopg_binary-3.2.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd65774ed7d65101b314808b6893e1a75b7664f680c3ef18d2e5c84d570fa393"},
{file = "psycopg_binary-3.2.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:700679c02f9348a0d0a2adcd33a0275717cd0d0aee9d4482b47d935023629505"},
{file = "psycopg_binary-3.2.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96334bb64d054e36fed346c50c4190bad9d7c586376204f50bede21a913bf942"},
{file = "psycopg_binary-3.2.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:9099e443d4cc24ac6872e6a05f93205ba1a231b1a8917317b07c9ef2b955f1f4"},
{file = "psycopg_binary-3.2.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:1985ab05e9abebfbdf3163a16ebb37fbc5d49aff2bf5b3d7375ff0920bbb54cd"},
{file = "psycopg_binary-3.2.3-cp313-cp313-win_amd64.whl", hash = "sha256:e90352d7b610b4693fad0feea48549d4315d10f1eba5605421c92bb834e90170"},
]
[[package]]
name = "psycopg-pool"
version = "3.2.4"
requires_python = ">=3.8"
summary = "Connection Pool for Psycopg"
groups = ["default"]
dependencies = [
"typing-extensions>=4.6",
]
files = [
{file = "psycopg_pool-3.2.4-py3-none-any.whl", hash = "sha256:f6a22cff0f21f06d72fb2f5cb48c618946777c49385358e0c88d062c59cbd224"},
{file = "psycopg_pool-3.2.4.tar.gz", hash = "sha256:61774b5bbf23e8d22bedc7504707135aaf744679f8ef9b3fe29942920746a6ed"},
]
[[package]]
name = "psycopg"
version = "3.2.3"
extras = ["binary", "pool"]
requires_python = ">=3.8"
summary = "PostgreSQL database adapter for Python"
groups = ["default"]
dependencies = [
"psycopg-binary==3.2.3; implementation_name != \"pypy\"",
"psycopg-pool",
"psycopg==3.2.3",
]
files = [
{file = "psycopg-3.2.3-py3-none-any.whl", hash = "sha256:644d3973fe26908c73d4be746074f6e5224b03c1101d302d9a53bf565ad64907"},
{file = "psycopg-3.2.3.tar.gz", hash = "sha256:a5764f67c27bec8bfac85764d23c534af2c27b893550377e37ce59c12aac47a2"},
]
[[package]]
name = "pycparser"
version = "2.22"
requires_python = ">=3.8"
summary = "C parser in Python"
groups = ["default"]
marker = "platform_python_implementation != \"PyPy\""
files = [
{file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
{file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
]
[[package]]
name = "pydantic"
version = "2.10.2"
requires_python = ">=3.8"
summary = "Data validation using Python type hints"
groups = ["default"]
dependencies = [
"annotated-types>=0.6.0",
"pydantic-core==2.27.1",
"typing-extensions>=4.12.2",
]
files = [
{file = "pydantic-2.10.2-py3-none-any.whl", hash = "sha256:cfb96e45951117c3024e6b67b25cdc33a3cb7b2fa62e239f7af1378358a1d99e"},
{file = "pydantic-2.10.2.tar.gz", hash = "sha256:2bc2d7f17232e0841cbba4641e65ba1eb6fafb3a08de3a091ff3ce14a197c4fa"},
]
[[package]]
name = "pydantic-core"
version = "2.27.1"
requires_python = ">=3.8"
summary = "Core functionality for Pydantic validation and serialization"
groups = ["default"]
dependencies = [
"typing-extensions!=4.7.0,>=4.6.0",
]
files = [
{file = "pydantic_core-2.27.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:f216dbce0e60e4d03e0c4353c7023b202d95cbaeff12e5fd2e82ea0a66905073"},
{file = "pydantic_core-2.27.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:a2e02889071850bbfd36b56fd6bc98945e23670773bc7a76657e90e6b6603c08"},
{file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:42b0e23f119b2b456d07ca91b307ae167cc3f6c846a7b169fca5326e32fdc6cf"},
{file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:764be71193f87d460a03f1f7385a82e226639732214b402f9aa61f0d025f0737"},
{file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1c00666a3bd2f84920a4e94434f5974d7bbc57e461318d6bb34ce9cdbbc1f6b2"},
{file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3ccaa88b24eebc0f849ce0a4d09e8a408ec5a94afff395eb69baf868f5183107"},
{file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c65af9088ac534313e1963443d0ec360bb2b9cba6c2909478d22c2e363d98a51"},
{file = "pydantic_core-2.27.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:206b5cf6f0c513baffaeae7bd817717140770c74528f3e4c3e1cec7871ddd61a"},
{file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:062f60e512fc7fff8b8a9d680ff0ddaaef0193dba9fa83e679c0c5f5fbd018bc"},
{file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_armv7l.whl", hash = "sha256:a0697803ed7d4af5e4c1adf1670af078f8fcab7a86350e969f454daf598c4960"},
{file = "pydantic_core-2.27.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:58ca98a950171f3151c603aeea9303ef6c235f692fe555e883591103da709b23"},
{file = "pydantic_core-2.27.1-cp313-none-win32.whl", hash = "sha256:8065914ff79f7eab1599bd80406681f0ad08f8e47c880f17b416c9f8f7a26d05"},
{file = "pydantic_core-2.27.1-cp313-none-win_amd64.whl", hash = "sha256:ba630d5e3db74c79300d9a5bdaaf6200172b107f263c98a0539eeecb857b2337"},
{file = "pydantic_core-2.27.1-cp313-none-win_arm64.whl", hash = "sha256:45cf8588c066860b623cd11c4ba687f8d7175d5f7ef65f7129df8a394c502de5"},
{file = "pydantic_core-2.27.1.tar.gz", hash = "sha256:62a763352879b84aa31058fc931884055fd75089cccbd9d58bb6afd01141b235"},
]
[[package]]
name = "pygments"
version = "2.18.0"
requires_python = ">=3.8"
summary = "Pygments is a syntax highlighting package written in Python."
groups = ["default", "local"]
files = [
{file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"},
{file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"},
]
[[package]]
name = "pyjwt"
version = "2.9.0"
requires_python = ">=3.8"
summary = "JSON Web Token implementation in Python"
groups = ["default"]
files = [
{file = "PyJWT-2.9.0-py3-none-any.whl", hash = "sha256:3b02fb0f44517787776cf48f2ae25d8e14f300e6d7545a4315cee571a415e850"},
{file = "pyjwt-2.9.0.tar.gz", hash = "sha256:7e1e5b56cc735432a7369cbfa0efe50fa113ebecdc04ae6922deba8b84582d0c"},
]
[[package]]
name = "pylint"
version = "3.3.1"
requires_python = ">=3.9.0"
summary = "python code static checker"
groups = ["static-analysis"]
dependencies = [
"astroid<=3.4.0-dev0,>=3.3.4",
"colorama>=0.4.5; sys_platform == \"win32\"",
"dill>=0.2; python_version < \"3.11\"",
"dill>=0.3.6; python_version >= \"3.11\"",
"dill>=0.3.7; python_version >= \"3.12\"",
"isort!=5.13.0,<6,>=4.2.5",
"mccabe<0.8,>=0.6",
"platformdirs>=2.2.0",
"tomli>=1.1.0; python_version < \"3.11\"",
"tomlkit>=0.10.1",
"typing-extensions>=3.10.0; python_version < \"3.10\"",
]
files = [
{file = "pylint-3.3.1-py3-none-any.whl", hash = "sha256:2f846a466dd023513240bc140ad2dd73bfc080a5d85a710afdb728c420a5a2b9"},
{file = "pylint-3.3.1.tar.gz", hash = "sha256:9f3dcc87b1203e612b78d91a896407787e708b3f189b5fa0b307712d49ff0c6e"},
]
[[package]]
name = "pylint-django"
version = "2.6.1"
requires_python = "<4.0,>=3.9"
summary = "A Pylint plugin to help Pylint understand the Django web framework"
groups = ["static-analysis"]
dependencies = [
"pylint-plugin-utils>=0.8",
"pylint<4,>=3.0",
]
files = [
{file = "pylint-django-2.6.1.tar.gz", hash = "sha256:19e8c85a8573a04e3de7be2ba91e9a7c818ebf05e1b617be2bbae67a906b725f"},
{file = "pylint_django-2.6.1-py3-none-any.whl", hash = "sha256:359f68fe8c810ee6bc8e1ab4c83c19b15a43b234a24b08978f47a23462b5ce28"},
]
[[package]]
name = "pylint-plugin-utils"
version = "0.8.2"
requires_python = ">=3.7,<4.0"
summary = "Utilities and helpers for writing Pylint plugins"
groups = ["static-analysis"]
dependencies = [
"pylint>=1.7",
]
files = [
{file = "pylint_plugin_utils-0.8.2-py3-none-any.whl", hash = "sha256:ae11664737aa2effbf26f973a9e0b6779ab7106ec0adc5fe104b0907ca04e507"},
{file = "pylint_plugin_utils-0.8.2.tar.gz", hash = "sha256:d3cebf68a38ba3fba23a873809155562571386d4c1b03e5b4c4cc26c3eee93e4"},
]
[[package]]
name = "pyproject-api"
version = "1.8.0"
requires_python = ">=3.8"
summary = "API to interact with the python pyproject.toml based projects"
groups = ["dev"]
dependencies = [
"packaging>=24.1",
"tomli>=2.0.1; python_version < \"3.11\"",
]
files = [
{file = "pyproject_api-1.8.0-py3-none-any.whl", hash = "sha256:3d7d347a047afe796fd5d1885b1e391ba29be7169bd2f102fcd378f04273d228"},
{file = "pyproject_api-1.8.0.tar.gz", hash = "sha256:77b8049f2feb5d33eefcc21b57f1e279636277a8ac8ad6b5871037b243778496"},
]
[[package]]
name = "pyproject-hooks"
version = "1.2.0"
requires_python = ">=3.7"
summary = "Wrappers to call pyproject.toml-based build backend hooks."
groups = ["default"]
files = [
{file = "pyproject_hooks-1.2.0-py3-none-any.whl", hash = "sha256:9e5c6bfa8dcc30091c74b0cf803c81fdd29d94f01992a7707bc97babb1141913"},
{file = "pyproject_hooks-1.2.0.tar.gz", hash = "sha256:1e859bd5c40fae9448642dd871adf459e5e2084186e8d2c2a79a824c970da1f8"},
]
[[package]]
name = "python-dateutil"
version = "2.9.0.post0"
requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7"
summary = "Extensions to the standard Python datetime module"
groups = ["default"]
dependencies = [
"six>=1.5",
]
files = [
{file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"},
{file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"},
]
[[package]]
name = "python-dotenv"
version = "1.0.1"
requires_python = ">=3.8"
summary = "Read key-value pairs from a .env file and set them as environment variables"
groups = ["default"]
files = [
{file = "python-dotenv-1.0.1.tar.gz", hash = "sha256:e324ee90a023d808f1959c46bcbc04446a10ced277783dc6ee09987c37ec10ca"},
{file = "python_dotenv-1.0.1-py3-none-any.whl", hash = "sha256:f7b63ef50f1b690dddf550d03497b66d609393b40b564ed0d674909a68ebf16a"},
]
[[package]]
name = "pytz"
version = "2024.2"
summary = "World timezone definitions, modern and historical"
groups = ["default"]
files = [
{file = "pytz-2024.2-py2.py3-none-any.whl", hash = "sha256:31c7c1817eb7fae7ca4b8c7ee50c72f93aa2dd863de768e1ef4245d426aa0725"},
{file = "pytz-2024.2.tar.gz", hash = "sha256:2aa355083c50a0f93fa581709deac0c9ad65cca8a9e9beac660adcbd493c798a"},
]
[[package]]
name = "pyyaml"
version = "6.0.2"
requires_python = ">=3.8"
summary = "YAML parser and emitter for Python"
groups = ["dev", "lint"]
files = [
{file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"},
{file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"},
{file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"},
{file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"},
{file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"},
{file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"},
{file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
]
[[package]]
name = "redis"
version = "5.2.0"
requires_python = ">=3.8"
summary = "Python client for Redis database and key-value store"
groups = ["default"]
dependencies = [
"async-timeout>=4.0.3; python_full_version < \"3.11.3\"",
]
files = [
{file = "redis-5.2.0-py3-none-any.whl", hash = "sha256:ae174f2bb3b1bf2b09d54bf3e51fbc1469cf6c10aa03e21141f51969801a7897"},
{file = "redis-5.2.0.tar.gz", hash = "sha256:0b1087665a771b1ff2e003aa5bdd354f15a70c9e25d5a7dbf9c722c16528a7b0"},
]
[[package]]
name = "regex"
version = "2024.11.6"
requires_python = ">=3.8"
summary = "Alternative regular expression module, to replace re."
groups = ["lint"]
files = [
{file = "regex-2024.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:a6ba92c0bcdf96cbf43a12c717eae4bc98325ca3730f6b130ffa2e3c3c723d84"},
{file = "regex-2024.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:525eab0b789891ac3be914d36893bdf972d483fe66551f79d3e27146191a37d4"},
{file = "regex-2024.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:086a27a0b4ca227941700e0b31425e7a28ef1ae8e5e05a33826e17e47fbfdba0"},
{file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bde01f35767c4a7899b7eb6e823b125a64de314a8ee9791367c9a34d56af18d0"},
{file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b583904576650166b3d920d2bcce13971f6f9e9a396c673187f49811b2769dc7"},
{file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c4de13f06a0d54fa0d5ab1b7138bfa0d883220965a29616e3ea61b35d5f5fc7"},
{file = "regex-2024.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3cde6e9f2580eb1665965ce9bf17ff4952f34f5b126beb509fee8f4e994f143c"},
{file = "regex-2024.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0d7f453dca13f40a02b79636a339c5b62b670141e63efd511d3f8f73fba162b3"},
{file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:59dfe1ed21aea057a65c6b586afd2a945de04fc7db3de0a6e3ed5397ad491b07"},
{file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:b97c1e0bd37c5cd7902e65f410779d39eeda155800b65fc4d04cc432efa9bc6e"},
{file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:f9d1e379028e0fc2ae3654bac3cbbef81bf3fd571272a42d56c24007979bafb6"},
{file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:13291b39131e2d002a7940fb176e120bec5145f3aeb7621be6534e46251912c4"},
{file = "regex-2024.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:4f51f88c126370dcec4908576c5a627220da6c09d0bff31cfa89f2523843316d"},
{file = "regex-2024.11.6-cp313-cp313-win32.whl", hash = "sha256:63b13cfd72e9601125027202cad74995ab26921d8cd935c25f09c630436348ff"},
{file = "regex-2024.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:2b3361af3198667e99927da8b84c1b010752fa4b1115ee30beaa332cabc3ef1a"},
{file = "regex-2024.11.6.tar.gz", hash = "sha256:7ab159b063c52a0333c884e4679f8d7a85112ee3078fe3d9004b2dd875585519"},
]
[[package]]
name = "requests"
version = "2.32.3"
requires_python = ">=3.8"
summary = "Python HTTP for Humans."
groups = ["default"]
dependencies = [
"certifi>=2017.4.17",
"charset-normalizer<4,>=2",
"idna<4,>=2.5",
"urllib3<3,>=1.21.1",
]
files = [
{file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"},
{file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"},
]
[[package]]
name = "requests-file"
version = "2.1.0"
summary = "File transport adapter for Requests"
groups = ["default"]
dependencies = [
"requests>=1.0.0",
]
files = [
{file = "requests_file-2.1.0-py2.py3-none-any.whl", hash = "sha256:cf270de5a4c5874e84599fc5778303d496c10ae5e870bfa378818f35d21bda5c"},
{file = "requests_file-2.1.0.tar.gz", hash = "sha256:0f549a3f3b0699415ac04d167e9cb39bccfb730cb832b4d20be3d9867356e658"},
]
[[package]]
name = "resolvelib"
version = "1.1.0"
requires_python = ">=3.7"
summary = "Resolve abstract dependencies into concrete ones"
groups = ["default"]
files = [
{file = "resolvelib-1.1.0-py2.py3-none-any.whl", hash = "sha256:f80de38ae744bcf4e918e27a681a5c6cb63a08d9a926c0989c0730bcdd089049"},
{file = "resolvelib-1.1.0.tar.gz", hash = "sha256:b68591ef748f58c1e2a2ac28d0961b3586ae8b25f60b0ba9a5e4f3d87c1d6a79"},
]
[[package]]
name = "rich"
version = "13.9.4"
requires_python = ">=3.8.0"
summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
groups = ["default"]
dependencies = [
"markdown-it-py>=2.2.0",
"pygments<3.0.0,>=2.13.0",
"typing-extensions<5.0,>=4.0.0; python_version < \"3.11\"",
]
files = [
{file = "rich-13.9.4-py3-none-any.whl", hash = "sha256:6049d5e6ec054bf2779ab3358186963bac2ea89175919d699e378b99738c2a90"},
{file = "rich-13.9.4.tar.gz", hash = "sha256:439594978a49a09530cff7ebc4b5c7103ef57baf48d5ea3184f21d9a2befa098"},
]
[[package]]
name = "ruff"
version = "0.8.0"
requires_python = ">=3.7"
summary = "An extremely fast Python linter and code formatter, written in Rust."
groups = ["lint"]
files = [
{file = "ruff-0.8.0-py3-none-linux_armv6l.whl", hash = "sha256:fcb1bf2cc6706adae9d79c8d86478677e3bbd4ced796ccad106fd4776d395fea"},
{file = "ruff-0.8.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:295bb4c02d58ff2ef4378a1870c20af30723013f441c9d1637a008baaf928c8b"},
{file = "ruff-0.8.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:7b1f1c76b47c18fa92ee78b60d2d20d7e866c55ee603e7d19c1e991fad933a9a"},
{file = "ruff-0.8.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:eb0d4f250a7711b67ad513fde67e8870109e5ce590a801c3722580fe98c33a99"},
{file = "ruff-0.8.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:0e55cce9aa93c5d0d4e3937e47b169035c7e91c8655b0974e61bb79cf398d49c"},
{file = "ruff-0.8.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3f4cd64916d8e732ce6b87f3f5296a8942d285bbbc161acee7fe561134af64f9"},
{file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:c5c1466be2a2ebdf7c5450dd5d980cc87c8ba6976fb82582fea18823da6fa362"},
{file = "ruff-0.8.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2dabfd05b96b7b8f2da00d53c514eea842bff83e41e1cceb08ae1966254a51df"},
{file = "ruff-0.8.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:facebdfe5a5af6b1588a1d26d170635ead6892d0e314477e80256ef4a8470cf3"},
{file = "ruff-0.8.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:87a8e86bae0dbd749c815211ca11e3a7bd559b9710746c559ed63106d382bd9c"},
{file = "ruff-0.8.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:85e654f0ded7befe2d61eeaf3d3b1e4ef3894469cd664ffa85006c7720f1e4a2"},
{file = "ruff-0.8.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:83a55679c4cb449fa527b8497cadf54f076603cc36779b2170b24f704171ce70"},
{file = "ruff-0.8.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:812e2052121634cf13cd6fddf0c1871d0ead1aad40a1a258753c04c18bb71bbd"},
{file = "ruff-0.8.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:780d5d8523c04202184405e60c98d7595bdb498c3c6abba3b6d4cdf2ca2af426"},
{file = "ruff-0.8.0-py3-none-win32.whl", hash = "sha256:5fdb6efecc3eb60bba5819679466471fd7d13c53487df7248d6e27146e985468"},
{file = "ruff-0.8.0-py3-none-win_amd64.whl", hash = "sha256:582891c57b96228d146725975fbb942e1f30a0c4ba19722e692ca3eb25cc9b4f"},
{file = "ruff-0.8.0-py3-none-win_arm64.whl", hash = "sha256:ba93e6294e9a737cd726b74b09a6972e36bb511f9a102f1d9a7e1ce94dd206a6"},
{file = "ruff-0.8.0.tar.gz", hash = "sha256:a7ccfe6331bf8c8dad715753e157457faf7351c2b69f62f32c165c2dbcbacd44"},
]
[[package]]
name = "rules"
version = "3.5"
summary = "Awesome Django authorization, without the database"
groups = ["default"]
files = [
{file = "rules-3.5-py2.py3-none-any.whl", hash = "sha256:0f00fc9ee448b3f82e9aff9334ab0c56c76dce4dfa14f1598f57969f1022acc0"},
{file = "rules-3.5.tar.gz", hash = "sha256:f01336218f4561bab95f53672d22418b4168baea271423d50d9e8490d64cb27a"},
]
[[package]]
name = "s3transfer"
version = "0.10.4"
requires_python = ">=3.8"
summary = "An Amazon S3 Transfer Manager"
groups = ["default"]
dependencies = [
"botocore<2.0a.0,>=1.33.2",
]
files = [
{file = "s3transfer-0.10.4-py3-none-any.whl", hash = "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e"},
{file = "s3transfer-0.10.4.tar.gz", hash = "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7"},
]
[[package]]
name = "segno"
version = "1.6.1"
requires_python = ">=3.5"
summary = "QR Code and Micro QR Code generator for Python"
groups = ["default"]
dependencies = [
"importlib-metadata>=3.6.0; python_version < \"3.10\"",
]
files = [
{file = "segno-1.6.1-py3-none-any.whl", hash = "sha256:e90c6ff82c633f757a96d4b1fb06cc932589b5237f33be653f52252544ac64df"},
{file = "segno-1.6.1.tar.gz", hash = "sha256:f23da78b059251c36e210d0cf5bfb1a9ec1604ae6e9f3d42f9a7c16d306d847e"},
]
[[package]]
name = "sentry-sdk"
version = "2.19.0"
requires_python = ">=3.6"
summary = "Python client for Sentry (https://sentry.io)"
groups = ["default"]
dependencies = [
"certifi",
"urllib3>=1.26.11",
]
files = [
{file = "sentry_sdk-2.19.0-py2.py3-none-any.whl", hash = "sha256:7b0b3b709dee051337244a09a30dbf6e95afe0d34a1f8b430d45e0982a7c125b"},
{file = "sentry_sdk-2.19.0.tar.gz", hash = "sha256:ee4a4d2ae8bfe3cac012dcf3e4607975904c137e1738116549fc3dbbb6ff0e36"},
]
[[package]]
name = "shellingham"
version = "1.5.4"
requires_python = ">=3.7"
summary = "Tool to Detect Surrounding Shell"
groups = ["default"]
files = [
{file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"},
{file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"},
]
[[package]]
name = "six"
version = "1.16.0"
requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*"
summary = "Python 2 and 3 compatibility utilities"
groups = ["default", "lint", "local"]
files = [
{file = "six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254"},
{file = "six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926"},
]
[[package]]
name = "sniffio"
version = "1.3.1"
requires_python = ">=3.7"
summary = "Sniff out which async library your code is running under"
groups = ["default", "watchfiles"]
files = [
{file = "sniffio-1.3.1-py3-none-any.whl", hash = "sha256:2f6da418d1f1e0fddd844478f41680e794e6051915791a034ff65e5f100525a2"},
{file = "sniffio-1.3.1.tar.gz", hash = "sha256:f4324edc670a0f49750a81b895f35c3adb843cca46f0530f79fc1babb23789dc"},
]
[[package]]
name = "socksio"
version = "1.0.0"
requires_python = ">=3.6"
summary = "Sans-I/O implementation of SOCKS4, SOCKS4A, and SOCKS5."
groups = ["default"]
files = [
{file = "socksio-1.0.0-py3-none-any.whl", hash = "sha256:95dc1f15f9b34e8d7b16f06d74b8ccf48f609af32ab33c608d08761c5dcbb1f3"},
{file = "socksio-1.0.0.tar.gz", hash = "sha256:f88beb3da5b5c38b9890469de67d0cb0f9d494b78b106ca1845f96c10b91c4ac"},
]
[[package]]
name = "soupsieve"
version = "2.6"
requires_python = ">=3.8"
summary = "A modern CSS selector implementation for Beautiful Soup."
groups = ["default"]
files = [
{file = "soupsieve-2.6-py3-none-any.whl", hash = "sha256:e72c4ff06e4fb6e4b5a9f0f55fe6e81514581fca1515028625d0f299c602ccc9"},
{file = "soupsieve-2.6.tar.gz", hash = "sha256:e2e68417777af359ec65daac1057404a3c8a5455bb8abc36f1a9866ab1a51abb"},
]
[[package]]
name = "sqlparse"
version = "0.5.2"
requires_python = ">=3.8"
summary = "A non-validating SQL parser."
groups = ["default", "typing", "watchfiles"]
files = [
{file = "sqlparse-0.5.2-py3-none-any.whl", hash = "sha256:e99bc85c78160918c3e1d9230834ab8d80fc06c59d03f8db2618f65f65dda55e"},
{file = "sqlparse-0.5.2.tar.gz", hash = "sha256:9e37b35e16d1cc652a2545f0997c1deb23ea28fa1f3eefe609eee3063c3b105f"},
]
[[package]]
name = "tomlkit"
version = "0.13.2"
requires_python = ">=3.8"
summary = "Style preserving TOML library"
groups = ["default", "static-analysis"]
files = [
{file = "tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde"},
{file = "tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79"},
]
[[package]]
name = "tox"
version = "4.23.2"
requires_python = ">=3.8"
summary = "tox is a generic virtualenv management and test command line tool"
groups = ["dev"]
dependencies = [
"cachetools>=5.5",
"chardet>=5.2",
"colorama>=0.4.6",
"filelock>=3.16.1",
"packaging>=24.1",
"platformdirs>=4.3.6",
"pluggy>=1.5",
"pyproject-api>=1.8",
"tomli>=2.0.1; python_version < \"3.11\"",
"typing-extensions>=4.12.2; python_version < \"3.11\"",
"virtualenv>=20.26.6",
]
files = [
{file = "tox-4.23.2-py3-none-any.whl", hash = "sha256:452bc32bb031f2282881a2118923176445bac783ab97c874b8770ab4c3b76c38"},
{file = "tox-4.23.2.tar.gz", hash = "sha256:86075e00e555df6e82e74cfc333917f91ecb47ffbc868dcafbd2672e332f4a2c"},
]
[[package]]
name = "tox-pdm"
version = "0.7.2"
requires_python = ">=3.7"
summary = "A plugin for tox that utilizes PDM as the package manager and installer"
groups = ["dev"]
dependencies = [
"tomli; python_version < \"3.11\"",
"tox>=4.0",
]
files = [
{file = "tox_pdm-0.7.2-py3-none-any.whl", hash = "sha256:12f6215416b7acd00a80a9e7128f3dc3e3c89308d60707f5d0a24abdf83ac104"},
{file = "tox_pdm-0.7.2.tar.gz", hash = "sha256:a841a7e1e942a71805624703b9a6d286663bd6af79bba6130ba756975c315308"},
]
[[package]]
name = "tqdm"
version = "4.67.1"
requires_python = ">=3.7"
summary = "Fast, Extensible Progress Meter"
groups = ["lint"]
dependencies = [
"colorama; platform_system == \"Windows\"",
]
files = [
{file = "tqdm-4.67.1-py3-none-any.whl", hash = "sha256:26445eca388f82e72884e0d580d5464cd801a3ea01e63e5601bdff9ba6a48de2"},
{file = "tqdm-4.67.1.tar.gz", hash = "sha256:f8aef9c52c08c13a65f30ea34f4e5aac3fd1a34959879d7e59e63027286627f2"},
]
[[package]]
name = "truststore"
version = "0.10.0"
requires_python = ">=3.10"
summary = "Verify certificates using native system trust stores"
groups = ["default"]
marker = "python_version >= \"3.10\""
files = [
{file = "truststore-0.10.0-py3-none-any.whl", hash = "sha256:b3798548e421ffe2ca2a6217cca49e7a17baf40b72d86a5505dc7d701e77d15b"},
{file = "truststore-0.10.0.tar.gz", hash = "sha256:5da347c665714fdfbd46f738c823fe9f0d8775e41ac5fb94f325749091187896"},
]
[[package]]
name = "types-pyyaml"
version = "6.0.12.20240917"
requires_python = ">=3.8"
summary = "Typing stubs for PyYAML"
groups = ["typing"]
files = [
{file = "types-PyYAML-6.0.12.20240917.tar.gz", hash = "sha256:d1405a86f9576682234ef83bcb4e6fff7c9305c8b1fbad5e0bcd4f7dbdc9c587"},
{file = "types_PyYAML-6.0.12.20240917-py3-none-any.whl", hash = "sha256:392b267f1c0fe6022952462bf5d6523f31e37f6cea49b14cee7ad634b6301570"},
]
[[package]]
name = "typing-extensions"
version = "4.12.2"
requires_python = ">=3.8"
summary = "Backported and Experimental Type Hints for Python 3.8+"
groups = ["default", "typing"]
files = [
{file = "typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d"},
{file = "typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8"},
]
[[package]]
name = "tzdata"
version = "2024.2"
requires_python = ">=2"
summary = "Provider of IANA time zone data"
groups = ["default", "typing", "watchfiles"]
files = [
{file = "tzdata-2024.2-py2.py3-none-any.whl", hash = "sha256:a48093786cdcde33cad18c2555e8532f34422074448fbc874186f0abd79565cd"},
{file = "tzdata-2024.2.tar.gz", hash = "sha256:7d85cc416e9382e69095b7bdf4afd9e3880418a2413feec7069d533d6b4e31cc"},
]
[[package]]
name = "unearth"
version = "0.17.2"
requires_python = ">=3.8"
summary = "A utility to fetch and download python packages"
groups = ["default"]
dependencies = [
"httpx<1,>=0.27.0",
"packaging>=20",
]
files = [
{file = "unearth-0.17.2-py3-none-any.whl", hash = "sha256:4d21af1238a583835fca156322f7225382e718cdcc42d6278050a88e605c4ad5"},
{file = "unearth-0.17.2.tar.gz", hash = "sha256:0b8a2afd3476f1ab6155fc579501ac47fffe43547d88a70e5a5b76a7fe6caa2c"},
]
[[package]]
name = "urllib3"
version = "2.2.3"
requires_python = ">=3.8"
summary = "HTTP library with thread-safe connection pooling, file post, and more."
groups = ["default"]
files = [
{file = "urllib3-2.2.3-py3-none-any.whl", hash = "sha256:ca899ca043dcb1bafa3e262d73aa25c465bfb49e0bd9dd5d59f1d0acba2f8fac"},
{file = "urllib3-2.2.3.tar.gz", hash = "sha256:e7d814a81dad81e6caf2ec9fdedb284ecc9c73076b62654547cc64ccdcae26e9"},
]
[[package]]
name = "virtualenv"
version = "20.27.1"
requires_python = ">=3.8"
summary = "Virtual Python Environment builder"
groups = ["default", "dev"]
dependencies = [
"distlib<1,>=0.3.7",
"filelock<4,>=3.12.2",
"importlib-metadata>=6.6; python_version < \"3.8\"",
"platformdirs<5,>=3.9.1",
]
files = [
{file = "virtualenv-20.27.1-py3-none-any.whl", hash = "sha256:f11f1b8a29525562925f745563bfd48b189450f61fb34c4f9cc79dd5aa32a1f4"},
{file = "virtualenv-20.27.1.tar.gz", hash = "sha256:142c6be10212543b32c6c45d3d3893dff89112cc588b7d0879ae5a1ec03a47ba"},
]
[[package]]
name = "watchfiles"
version = "1.0.0"
requires_python = ">=3.9"
summary = "Simple, modern and high performance file watching and code reload in python."
groups = ["watchfiles"]
dependencies = [
"anyio>=3.0.0",
]
files = [
{file = "watchfiles-1.0.0-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:95de85c254f7fe8cbdf104731f7f87f7f73ae229493bebca3722583160e6b152"},
{file = "watchfiles-1.0.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:533a7cbfe700e09780bb31c06189e39c65f06c7f447326fee707fd02f9a6e945"},
{file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2218e78e2c6c07b1634a550095ac2a429026b2d5cbcd49a594f893f2bb8c936"},
{file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9122b8fdadc5b341315d255ab51d04893f417df4e6c1743b0aac8bf34e96e025"},
{file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9272fdbc0e9870dac3b505bce1466d386b4d8d6d2bacf405e603108d50446940"},
{file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a3b33c3aefe9067ebd87846806cd5fc0b017ab70d628aaff077ab9abf4d06b3"},
{file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bc338ce9f8846543d428260fa0f9a716626963148edc937d71055d01d81e1525"},
{file = "watchfiles-1.0.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ac778a460ea22d63c7e6fb0bc0f5b16780ff0b128f7f06e57aaec63bd339285"},
{file = "watchfiles-1.0.0-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:53ae447f06f8f29f5ab40140f19abdab822387a7c426a369eb42184b021e97eb"},
{file = "watchfiles-1.0.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1f73c2147a453315d672c1ad907abe6d40324e34a185b51e15624bc793f93cc6"},
{file = "watchfiles-1.0.0-cp313-none-win32.whl", hash = "sha256:eba98901a2eab909dbd79681190b9049acc650f6111fde1845484a4450761e98"},
{file = "watchfiles-1.0.0-cp313-none-win_amd64.whl", hash = "sha256:d562a6114ddafb09c33246c6ace7effa71ca4b6a2324a47f4b09b6445ea78941"},
{file = "watchfiles-1.0.0.tar.gz", hash = "sha256:37566c844c9ce3b5deb964fe1a23378e575e74b114618d211fbda8f59d7b5dab"},
]
[[package]]
name = "webencodings"
version = "0.5.1"
summary = "Character encoding aliases for legacy web content"
groups = ["default"]
files = [
{file = "webencodings-0.5.1-py2.py3-none-any.whl", hash = "sha256:a0af1213f3c2226497a97e2b3aa01a7e4bee4f403f95be16fc9acd2947514a78"},
{file = "webencodings-0.5.1.tar.gz", hash = "sha256:b36a1c245f2d304965eb4e0a82848379241dc04b865afcc4aab16748587e1923"},
]
......@@ -2,9 +2,7 @@
name = "hub"
dynamic = ["version"]
description = "Management tool for chaos events."
authors = [
{name = "Roang", email = "lucas@brandstaetter.tech"},
]
authors = [{ name = "Hub Team", email = "hub@cccv.de" }]
dependencies = [
"babel~=2.16",
"bleach~=6.1",
......@@ -39,69 +37,58 @@ dependencies = [
"segno~=1.6.1",
"sentry-sdk>=2.17.0,<3",
"tzdata~=2024.2",
"pdm>=2.11.2",
"psycopg[binary,pool]>=3.2.3",
"gunicorn>=23.0.0",
"pydantic>=2.9.2",
"django-rich>=1.13.0",
"django-csp>=3.8",
"rules>=3.5",
"django-ical>=1.9.2",
"django-stubs-ext>=5.1.2",
"ipython>=8.31.0",
"django-extensions>=3.2.3",
]
requires-python = "==3.13.*"
readme = "README.md"
license = { text = "MIT" }
[project.optional-dependencies]
watchfiles = [
"django-watchfiles>=1.0.0",
]
[tool.pdm]
distribution = false
[tool.pdm.version]
source = "scm"
write_to = "version.txt"
[tool.pdm.dev-dependencies]
lint = [
"ruff>=0.1.11",
"djlint>=1.35.4",
]
local = [
"debugpy>=1.8.0",
"icecream>=2.1.3",
]
[dependency-groups]
dev = [
"tox>=4.11.4",
"coverage>=7.4.0",
"tox-pdm>=0.7.2",
"pre-commit>=3.6.0",
"docutils>=0.21.2",
"pre-commit>=3.6.0",
"tblib>=3.0.0",
"tox-uv>=1.19.0",
"tox>=4.11.4",
"taskipy>=1.14.1",
]
lint = ["ruff>=0.1.11", "djlint>=1.35.4"]
local = ["debugpy>=1.8.0", "icecream>=2.1.3"]
typing = [
"django-stubs[mypy-compatible]>=5.1.1",
]
static-analysis = [
"pylint>=3.3.1",
"pylint-django>=2.6.1",
"pyright>=1.1.392.post0",
"djangorestframework-stubs[compatible-mypy]>=1.4.0",
"django-stubs>=5.1.2",
]
static-analysis = ["pylint>=3.3.1", "pylint-django>=2.6.1"]
watchfiles = ["django-watchfiles>=1.0.0"]
[tool.pdm.scripts]
# Generic scripts
whoami = { shell = "echo `{pdm} -V` was called as '{pdm} -V'" }
# uv currently has no task runner, use taskipy instead.
# Ref: https://github.com/astral-sh/uv/issues/5903
[tool.taskipy.tasks]
# Application version
app_version = "./src/manage.py appversion"
# Django scripts
start = "./src/manage.py runserver"
shell = "./src/manage.py shell"
manage = "./src/manage.py"
start = { cmd = "./src/manage.py runserver", cwd = "." }
shell = { cmd = "./src/manage.py shell_plus", cwd = "." }
manage = { cmd = "./src/manage.py", cwd = "." }
compilemessages = { cmd = "./manage.py compilemessages", cwd = "./src" }
# TOX scripts
all = "tox"
check-migrations = "tox -e migrations"
coverage-report = "tox -e coverage-report"
style-check = {composite = ["format", "lint"]}
format = {composite = ["py-format", "html-format"]}
lint = {composite = ["py-lint", "html-lint"]}
style-check = "task format && task lint"
format = "tox -e py-format,html-format"
lint = "tox -e py-lint,html-lint"
py-format = "tox -e py-format"
py-lint = "tox -e py-lint"
html-format = "tox -e html-format"
......@@ -112,15 +99,20 @@ live-test = "tox -e live-test"
[tool.coverage.run]
data_file = ".tools/coverage/coverage"
dynamic_context = "test_function"
omit =[
"*/migrations/*"]
omit = ["*/migrations/*"]
branch = true
[tool.coverage.report]
show_missing = true
exclude_also = [
"def __repr__",
"if settings.DEBUG",
"if TYPE_CHECKING:",
"raise NotImplementedError",
]
[tool.coverage.xml]
output = ".tools/coverage/coverage.xml"
output = ".tools/coverage/report.xml"
[tool.coverage.html]
directory = ".tools/coverage/html_report"
......@@ -130,10 +122,187 @@ indent = 2
ignore = "H006,H013,H021,H022,H030,H031"
linter_output_format = "{filename}:{line}: {code} {message} {match}"
preserve_blank_lines = true
extend_exclude=".tools"
# We neeed to override the default settings for the GitLab CI
# Ref: https://github.com/djlint/djLint/issues/1028
exclude = ".venv"
extend_exclude = "__pypackages__,_build,.bzr,.direnv,.eggs,.git,.git-rewrite,.hg,.ipynb_checkpoints,.mypy_cache,.nox,.pants.d,.pytest_cache,.pytype,.ruff_cache,.svn,.tox,.venv,.vscode,buck-out,dist,node_modules,venv,.tools"
[tool.mypy]
plugins = ["mypy_django_plugin.main"]
[tool.django-stubs]
django_settings_module = "hub.settings.base"
[tool.tox]
requires = ["tox>=4"]
env_list = [
"py-lint",
"py-format",
"html-lint",
"html-format",
"django-test",
"coverage-repor",
]
work_dir = ".tools/tox"
[tool.tox.env_run_base]
runner = "uv-venv-lock-runner"
skip_install = true
[tool.tox.env.hub.set_env]
ALLOWED_HOSTS = { replace = "env", name = "ALLOWED_HOSTS" }
DATABASE_URL = { replace = "env", name = "DATABASE_URL" }
DJANGO_DEBUG = "I_KNOW_WHAT_I_AM_DOING"
DJANGO_SETTINGS_MODULE = "hub.settings.test"
DISABLE_REQUEST_LOGGING = "True"
SERVE_API = "True"
SERVE_BACKOFFICE = "True"
SERVE_FRONTEND = "True"
SSO_SECRET_GENERATE = "True"
STORAGE_TYPE = "local"
USE_PLAIN_STATICFILES = "True"
METRICS_SERVER_IPS = "127.0.0.1,localhost"
[tool.tox.env.py-lint]
uv_sync_flags = ["--only-group=lint"]
commands = [["ruff", "check", "."]]
[tool.tox.env.py-format]
uv_sync_flags = ["--only-group=lint"]
commands = [["ruff", "format", ".", "--diff"]]
[tool.tox.env.html-lint]
uv_sync_flags = ["--only-group=lint"]
commands = [
[
"djlint",
"--profile",
"jinja",
"-e",
"j2",
"--lint",
".",
],
[
"djlint",
"--profile",
"django",
"-e",
"html",
"--lint",
".",
],
]
[tool.tox.env.html-format]
uv_sync_flags = ["--only-group=lint"]
commands = [
[
"djlint",
"--profile",
"jinja",
"-e",
"j2",
"--reformat",
".",
],
[
"djlint",
"--profile",
"django",
"-e",
"html",
"--reformat",
".",
],
]
[tool.tox.env.django-test]
set_env = [
{ replace = "ref", of = [
"tool",
"tox",
"env",
"hub",
"set_env",
] },
{ PYTHONWARNINGS = "always" },
]
allowlist_externals = ["coverage"]
extras = ["dev"]
commands = [
[
"coverage",
"run",
"--concurrency=multiprocessing",
"{toxinidir}/src/manage.py",
"test",
"-v",
"2",
"--parallel=8",
'src',
{ replace = "posargs", extend = true },
],
[
"coverage",
"combine",
],
]
[tool.tox.env.django-test-single]
set_env = [
{ replace = "ref", of = [
"tool",
"tox",
"env",
"hub",
"set_env",
] },
{ PYTHONWARNINGS = "always" },
]
extras = ["dev"]
change_dir = "{toxinidir}/src"
allowlist_externals = ["coverage"]
commands = [
[
"coverage",
"run",
"./manage.py",
"test",
"-v",
"2",
{ replace = "posargs", extend = true },
],
]
[tool.tox.env.live-test]
groups = "dev"
change_dir = "{toxinidir}"
commands = [["python", "-m", "unittest", "{posargs}"]]
[tool.tox.env.live-test.set_env]
PYTHONWARNINGS = "always"
SERVE_API = "yes"
[tool.tox.env.coverage-report]
deps = ["coverage"]
commands = [["coverage", "report"], ["coverage", "xml"], ["coverage", "html"]]
[tool.pyright]
include = ["src"]
exclude = [
"**/node_modules",
"**/dist",
"**/build",
"**/.venv",
"**/.vscode",
"**/.tools",
]
venvPath = "."
venv = ".venv"
verboseOutput = true
reportMissingTypeArgument = "information"
reportPrivateUsage = "information"
typeCheckingMode = "standard" # "off", "basic", "standard", "strict"
# This file is @generated by PDM.
# Please do not edit it manually.
# This file was autogenerated by uv via the following command:
# uv export --frozen -o=requirements.dev.txt --no-hashes --all-groups
annotated-types==0.7.0
anyio==4.6.2.post1
anyio==4.8.0
asgiref==3.8.1
astroid==3.3.5
asttokens==2.4.1
babel==2.16.0
beautifulsoup4==4.12.3
astroid==3.3.8
asttokens==3.0.0
babel==2.17.0
beautifulsoup4==4.13.3
bleach==6.2.0
blinker==1.9.0
boto3==1.35.71
botocore==1.35.71
cachetools==5.5.0
certifi==2024.8.30
cffi==1.17.1; platform_python_implementation != "PyPy"
boto3==1.36.26
botocore==1.36.26
cachetools==5.5.2
certifi==2025.1.31
cffi==1.17.1 ; platform_python_implementation != 'PyPy'
cfgv==3.4.0
chardet==5.2.0
charset-normalizer==3.4.0
click==8.1.7
charset-normalizer==3.4.1
click==8.1.8
colorama==0.4.6
coverage==7.6.8
cryptography==43.0.3
cssbeautifier==1.15.1
debugpy==1.8.9
coverage==7.6.12
cryptography==44.0.1
cssbeautifier==1.15.3
debugpy==1.8.12
decorator==5.2.0
defusedxml==0.7.1
dep-logic==0.4.9
dill==0.3.9; python_version >= "3.11"
dill==0.3.9
distlib==0.3.9
django==5.1.3
django==5.1.6
django-bootstrap5==24.3
django-cors-headers==4.6.0
django-cors-headers==4.7.0
django-csp==3.8
django-debug-toolbar==4.4.6
django-environ==0.11.2
django-modeltranslation==0.19.11
django-extensions==3.2.3
django-ical==1.9.2
django-modeltranslation==0.19.12
django-oauth-toolkit==3.0.1
django-ratelimit==4.1.0
django-recurrence==1.11.1
django-redis==5.4.0
django-rich==1.13.0
django-storages==1.14.4
django-stubs-ext==5.1.1
django-stubs[mypy-compatible]==5.1.1
django-rich==1.14.0
django-storages==1.14.5
django-stubs==5.1.3
django-stubs-ext==5.1.3
django-timezone-field==7.0
django-watchfiles==1.1.0
django-widget-tweaks==1.5.0
djangorestframework==3.15.2
djlint==1.36.2
djangorestframework-stubs==3.15.3
djlint==1.36.4
docutils==0.21.2
editorconfig==0.12.4
editorconfig==0.17.0
et-xmlfile==2.0.0
executing==2.1.0
filelock==3.16.1
findpython==0.6.2
executing==2.2.0
filelock==3.17.0
freezegun==1.5.1
gunicorn==23.0.0
h11==0.14.0
hishel==0.0.33
httpcore==1.0.7
httpx[socks]==0.27.2
icecream==2.1.3
identify==2.6.2
icalendar==6.1.1
icecream==2.1.4
identify==2.6.7
idna==3.10
installer==0.7.0
isort==5.13.2
jinja2==3.1.4
ipython==8.32.0
isort==6.0.0
jedi==0.19.2
jinja2==3.1.5
jmespath==1.0.1
jsbeautifier==1.15.1
json5==0.9.28
jsbeautifier==1.15.3
json5==0.10.0
jwcrypto==1.5.6
lxml==5.3.0
lxml==5.3.1
markdown-it-py==3.0.0
markdownify==0.13.1
markupsafe==3.0.2
matplotlib-inline==0.1.7
mccabe==0.7.0
mdurl==0.1.2
mistletoe==1.4.0
msgpack==1.1.0
mslex==1.3.0 ; sys_platform == 'win32'
mypy==1.15.0
mypy-extensions==1.0.0
nodeenv==1.9.1
numpy==2.1.3; python_version >= "3.12"
numpy==2.2.3
oauthlib==3.2.2
odfpy==1.4.1
openpyxl==3.1.5
ordered-set==4.1.0
packaging==24.2
pandas==2.2.3
parso==0.8.4
pathspec==0.12.1
pbs-installer==2024.10.16
pdm==2.21.0
pexpect==4.9.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pillow==10.4.0
platformdirs==4.3.6
pluggy==1.5.0
pre-commit==4.0.1
psycopg-binary==3.2.3; implementation_name != "pypy"
psycopg-pool==3.2.4
psycopg[binary,pool]==3.2.3
pycparser==2.22; platform_python_implementation != "PyPy"
pydantic==2.10.2
pydantic-core==2.27.1
pygments==2.18.0
pre-commit==4.1.0
prompt-toolkit==3.0.50
psutil==6.1.1
psycopg==3.2.4
psycopg-binary==3.2.4 ; implementation_name != 'pypy'
psycopg-pool==3.2.5
ptyprocess==0.7.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pure-eval==0.2.3
pycparser==2.22 ; platform_python_implementation != 'PyPy'
pydantic==2.10.6
pydantic-core==2.27.2
pygments==2.19.1
pyjwt==2.9.0
pylint==3.3.1
pylint==3.3.4
pylint-django==2.6.1
pylint-plugin-utils==0.8.2
pyproject-api==1.8.0
pyproject-hooks==1.2.0
pyproject-api==1.9.0
pyright==1.1.394
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
pytz==2024.2
pytz==2025.1
pyyaml==6.0.2
redis==5.2.0
redis==5.2.1
regex==2024.11.6
requests==2.32.3
requests-file==2.1.0
resolvelib==1.1.0
rich==13.9.4
ruff==0.8.0
ruff==0.9.7
rules==3.5
s3transfer==0.10.4
s3transfer==0.11.2
segno==1.6.1
sentry-sdk==2.19.0
shellingham==1.5.4
six==1.16.0
sentry-sdk==2.22.0
six==1.17.0
sniffio==1.3.1
socksio==1.0.0
soupsieve==2.6
sqlparse==0.5.2
sqlparse==0.5.3
stack-data==0.6.3
taskipy==1.14.1
tblib==3.0.0
tomli==2.2.1
tomlkit==0.13.2
tox==4.23.2
tox-pdm==0.7.2
tox==4.24.1
tox-uv==1.25.0
tqdm==4.67.1
truststore==0.10.0; python_version >= "3.10"
types-pyyaml==6.0.12.20240917
traitlets==5.14.3
types-pyyaml==6.0.12.20241230
types-requests==2.32.0.20241016
typing-extensions==4.12.2
tzdata==2024.2
unearth==0.17.2
urllib3==2.2.3
virtualenv==20.27.1
urllib3==2.3.0
uv==0.6.2
virtualenv==20.29.2
watchfiles==1.0.4
wcwidth==0.2.13
webencodings==0.5.1
# This file is @generated by PDM.
# Please do not edit it manually.
# This file was autogenerated by uv via the following command:
# uv export --frozen -o=requirements.txt --no-hashes --no-dev
annotated-types==0.7.0
anyio==4.6.2.post1
asgiref==3.8.1
babel==2.16.0
beautifulsoup4==4.12.3
asttokens==3.0.0
babel==2.17.0
beautifulsoup4==4.13.3
bleach==6.2.0
blinker==1.9.0
boto3==1.35.71
botocore==1.35.71
certifi==2024.8.30
cffi==1.17.1; platform_python_implementation != "PyPy"
charset-normalizer==3.4.0
cryptography==43.0.3
boto3==1.36.26
botocore==1.36.26
certifi==2025.1.31
cffi==1.17.1 ; platform_python_implementation != 'PyPy'
charset-normalizer==3.4.1
colorama==0.4.6 ; sys_platform == 'win32'
cryptography==44.0.1
decorator==5.2.0
defusedxml==0.7.1
dep-logic==0.4.9
distlib==0.3.9
django==5.1.3
django==5.1.6
django-bootstrap5==24.3
django-cors-headers==4.6.0
django-cors-headers==4.7.0
django-csp==3.8
django-debug-toolbar==4.4.6
django-environ==0.11.2
django-modeltranslation==0.19.11
django-extensions==3.2.3
django-ical==1.9.2
django-modeltranslation==0.19.12
django-oauth-toolkit==3.0.1
django-ratelimit==4.1.0
django-recurrence==1.11.1
django-redis==5.4.0
django-rich==1.13.0
django-storages==1.14.4
django-rich==1.14.0
django-storages==1.14.5
django-stubs-ext==5.1.3
django-timezone-field==7.0
django-widget-tweaks==1.5.0
djangorestframework==3.15.2
et-xmlfile==2.0.0
filelock==3.16.1
findpython==0.6.2
executing==2.2.0
freezegun==1.5.1
gunicorn==23.0.0
h11==0.14.0
hishel==0.0.33
httpcore==1.0.7
httpx[socks]==0.27.2
icalendar==6.1.1
idna==3.10
installer==0.7.0
jinja2==3.1.4
ipython==8.32.0
jedi==0.19.2
jinja2==3.1.5
jmespath==1.0.1
jwcrypto==1.5.6
lxml==5.3.0
lxml==5.3.1
markdown-it-py==3.0.0
markdownify==0.13.1
markupsafe==3.0.2
matplotlib-inline==0.1.7
mdurl==0.1.2
mistletoe==1.4.0
msgpack==1.1.0
numpy==2.1.3; python_version >= "3.12"
numpy==2.2.3
oauthlib==3.2.2
odfpy==1.4.1
openpyxl==3.1.5
ordered-set==4.1.0
packaging==24.2
pandas==2.2.3
pbs-installer==2024.10.16
pdm==2.21.0
parso==0.8.4
pexpect==4.9.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pillow==10.4.0
platformdirs==4.3.6
psycopg-binary==3.2.3; implementation_name != "pypy"
psycopg-pool==3.2.4
psycopg[binary,pool]==3.2.3
pycparser==2.22; platform_python_implementation != "PyPy"
pydantic==2.10.2
pydantic-core==2.27.1
pygments==2.18.0
prompt-toolkit==3.0.50
psycopg==3.2.4
psycopg-binary==3.2.4 ; implementation_name != 'pypy'
psycopg-pool==3.2.5
ptyprocess==0.7.0 ; sys_platform != 'emscripten' and sys_platform != 'win32'
pure-eval==0.2.3
pycparser==2.22 ; platform_python_implementation != 'PyPy'
pydantic==2.10.6
pydantic-core==2.27.2
pygments==2.19.1
pyjwt==2.9.0
pyproject-hooks==1.2.0
python-dateutil==2.9.0.post0
python-dotenv==1.0.1
pytz==2024.2
redis==5.2.0
pytz==2025.1
redis==5.2.1
requests==2.32.3
requests-file==2.1.0
resolvelib==1.1.0
rich==13.9.4
rules==3.5
s3transfer==0.10.4
s3transfer==0.11.2
segno==1.6.1
sentry-sdk==2.19.0
shellingham==1.5.4
six==1.16.0
sniffio==1.3.1
socksio==1.0.0
sentry-sdk==2.22.0
six==1.17.0
soupsieve==2.6
sqlparse==0.5.2
tomlkit==0.13.2
truststore==0.10.0; python_version >= "3.10"
sqlparse==0.5.3
stack-data==0.6.3
traitlets==5.14.3
typing-extensions==4.12.2
tzdata==2024.2
unearth==0.17.2
urllib3==2.2.3
virtualenv==20.27.1
urllib3==2.3.0
wcwidth==0.2.13
webencodings==0.5.1
from typing import Optional
from django_ical.views import ICalFeed
from django.utils.text import slugify
from core.models import (
Conference,
Event,
)
class EventICalFeed(ICalFeed):
"""
EventICalFeed serializes Events to an iCal response.
"""
def __init__(self, events: list[Event], name: Optional[str] = None, conference: Optional[Conference] = None):
super().__init__()
self.name = name
self.conference = conference
self.events = events
def product_id(self) -> str:
issuer = self.conference.name if self.conference else 'Hub'
product = self.name if self.name else 'iCal export'
return f'-//{issuer}//{product}'
def title(self) -> str:
if self.name:
return self.name
return 'Hub iCal export'
def items(self) -> list[Event]:
return self.events
def item_title(self, item) -> str:
return item.name
def item_description(self, item) -> str:
return item.description
def item_start_datetime(self, item):
return item.schedule_start
def item_end_datetime(self, item):
return item.schedule_end
def item_location(self, item) -> str:
if item.room:
return item.room.name
if item.location:
return item.location
return ''
def item_guid(self, item) -> str:
return item.pk
def item_categories(self, item) -> list[str]:
categories = []
if item.recording == Event.Recording.YES:
categories.append('recorded')
elif item.recording == Event.Recording.NO:
categories.append('not recorded')
if item.kind == Event.Kind.OFFICIAL or item.assembly.is_official:
categories.append('official')
if item.track:
categories.append(item.track.name)
return categories
def file_name(self) -> str:
return slugify(self.title()) + '.ics'