Ver Fonte

update build and release scripts to use uv

Nick Sweeting há 1 ano atrás
pai
commit
e29aff12bf
10 ficheiros alterados com 1237 adições e 2096 exclusões
  1. 31 29
      bin/build_docker.sh
  2. 1 1
      bin/build_docs.sh
  3. 2 8
      bin/build_pip.sh
  4. 16 30
      bin/lock_pkgs.sh
  5. 32 28
      bin/release_docker.sh
  6. 1 4
      bin/release_pip.sh
  7. 0 1855
      pdm.lock
  8. 7 13
      pyproject.toml
  9. 336 127
      requirements.txt
  10. 811 1
      uv.lock

+ 31 - 29
bin/build_docker.sh

@@ -9,7 +9,7 @@ set -o errexit
 set -o errtrace
 set -o nounset
 set -o pipefail
-IFS=$'\n'
+IFS=$' '
 
 REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && pwd )"
 cd "$REPO_DIR"
@@ -18,15 +18,34 @@ which docker > /dev/null || exit 1
 which jq > /dev/null || exit 1
 # which pdm > /dev/null || exit 1
 
-SUPPORTED_PLATFORMS="linux/amd64,linux/arm64"
-
-TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
+declare -a TAG_NAMES="$*"
+BRANCH_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
 VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
-SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
 GIT_SHA=sha-"$(git rev-parse --short HEAD)"
-SELECTED_PLATFORMS="${2:-$SUPPORTED_PLATFORMS}"
-
-echo "[+] Building Docker image: tag=$TAG_NAME version=$SHORT_VERSION arch=$SELECTED_PLATFORMS"
+SELECTED_PLATFORMS="linux/amd64,linux/arm64"
+
+# if not already in TAG_NAMES, add GIT_SHA and BRANCH_NAME  
+if ! echo "${TAG_NAMES[@]}" | grep -q "$GIT_SHA"; then
+    TAG_NAMES+=("$GIT_SHA")
+fi
+if ! echo "${TAG_NAMES[@]}" | grep -q "$BRANCH_NAME"; then
+    TAG_NAMES+=("$BRANCH_NAME")
+fi
+if ! echo "${TAG_NAMES[@]}" | grep -q "$VERSION"; then
+    TAG_NAMES+=("$VERSION")
+fi
+
+echo "[+] Building Docker image for $SELECTED_PLATFORMS: branch=$BRANCH_NAME version=$VERSION tags=${TAG_NAMES[*]}"
+
+declare -a FULL_TAG_NAMES
+# for each tag in TAG_NAMES, add archivebox/archivebox:tag and nikisweeting/archivebox:tag to FULL_TAG_NAMES
+for TAG_NAME in "${TAG_NAMES[@]}"; do
+    [[ "$TAG_NAME" == "" ]] && continue
+    FULL_TAG_NAMES+=("-t archivebox/archivebox:$TAG_NAME")
+    FULL_TAG_NAMES+=("-t nikisweeting/archivebox:$TAG_NAME")
+    FULL_TAG_NAMES+=("-t ghcr.io/archivebox/archivebox:$TAG_NAME")
+done
+echo "${FULL_TAG_NAMES[@]}"
 
 function check_platforms() {
     INSTALLED_PLATFORMS="$(docker buildx inspect | grep 'Platforms:' )"
@@ -72,30 +91,13 @@ check_platforms || (recreate_builder && check_platforms) || exit 1
 
 
 # Make sure pyproject.toml, pdm{.dev}.lock, requirements{-dev}.txt, package{-lock}.json are all up-to-date
-echo "[!] Make sure you've run ./bin/lock_pkgs.sh recently!"
-sleep 1
-# bash ./bin/lock_pkgs.sh
+# echo "[!] Make sure you've run ./bin/lock_pkgs.sh recently!"
+bash ./bin/lock_pkgs.sh
 
 
 echo "[+] Building archivebox:$VERSION docker image..."
 # docker builder prune
 # docker build . --no-cache -t archivebox-dev \
 # replace --load with --push to deploy
-docker buildx build --platform "$SELECTED_PLATFORMS" --load . \
-               -t archivebox/archivebox:$TAG_NAME \
-               -t archivebox/archivebox:$GIT_SHA \
-               -t nikisweeting/archivebox:$TAG_NAME \
-               -t nikisweeting/archivebox:$GIT_SHA \
-               -t ghcr.io/archivebox/archivebox:$TAG_NAME \
-               -t ghcr.io/archivebox/archivebox:$GIT_SHA
-               # -t archivebox/archivebox \
-               # -t archivebox/archivebox:$VERSION \
-               # -t archivebox/archivebox:$SHORT_VERSION \
-               # -t archivebox/archivebox:latest \
-               # -t nikisweeting/archivebox \
-               # -t nikisweeting/archivebox:$VERSION \
-               # -t nikisweeting/archivebox:$SHORT_VERSION \
-               # -t nikisweeting/archivebox:latest \
-               # -t ghcr.io/archivebox/archivebox:$VERSION \
-               # -t ghcr.io/archivebox/archivebox:$SHORT_VERSION \
-               # -t ghcr.io/archivebox/archivebox:latest
+# shellcheck disable=SC2068
+docker buildx build --platform "$SELECTED_PLATFORMS" --load . ${FULL_TAG_NAMES[@]}

+ 1 - 1
bin/build_docs.sh

@@ -26,8 +26,8 @@ git pull
 cd "$REPO_DIR"
 
 echo "[+] Building docs"
-sphinx-apidoc -o docs archivebox
 cd "$REPO_DIR/docs"
+make clean
 make html
 # open docs/_build/html/index.html to see the output
 cd "$REPO_DIR"

+ 2 - 8
bin/build_pip.sh

@@ -11,21 +11,15 @@ set -o pipefail
 IFS=$'\n'
 
 REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && pwd )"
-
-if [[ -f "$REPO_DIR/.venv/bin/activate" ]]; then
-    source "$REPO_DIR/.venv/bin/activate"
-else
-    echo "[!] Warning: No virtualenv presesnt in $REPO_DIR/.venv, creating one now..."
-    python3 -m venv --system-site-packages --symlinks $REPO_DIR/.venv
-fi
 cd "$REPO_DIR"
 
 # Generate pdm.lock, requirements.txt, and package-lock.json
 bash ./bin/lock_pkgs.sh
+source .venv/bin/activate
 
 echo "[+] Building sdist, bdist_wheel, and egg_info"
 rm -Rf build dist
-pdm build
+uv build
 cp dist/* ./pip_dist/
 
 echo

+ 16 - 30
bin/lock_pkgs.sh

@@ -32,52 +32,40 @@ echo
 echo "[*] Cleaning up old lockfiles and build files"
 deactivate 2>/dev/null || true
 rm -Rf build dist
-rm -f pdm.lock
-rm -f pdm.dev.lock
+rm -f uv.lock
 rm -f requirements.txt
-rm -f requirements-dev.txt
 rm -f package-lock.json
 rm -f archivebox/package.json
 rm -f archivebox/package-lock.json
-rm -Rf ./.venv
-rm -Rf ./node_modules
-rm -Rf ./archivebox/node_modules
+# rm -Rf ./.venv
+# rm -Rf ./node_modules
+# rm -Rf ./archivebox/node_modules
 
 echo
 echo
 
 echo "[+] Generating dev & prod requirements.txt & pdm.lock from pyproject.toml..."
-pip install --upgrade pip setuptools
-pdm self update >/dev/null 2>&1 || true
-pdm venv create 3.12
+uv venv --python 3.12
+source .venv/bin/activate
 echo
 echo "pyproject.toml:    archivebox $(grep 'version = ' pyproject.toml | awk '{print $3}' | jq -r)"
 echo "$(which python):   $(python --version | head -n 1)"
-echo "$(which pdm):      $(pdm --version | head -n 1)"
-pdm info --env
-pdm info
+echo "$(which uv):       $(uv --version | head -n 1)"
 
 echo
 # https://pdm-project.org/latest/usage/lockfile/
 # prod
-pdm lock --group=':all' --production --lockfile pdm.lock --python="==3.12.*" --platform=linux
-pdm lock --group=':all' --production --lockfile pdm.lock --python="==3.12.*" --platform=macos --append
-pdm sync --group=':all' --production --lockfile pdm.lock --clean
-pdm export --group=':all' --production --lockfile pdm.lock --without-hashes -o requirements.txt
-# cp ./pdm.lock ./pip_dist/
-# cp ./requirements.txt ./pip_dist/
-
-# dev
-pdm lock --group=':all' --dev --lockfile pdm.dev.lock --python="==3.12.*" --platform=linux
-pdm lock --group=':all' --dev --lockfile pdm.dev.lock --python="==3.12.*" --platform=macos --append
-pdm sync --group=':all' --dev --lockfile pdm.dev.lock --clean
-pdm export --group=':all' --dev --lockfile pdm.dev.lock --without-hashes -o requirements-dev.txt
-# cp ./pdm.dev.lock ./pip_dist/
-# cp ./requirements-dev.txt ./pip_dist/
+uv lock
+uv pip compile pyproject.toml --all-extras -o requirements.txt >/dev/null
+uv sync --all-extras --frozen 2>/dev/null
 
 echo
 echo "[+] Generating package-lock.json from package.json..."
 npm install -g npm
+npm config set fund false --location=global &
+npm config set fund false &
+npm config set audit false --location=global &
+npm config set audit false &
 echo
 echo "package.json:    archivebox $(jq -r '.version' package.json)"
 echo
@@ -85,7 +73,7 @@ echo "$(which node):   $(node --version | head -n 1)"
 echo "$(which npm):    $(npm --version | head -n 1)"
 
 echo
-npm install --package-lock-only
+npm install --package-lock-only --prefer-offline
 cp package.json archivebox/package.json
 cp package-lock.json archivebox/package-lock.json
 
@@ -93,10 +81,8 @@ echo
 echo "[√] Finished. Don't forget to commit the new lockfiles:"
 echo
 ls "pyproject.toml" | cat
-ls "pdm.lock" | cat
-ls "pdm.dev.lock" | cat
 ls "requirements.txt" | cat
-ls "requirements-dev.txt" | cat
+ls "uv.lock" | cat
 echo
 ls "package.json" | cat
 ls "package-lock.json" | cat

+ 32 - 28
bin/release_docker.sh

@@ -8,43 +8,47 @@ set -o errexit
 set -o errtrace
 set -o nounset
 set -o pipefail
-IFS=$'\n'
+IFS=$' '
 
 REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && pwd )"
 cd "$REPO_DIR"
 
-SUPPORTED_PLATFORMS="linux/amd64,linux/arm64"   # no longer supported: linux/arm/v7
-
-TAG_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
+declare -a TAG_NAMES="$*"
+BRANCH_NAME="${1:-$(git rev-parse --abbrev-ref HEAD)}"
 VERSION="$(jq -r '.version' < "$REPO_DIR/package.json")"
-SHORT_VERSION="$(echo "$VERSION" | perl -pe 's/(\d+)\.(\d+)\.(\d+)/$1.$2/g')"
 GIT_SHA=sha-"$(git rev-parse --short HEAD)"
-SELECTED_PLATFORMS="${2:-$SUPPORTED_PLATFORMS}"
-
+SELECTED_PLATFORMS="linux/amd64,linux/arm64"
+
+# if not already in TAG_NAMES, add GIT_SHA and BRANCH_NAME  
+if ! echo "${TAG_NAMES[@]}" | grep -q "$GIT_SHA"; then
+   TAG_NAMES+=("$GIT_SHA")
+fi
+if ! echo "${TAG_NAMES[@]}" | grep -q "$BRANCH_NAME"; then
+   TAG_NAMES+=("$BRANCH_NAME")
+fi
+if ! echo "${TAG_NAMES[@]}" | grep -q "$VERSION"; then
+   TAG_NAMES+=("$VERSION")
+fi
+
+echo "[+] Building + releasing Docker image for $SELECTED_PLATFORMS: branch=$BRANCH_NAME version=$VERSION tags=${TAG_NAMES[*]}"
+
+declare -a FULL_TAG_NAMES
+# for each tag in TAG_NAMES, add archivebox/archivebox:tag and nikisweeting/archivebox:tag to FULL_TAG_NAMES
+for TAG_NAME in "${TAG_NAMES[@]}"; do
+    [[ "$TAG_NAME" == "" ]] && continue
+    FULL_TAG_NAMES+=("-t archivebox/archivebox:$TAG_NAME")
+    FULL_TAG_NAMES+=("-t nikisweeting/archivebox:$TAG_NAME")
+    FULL_TAG_NAMES+=("-t ghcr.io/archivebox/archivebox:$TAG_NAME")
+done
+echo "${FULL_TAG_NAMES[@]}"
+
+
+./bin/lock_pkgs.sh
 
 # echo "[*] Logging in to Docker Hub & Github Container Registry"
 # docker login --username=nikisweeting
 # docker login ghcr.io --username=pirate
 
-# echo "[^] Building docker image"
-# ./bin/build_docker.sh "$TAG_NAME" "$SELECTED_PLATFORMS"
-
 echo "[^] Uploading docker image"
-docker buildx build --platform "$SELECTED_PLATFORMS" --push . \
-               -t archivebox/archivebox:"$TAG_NAME" \
-               -t archivebox/archivebox:"$GIT_SHA" \
-               -t nikisweeting/archivebox:"$TAG_NAME" \
-               -t nikisweeting/archivebox:"$GIT_SHA" \
-               -t ghcr.io/archivebox/archivebox:"$TAG_NAME" \
-               -t ghcr.io/archivebox/archivebox:"$GIT_SHA"
-            #    -t archivebox/archivebox \
-            #    -t archivebox/archivebox:$VERSION \
-            #    -t archivebox/archivebox:$SHORT_VERSION \
-            #    -t archivebox/archivebox:latest \
-            #    -t nikisweeting/archivebox \
-            #    -t nikisweeting/archivebox:$VERSION \
-            #    -t nikisweeting/archivebox:$SHORT_VERSION \
-            #    -t nikisweeting/archivebox:latest \
-            #    -t ghcr.io/archivebox/archivebox:$VERSION \
-            #    -t ghcr.io/archivebox/archivebox:$SHORT_VERSION \
-
+# shellcheck disable=SC2068
+docker buildx build --platform "$SELECTED_PLATFORMS" --push . ${FULL_TAG_NAMES[@]}   

+ 1 - 4
bin/release_pip.sh

@@ -14,8 +14,5 @@ REPO_DIR="$( cd "$( dirname "${BASH_SOURCE[0]}" )" >/dev/null 2>&1 && cd .. && p
 cd "$REPO_DIR"
 source "$REPO_DIR/.venv/bin/activate"
 
-echo "[^] Publishing to Test PyPI..."
-pdm publish --repository testpypi
-
 echo "[^] Publishing to PyPI..."
-pdm publish --no-build
+uv publish

+ 0 - 1855
pdm.lock

@@ -1,1855 +0,0 @@
-# This file is @generated by PDM.
-# It is not intended for manual editing.
-
-[metadata]
-groups = ["default", "all", "ldap", "sonic"]
-strategy = ["inherit_metadata"]
-lock_version = "4.5.0"
-content_hash = "sha256:d6c891a0805024b0cdd752c09dad5785b8d2b57fd659f875213ab62c8357286c"
-
-[[metadata.targets]]
-requires_python = "==3.12.*"
-platform = "manylinux_2_17_x86_64"
-
-[[metadata.targets]]
-requires_python = "==3.12.*"
-platform = "macos_14_0_arm64"
-
-[[package]]
-name = "annotated-types"
-version = "0.7.0"
-requires_python = ">=3.8"
-summary = "Reusable constraint types to use with typing.Annotated"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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.0"
-requires_python = ">=3.9"
-summary = "High level compatibility layer for multiple asynchronous event loop implementations"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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.0-py3-none-any.whl", hash = "sha256:c7d2e9d63e31599eeb636c8c5c03a7e108d73b345f064f1c19fdc87b79036a9a"},
-    {file = "anyio-4.6.0.tar.gz", hash = "sha256:137b4559cbb034c477165047febb6ff83f390fc3b20bf181c1fc0a728cb8beeb"},
-]
-
-[[package]]
-name = "asgiref"
-version = "3.8.1"
-requires_python = ">=3.8"
-summary = "ASGI specs, helper code, and adapters"
-groups = ["default", "all", "ldap"]
-marker = "python_version == \"3.12\""
-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 = "asttokens"
-version = "2.4.1"
-summary = "Annotate AST trees with source code positions"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = "atomicwrites"
-version = "1.4.1"
-requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-summary = "Atomic file writes."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "atomicwrites-1.4.1.tar.gz", hash = "sha256:81b2c9071a49367a7f770170e5eec8cb66567cfbbc8c73d20ce5ca4a8d71cf11"},
-]
-
-[[package]]
-name = "attrs"
-version = "24.2.0"
-requires_python = ">=3.7"
-summary = "Classes Without Boilerplate"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "importlib-metadata; python_version < \"3.8\"",
-]
-files = [
-    {file = "attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2"},
-    {file = "attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346"},
-]
-
-[[package]]
-name = "autobahn"
-version = "24.4.2"
-requires_python = ">=3.9"
-summary = "WebSocket client & server library, WAMP real-time framework"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "cryptography>=3.4.6",
-    "hyperlink>=21.0.0",
-    "setuptools",
-    "txaio>=21.2.1",
-]
-files = [
-    {file = "autobahn-24.4.2-py2.py3-none-any.whl", hash = "sha256:c56a2abe7ac78abbfb778c02892d673a4de58fd004d088cd7ab297db25918e81"},
-    {file = "autobahn-24.4.2.tar.gz", hash = "sha256:a2d71ef1b0cf780b6d11f8b205fd2c7749765e65795f2ea7d823796642ee92c9"},
-]
-
-[[package]]
-name = "automat"
-version = "24.8.1"
-requires_python = ">=3.8"
-summary = "Self-service finite-state machines for the programmer on the go."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "typing-extensions; python_version < \"3.10\"",
-]
-files = [
-    {file = "Automat-24.8.1-py3-none-any.whl", hash = "sha256:bf029a7bc3da1e2c24da2343e7598affaa9f10bf0ab63ff808566ce90551e02a"},
-    {file = "automat-24.8.1.tar.gz", hash = "sha256:b34227cf63f6325b8ad2399ede780675083e439b20c323d376373d8ee6306d88"},
-]
-
-[[package]]
-name = "base32-crockford"
-version = "0.3.0"
-summary = "A Python implementation of Douglas Crockford's base32 encoding scheme"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "base32-crockford-0.3.0.tar.gz", hash = "sha256:115f5bd32ae32b724035cb02eb65069a8824ea08c08851eb80c8b9f63443a969"},
-    {file = "base32_crockford-0.3.0-py2.py3-none-any.whl", hash = "sha256:295ef5ffbf6ed96b6e739ffd36be98fa7e90a206dd18c39acefb15777eedfe6e"},
-]
-
-[[package]]
-name = "beautifulsoup4"
-version = "4.12.3"
-requires_python = ">=3.6.0"
-summary = "Screen-scraping library"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = "brotli"
-version = "1.1.0"
-summary = "Python bindings for the Brotli compression library"
-groups = ["default"]
-marker = "implementation_name == \"cpython\" and python_version == \"3.12\""
-files = [
-    {file = "Brotli-1.1.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:316cc9b17edf613ac76b1f1f305d2a748f1b976b033b049a6ecdfd5612c70409"},
-    {file = "Brotli-1.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0c5516f0aed654134a2fc936325cc2e642f8a0e096d075209672eb321cff408"},
-    {file = "Brotli-1.1.0.tar.gz", hash = "sha256:81de08ac11bcb85841e440c13611c00b67d3bf82698314928d0b676362546724"},
-]
-
-[[package]]
-name = "brotlicffi"
-version = "1.1.0.0"
-requires_python = ">=3.7"
-summary = "Python CFFI bindings to the Brotli library"
-groups = ["default"]
-marker = "implementation_name != \"cpython\" and python_version == \"3.12\""
-dependencies = [
-    "cffi>=1.0.0",
-]
-files = [
-    {file = "brotlicffi-1.1.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9feb210d932ffe7798ee62e6145d3a757eb6233aa9a4e7db78dd3690d7755814"},
-    {file = "brotlicffi-1.1.0.0.tar.gz", hash = "sha256:b77827a689905143f87915310b93b273ab17888fd43ef350d4832c4a71083c13"},
-]
-
-[[package]]
-name = "bx-django-utils"
-version = "79"
-summary = "Various Django utility functions"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "bx-py-utils>=92",
-    "django>=4.2",
-    "python-stdnum",
-]
-files = [
-    {file = "bx_django_utils-79-py3-none-any.whl", hash = "sha256:d50b10ace24b0b363574542faecf04a81029e2fec6d6e6525fe063ed06238e04"},
-    {file = "bx_django_utils-79.tar.gz", hash = "sha256:cb66087d4e9396281acf5a4394b749cff3062b66082d5726f6a8a342fdd35d0e"},
-]
-
-[[package]]
-name = "bx-py-utils"
-version = "104"
-requires_python = "<4,>=3.10"
-summary = "Various Python utility functions"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "bx_py_utils-104-py3-none-any.whl", hash = "sha256:c92ebc4fb122e3e3c228d984d0a1f5c3284c3da6aab1a1c753f7eb1f71bdab3a"},
-    {file = "bx_py_utils-104.tar.gz", hash = "sha256:508cfc1d0fa6c22298f697c4efaa913337847d488d8a53eeccfae9ee106123f6"},
-]
-
-[[package]]
-name = "certifi"
-version = "2024.8.30"
-requires_python = ">=3.6"
-summary = "Python package for providing Mozilla's CA Bundle."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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\" or implementation_name != \"cpython\") and python_version == \"3.12\""
-dependencies = [
-    "pycparser",
-]
-files = [
-    {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"},
-    {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"},
-    {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"},
-]
-
-[[package]]
-name = "channels"
-version = "4.1.0"
-requires_python = ">=3.8"
-summary = "Brings async, event-driven capabilities to Django 3.2 and up."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "Django>=4.2",
-    "asgiref<4,>=3.6.0",
-]
-files = [
-    {file = "channels-4.1.0-py3-none-any.whl", hash = "sha256:a3c4419307f582c3f71d67bfb6eff748ae819c2f360b9b141694d84f242baa48"},
-    {file = "channels-4.1.0.tar.gz", hash = "sha256:e0ed375719f5c1851861f05ed4ce78b0166f9245ca0ecd836cb77d4bb531489d"},
-]
-
-[[package]]
-name = "channels"
-version = "4.1.0"
-extras = ["daphne"]
-requires_python = ">=3.8"
-summary = "Brings async, event-driven capabilities to Django 3.2 and up."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "channels==4.1.0",
-    "daphne>=4.0.0",
-]
-files = [
-    {file = "channels-4.1.0-py3-none-any.whl", hash = "sha256:a3c4419307f582c3f71d67bfb6eff748ae819c2f360b9b141694d84f242baa48"},
-    {file = "channels-4.1.0.tar.gz", hash = "sha256:e0ed375719f5c1851861f05ed4ce78b0166f9245ca0ecd836cb77d4bb531489d"},
-]
-
-[[package]]
-name = "charset-normalizer"
-version = "3.3.2"
-requires_python = ">=3.7.0"
-summary = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "charset-normalizer-3.3.2.tar.gz", hash = "sha256:f30c3cb33b24454a82faecaf01b19c18562b1e89558fb6c56de4d9118a032fd5"},
-    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:0b2b64d2bb6d3fb9112bafa732def486049e63de9618b5843bcdd081d8144cd8"},
-    {file = "charset_normalizer-3.3.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:55086ee1064215781fff39a1af09518bc9255b50d6333f2e4c74ca09fac6a8f6"},
-    {file = "charset_normalizer-3.3.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90d558489962fd4918143277a773316e56c72da56ec7aa3dc3dbbe20fdfed15b"},
-    {file = "charset_normalizer-3.3.2-py3-none-any.whl", hash = "sha256:3e4d1f6587322d2788836a99c69062fbb091331ec940e02d12d179c1d53e25fc"},
-]
-
-[[package]]
-name = "constantly"
-version = "23.10.4"
-requires_python = ">=3.8"
-summary = "Symbolic constants in Python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "constantly-23.10.4-py3-none-any.whl", hash = "sha256:3fd9b4d1c3dc1ec9757f3c52aef7e53ad9323dbe39f51dfd4c43853b68dfa3f9"},
-    {file = "constantly-23.10.4.tar.gz", hash = "sha256:aa92b70a33e2ac0bb33cd745eb61776594dc48764b06c35e0efd050b7f1c7cbd"},
-]
-
-[[package]]
-name = "croniter"
-version = "3.0.3"
-requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,>=2.6"
-summary = "croniter provides iteration for datetime object with cron like format"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "python-dateutil",
-    "pytz>2021.1",
-]
-files = [
-    {file = "croniter-3.0.3-py2.py3-none-any.whl", hash = "sha256:b3bd11f270dc54ccd1f2397b813436015a86d30ffc5a7a9438eec1ed916f2101"},
-    {file = "croniter-3.0.3.tar.gz", hash = "sha256:34117ec1741f10a7bd0ec3ad7d8f0eb8fa457a2feb9be32e6a2250e158957668"},
-]
-
-[[package]]
-name = "cryptography"
-version = "43.0.1"
-requires_python = ">=3.7"
-summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "cffi>=1.12; platform_python_implementation != \"PyPy\"",
-]
-files = [
-    {file = "cryptography-43.0.1-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:8385d98f6a3bf8bb2d65a73e17ed87a3ba84f6991c155691c51112075f9ffc5d"},
-    {file = "cryptography-43.0.1-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:68aaecc4178e90719e95298515979814bda0cbada1256a4485414860bd7ab962"},
-    {file = "cryptography-43.0.1-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:ac119bb76b9faa00f48128b7f5679e1d8d437365c5d26f1c2c3f0da4ce1b553d"},
-    {file = "cryptography-43.0.1-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:58d4e9129985185a06d849aa6df265bdd5a74ca6e1b736a77959b498e0505b85"},
-    {file = "cryptography-43.0.1.tar.gz", hash = "sha256:203e92a75716d8cfb491dc47c79e17d0d9207ccffcbcb35f598fbe463ae3444d"},
-]
-
-[[package]]
-name = "daphne"
-version = "4.1.2"
-requires_python = ">=3.8"
-summary = "Django ASGI (HTTP/WebSocket) server"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "asgiref<4,>=3.5.2",
-    "autobahn>=22.4.2",
-    "twisted[tls]>=22.4",
-]
-files = [
-    {file = "daphne-4.1.2-py3-none-any.whl", hash = "sha256:618d1322bb4d875342b99dd2a10da2d9aae7ee3645f765965fdc1e658ea5290a"},
-    {file = "daphne-4.1.2.tar.gz", hash = "sha256:fcbcace38eb86624ae247c7ffdc8ac12f155d7d19eafac4247381896d6f33761"},
-]
-
-[[package]]
-name = "dateparser"
-version = "1.2.0"
-requires_python = ">=3.7"
-summary = "Date parsing library designed to parse dates from HTML pages"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "python-dateutil",
-    "pytz",
-    "regex!=2019.02.19,!=2021.8.27",
-    "tzlocal",
-]
-files = [
-    {file = "dateparser-1.2.0-py2.py3-none-any.whl", hash = "sha256:0b21ad96534e562920a0083e97fd45fa959882d4162acc358705144520a35830"},
-    {file = "dateparser-1.2.0.tar.gz", hash = "sha256:7975b43a4222283e0ae15be7b4999d08c9a70e2d378ac87385b1ccf2cffbbb30"},
-]
-
-[[package]]
-name = "decorator"
-version = "5.1.1"
-requires_python = ">=3.5"
-summary = "Decorators for Humans"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
-    {file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
-]
-
-[[package]]
-name = "django"
-version = "5.1.1"
-requires_python = ">=3.10"
-summary = "A high-level Python web framework that encourages rapid development and clean, pragmatic design."
-groups = ["default", "all", "ldap"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "asgiref<4,>=3.8.1",
-    "sqlparse>=0.3.1",
-    "tzdata; sys_platform == \"win32\"",
-]
-files = [
-    {file = "Django-5.1.1-py3-none-any.whl", hash = "sha256:71603f27dac22a6533fb38d83072eea9ddb4017fead6f67f2562a40402d61c3f"},
-    {file = "Django-5.1.1.tar.gz", hash = "sha256:021ffb7fdab3d2d388bc8c7c2434eb9c1f6f4d09e6119010bbb1694dda286bc2"},
-]
-
-[[package]]
-name = "django-admin-data-views"
-version = "0.4.1"
-requires_python = "<4,>=3.10"
-summary = "Add custom data views to django admin panel."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "Django>=3.2",
-    "django-settings-holder>=0.1.2",
-]
-files = [
-    {file = "django_admin_data_views-0.4.1-py3-none-any.whl", hash = "sha256:ed4988ce2f1c000bfa0ebef3b0126be1284399e03e23763eeb9d2c499745bf08"},
-    {file = "django_admin_data_views-0.4.1.tar.gz", hash = "sha256:fbdd2d5d0caf3b1cb1ffac57f7caff0e38f02dfc71dfa4e230c8c50f1741bb61"},
-]
-
-[[package]]
-name = "django-auth-ldap"
-version = "4.8.0"
-requires_python = ">=3.8"
-summary = "Django LDAP authentication backend"
-groups = ["all", "ldap"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "Django>=3.2",
-    "python-ldap>=3.1",
-]
-files = [
-    {file = "django-auth-ldap-4.8.0.tar.gz", hash = "sha256:604250938ddc9fda619f247c7a59b0b2f06e53a7d3f46a156f28aa30dd71a738"},
-    {file = "django_auth_ldap-4.8.0-py3-none-any.whl", hash = "sha256:4b4b944f3c28bce362f33fb6e8db68429ed8fd8f12f0c0c4b1a4344a7ef225ce"},
-]
-
-[[package]]
-name = "django-charid-field"
-version = "0.4"
-requires_python = ">=3.8,<4.0"
-summary = "Provides a char-based, prefixable ID field for your Django models. Supports cuid, ksuid, ulid, et al."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "django<6.0,>=3.2",
-]
-files = [
-    {file = "django_charid_field-0.4-py3-none-any.whl", hash = "sha256:70f140cb15ddde8459fc5a6cd8c4d24ed08d4c2aac2212d24df0ac724bc411f4"},
-    {file = "django_charid_field-0.4.tar.gz", hash = "sha256:3d8a0f4395f4c9b19667800254924503016160051c166c61e935e7366036cd38"},
-]
-
-[[package]]
-name = "django-extensions"
-version = "3.2.3"
-requires_python = ">=3.6"
-summary = "Extensions for Django"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "Django>=3.2",
-]
-files = [
-    {file = "django-extensions-3.2.3.tar.gz", hash = "sha256:44d27919d04e23b3f40231c4ab7af4e61ce832ef46d610cc650d53e68328410a"},
-    {file = "django_extensions-3.2.3-py3-none-any.whl", hash = "sha256:9600b7562f79a92cbf1fde6403c04fee314608fefbb595502e34383ae8203401"},
-]
-
-[[package]]
-name = "django-huey"
-version = "1.2.1"
-requires_python = ">=3.8"
-summary = "An extension for django and huey that supports multi queue management"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "django>=3.2",
-    "huey>=2.0",
-]
-files = [
-    {file = "django_huey-1.2.1-py3-none-any.whl", hash = "sha256:59c82b72fd4b6e60c219bd1fbab78acfe68a1c8d3efb1d3e42798a67d01a4aa2"},
-    {file = "django_huey-1.2.1.tar.gz", hash = "sha256:634abf1e707acef90dd00df4267458486f89a3117419000ec5584b1c4129701a"},
-]
-
-[[package]]
-name = "django-huey-monitor"
-version = "0.9.0"
-requires_python = ">=3.10"
-summary = "Django based tool for monitoring huey task queue: https://github.com/coleifer/huey"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "bx-django-utils",
-    "bx-py-utils",
-    "django",
-    "huey",
-]
-files = [
-    {file = "django-huey-monitor-0.9.0.tar.gz", hash = "sha256:03366d98579c07e132672aa760373949fecec108a0e91229e870bb21453c800b"},
-    {file = "django_huey_monitor-0.9.0-py3-none-any.whl", hash = "sha256:1d5922d182e138e288f99d6cdb326cbed20c831d4c906c96cba148b0979e648a"},
-]
-
-[[package]]
-name = "django-jsonform"
-version = "2.23.0"
-requires_python = ">=3.4"
-summary = "A user-friendly JSON editing form for Django admin."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "django>=2.0",
-]
-files = [
-    {file = "django_jsonform-2.23.0-py3-none-any.whl", hash = "sha256:92078022f0d5bd8ffec215131f2d9826dfa83f08cc910090447f8b6028242e21"},
-    {file = "django_jsonform-2.23.0.tar.gz", hash = "sha256:21d64555679b51606b1774e642f7ec36f78a5d439ee0dfa3508e7b4faecb0d5d"},
-]
-
-[[package]]
-name = "django-ninja"
-version = "1.3.0"
-requires_python = ">=3.7"
-summary = "Django Ninja - Fast Django REST framework"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "Django>=3.1",
-    "pydantic<3.0.0,>=2.0",
-]
-files = [
-    {file = "django_ninja-1.3.0-py3-none-any.whl", hash = "sha256:f58096b6c767d1403dfd6c49743f82d780d7b9688d9302ecab316ac1fa6131bb"},
-    {file = "django_ninja-1.3.0.tar.gz", hash = "sha256:5b320e2dc0f41a6032bfa7e1ebc33559ae1e911a426f0c6be6674a50b20819be"},
-]
-
-[[package]]
-name = "django-object-actions"
-version = "4.3.0"
-requires_python = "<4.0,>=3.7"
-summary = "A Django app for adding object tools for models in the admin"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "django_object_actions-4.3.0-py3-none-any.whl", hash = "sha256:1af87dedcfd5a35207a4b90c386c059e5f02ecf1d954e3131e25f4a04d01c963"},
-    {file = "django_object_actions-4.3.0.tar.gz", hash = "sha256:611f768d768c9ca7b48278573feb7c07966174f5c50a9323ab4d02d0c4b7501e"},
-]
-
-[[package]]
-name = "django-pydantic-field"
-version = "0.3.10"
-requires_python = ">=3.7"
-summary = "Django JSONField with Pydantic models as a Schema"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "django<6,>=3.1",
-    "pydantic<3,>=1.10",
-    "typing-extensions",
-]
-files = [
-    {file = "django_pydantic_field-0.3.10-py3-none-any.whl", hash = "sha256:c9824962d300dacd7009b76a64ef9ede81858cc769edbeb25a2c81d338c6f9b8"},
-    {file = "django_pydantic_field-0.3.10.tar.gz", hash = "sha256:9237ad99f2fd1f54aa19c4da68e6c92ef9bcf8d2240f205aeea44a8a9aecdd47"},
-]
-
-[[package]]
-name = "django-settings-holder"
-version = "0.1.2"
-requires_python = ">=3.9,<4"
-summary = "Object that allows settings to be accessed with attributes."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "django_settings_holder-0.1.2-py3-none-any.whl", hash = "sha256:7a65f888fc1e8427a807be72d43d5f3f242163e0a0eaf33a393592e6fff3e102"},
-    {file = "django_settings_holder-0.1.2.tar.gz", hash = "sha256:8ab0f2dabf5a1c79ec9e95e97a296808e0f2c48f6f9aa1da1b77b433ee1e2f9e"},
-]
-
-[[package]]
-name = "django-signal-webhooks"
-version = "0.3.0"
-requires_python = ">=3.9,<4"
-summary = "Add webhooks to django using signals."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "Django>=3.2",
-    "asgiref>=3.5.0",
-    "cryptography>=36.0.0",
-    "django-settings-holder>=0.1.0",
-    "httpx>=0.23.0",
-]
-files = [
-    {file = "django_signal_webhooks-0.3.0-py3-none-any.whl", hash = "sha256:64be32ff06c1b74fe80176395258cfb51f1757fed28f026285f38a44d559c00f"},
-    {file = "django_signal_webhooks-0.3.0.tar.gz", hash = "sha256:3efff4305a8c0555a17ce8f4cbb1006014afd7314862647db5724e06eec4493e"},
-]
-
-[[package]]
-name = "django-stubs"
-version = "5.1.0"
-requires_python = ">=3.8"
-summary = "Mypy stubs for Django"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "asgiref",
-    "django",
-    "django-stubs-ext>=5.1.0",
-    "tomli; python_version < \"3.11\"",
-    "types-PyYAML",
-    "typing-extensions>=4.11.0",
-]
-files = [
-    {file = "django_stubs-5.1.0-py3-none-any.whl", hash = "sha256:b98d49a80aa4adf1433a97407102d068de26c739c405431d93faad96dd282c40"},
-    {file = "django_stubs-5.1.0.tar.gz", hash = "sha256:86128c228b65e6c9a85e5dc56eb1c6f41125917dae0e21e6cfecdf1b27e630c5"},
-]
-
-[[package]]
-name = "django-stubs-ext"
-version = "5.1.0"
-requires_python = ">=3.8"
-summary = "Monkey-patching and extensions for django-stubs"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "django",
-    "typing-extensions",
-]
-files = [
-    {file = "django_stubs_ext-5.1.0-py3-none-any.whl", hash = "sha256:a455fc222c90b30b29ad8c53319559f5b54a99b4197205ddbb385aede03b395d"},
-    {file = "django_stubs_ext-5.1.0.tar.gz", hash = "sha256:ed7d51c0b731651879fc75f331fb0806d98b67bfab464e96e2724db6b46ef926"},
-]
-
-[[package]]
-name = "django-taggit"
-version = "1.3.0"
-requires_python = ">=3.5"
-summary = "django-taggit is a reusable Django application for simple tagging."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "Django>=1.11",
-]
-files = [
-    {file = "django-taggit-1.3.0.tar.gz", hash = "sha256:4a833bf71f4c2deddd9745924eee53be1c075d7f0020a06f12e29fa3d752732d"},
-    {file = "django_taggit-1.3.0-py3-none-any.whl", hash = "sha256:609b0223d8a652f3fae088b7fd29f294fdadaca2d7931d45c27d6c59b02fdf31"},
-]
-
-[[package]]
-name = "et-xmlfile"
-version = "1.1.0"
-requires_python = ">=3.6"
-summary = "An implementation of lxml.xmlfile for the standard library"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "et_xmlfile-1.1.0-py3-none-any.whl", hash = "sha256:a2ba85d1d6a74ef63837eed693bcb89c3f752169b0e3e7ae5b16ca5e1b3deada"},
-    {file = "et_xmlfile-1.1.0.tar.gz", hash = "sha256:8eb9e2bc2f8c97e37a2dc85a09ecdcdec9d8a396530a6d5a33b30b9a92da0c5c"},
-]
-
-[[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 = ["default"]
-marker = "python_version == \"3.12\""
-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 = "feedparser"
-version = "6.0.11"
-requires_python = ">=3.6"
-summary = "Universal feed parser, handles RSS 0.9x, RSS 1.0, RSS 2.0, CDF, Atom 0.3, and Atom 1.0 feeds"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "sgmllib3k",
-]
-files = [
-    {file = "feedparser-6.0.11-py3-none-any.whl", hash = "sha256:0be7ee7b395572b19ebeb1d6aafb0028dee11169f1c934e0ed67d54992f4ad45"},
-    {file = "feedparser-6.0.11.tar.gz", hash = "sha256:c9d0407b64c6f2a065d0ebb292c2b35c01050cc0dc33757461aaabdc4c4184d5"},
-]
-
-[[package]]
-name = "ftfy"
-version = "6.2.3"
-requires_python = "<4,>=3.8.1"
-summary = "Fixes mojibake and other problems with Unicode, after the fact"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "wcwidth<0.3.0,>=0.2.12",
-]
-files = [
-    {file = "ftfy-6.2.3-py3-none-any.whl", hash = "sha256:f15761b023f3061a66207d33f0c0149ad40a8319fd16da91796363e2c049fdf8"},
-    {file = "ftfy-6.2.3.tar.gz", hash = "sha256:79b505988f29d577a58a9069afe75553a02a46e42de6091c0660cdc67812badc"},
-]
-
-[[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"]
-marker = "python_version == \"3.12\""
-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 = "httpcore"
-version = "1.0.6"
-requires_python = ">=3.8"
-summary = "A minimal low-level HTTP client."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "certifi",
-    "h11<0.15,>=0.13",
-]
-files = [
-    {file = "httpcore-1.0.6-py3-none-any.whl", hash = "sha256:27b59625743b85577a8c0e10e55b50b5368a4f2cfe8cc7bcfa9cf00829c2682f"},
-    {file = "httpcore-1.0.6.tar.gz", hash = "sha256:73f6dbd6eb8c21bbf7ef8efad555481853f5f6acdeaff1edb0694289269ee17f"},
-]
-
-[[package]]
-name = "httpx"
-version = "0.27.2"
-requires_python = ">=3.8"
-summary = "The next generation HTTP client."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = "huey"
-version = "2.5.2"
-summary = "huey, a little task queue"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "huey-2.5.2.tar.gz", hash = "sha256:df33db474c05414ed40ee2110e9df692369871734da22d74ffb035a4bd74047f"},
-]
-
-[[package]]
-name = "hyperlink"
-version = "21.0.0"
-requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*"
-summary = "A featureful, immutable, and correct URL for Python."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "idna>=2.5",
-    "typing; python_version < \"3.5\"",
-]
-files = [
-    {file = "hyperlink-21.0.0-py2.py3-none-any.whl", hash = "sha256:e6b14c37ecb73e89c77d78cdb4c2cc8f3fb59a885c5b3f819ff4ed80f25af1b4"},
-    {file = "hyperlink-21.0.0.tar.gz", hash = "sha256:427af957daa58bc909471c6c40f74c5450fa123dd093fc53efd2e91d2705a56b"},
-]
-
-[[package]]
-name = "idna"
-version = "3.10"
-requires_python = ">=3.6"
-summary = "Internationalized Domain Names in Applications (IDNA)"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"},
-    {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"},
-]
-
-[[package]]
-name = "incremental"
-version = "24.7.2"
-requires_python = ">=3.8"
-summary = "A small library that versions your Python projects."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "setuptools>=61.0",
-    "tomli; python_version < \"3.11\"",
-]
-files = [
-    {file = "incremental-24.7.2-py3-none-any.whl", hash = "sha256:8cb2c3431530bec48ad70513931a760f446ad6c25e8333ca5d95e24b0ed7b8fe"},
-    {file = "incremental-24.7.2.tar.gz", hash = "sha256:fb4f1d47ee60efe87d4f6f0ebb5f70b9760db2b2574c59c8e8912be4ebd464c9"},
-]
-
-[[package]]
-name = "ipython"
-version = "8.28.0"
-requires_python = ">=3.10"
-summary = "IPython: Productive Interactive Computing"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "colorama; sys_platform == \"win32\"",
-    "decorator",
-    "exceptiongroup; python_version < \"3.11\"",
-    "jedi>=0.16",
-    "matplotlib-inline",
-    "pexpect>4.3; sys_platform != \"win32\" and sys_platform != \"emscripten\"",
-    "prompt-toolkit<3.1.0,>=3.0.41",
-    "pygments>=2.4.0",
-    "stack-data",
-    "traitlets>=5.13.0",
-    "typing-extensions>=4.6; python_version < \"3.12\"",
-]
-files = [
-    {file = "ipython-8.28.0-py3-none-any.whl", hash = "sha256:530ef1e7bb693724d3cdc37287c80b07ad9b25986c007a53aa1857272dac3f35"},
-    {file = "ipython-8.28.0.tar.gz", hash = "sha256:0d0d15ca1e01faeb868ef56bc7ee5a0de5bd66885735682e8a322ae289a13d1a"},
-]
-
-[[package]]
-name = "jedi"
-version = "0.19.1"
-requires_python = ">=3.6"
-summary = "An autocompletion tool for Python that can be used for text editors."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "parso<0.9.0,>=0.8.3",
-]
-files = [
-    {file = "jedi-0.19.1-py2.py3-none-any.whl", hash = "sha256:e983c654fe5c02867aef4cdfce5a2fbb4a50adc0af145f70504238f18ef5e7e0"},
-    {file = "jedi-0.19.1.tar.gz", hash = "sha256:cf0496f3651bc65d7174ac1b7d043eff454892c708a87d1b683e57b569927ffd"},
-]
-
-[[package]]
-name = "mailchecker"
-version = "6.0.11"
-summary = "Cross-language email validation. Backed by a database of thousands throwable email providers."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "mailchecker-6.0.11.tar.gz", hash = "sha256:bf2490e26a3a9ac385760838e3fcc7321a6be1980fdad5746d07b63a06479aa2"},
-]
-
-[[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"]
-marker = "python_version == \"3.12\""
-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 = "matplotlib-inline"
-version = "0.1.7"
-requires_python = ">=3.8"
-summary = "Inline Matplotlib backend for Jupyter"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "traitlets",
-]
-files = [
-    {file = "matplotlib_inline-0.1.7-py3-none-any.whl", hash = "sha256:df192d39a4ff8f21b1895d72e6a13f5fcc5099f00fa84384e0ea28c2cc0653ca"},
-    {file = "matplotlib_inline-0.1.7.tar.gz", hash = "sha256:8423b23ec666be3d16e16b60bdd8ac4e86e840ebd1dd11a30b9f117f2fa0ab90"},
-]
-
-[[package]]
-name = "mdurl"
-version = "0.1.2"
-requires_python = ">=3.7"
-summary = "Markdown URL utilities"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = "mutagen"
-version = "1.47.0"
-requires_python = ">=3.7"
-summary = "read and write audio tags for many formats"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "mutagen-1.47.0-py3-none-any.whl", hash = "sha256:edd96f50c5907a9539d8e5bba7245f62c9f520aef333d13392a79a4f70aca719"},
-    {file = "mutagen-1.47.0.tar.gz", hash = "sha256:719fadef0a978c31b4cf3c956261b3c58b6948b32023078a2117b1de09f0fc99"},
-]
-
-[[package]]
-name = "mypy-extensions"
-version = "1.0.0"
-requires_python = ">=3.5"
-summary = "Type system extensions for programs checked with the mypy type checker."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d"},
-    {file = "mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782"},
-]
-
-[[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"]
-marker = "python_version == \"3.12\""
-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 = "parso"
-version = "0.8.4"
-requires_python = ">=3.6"
-summary = "A Python Parser"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "parso-0.8.4-py2.py3-none-any.whl", hash = "sha256:a418670a20291dacd2dddc80c377c5c3791378ee1e8d12bffc35420643d43f18"},
-    {file = "parso-0.8.4.tar.gz", hash = "sha256:eb3a7b58240fb99099a345571deecc0f9540ea5f4dd2fe14c2a99d6b281ab92d"},
-]
-
-[[package]]
-name = "pexpect"
-version = "4.9.0"
-summary = "Pexpect allows easy control of interactive console applications."
-groups = ["default"]
-marker = "(sys_platform != \"win32\" and sys_platform != \"emscripten\") and python_version == \"3.12\""
-dependencies = [
-    "ptyprocess>=0.5",
-]
-files = [
-    {file = "pexpect-4.9.0-py2.py3-none-any.whl", hash = "sha256:7236d1e080e4936be2dc3e326cec0af72acf9212a7e1d060210e70a47e253523"},
-    {file = "pexpect-4.9.0.tar.gz", hash = "sha256:ee7d41123f3c9911050ea2c2dac107568dc43b2d3b0c7557a33212c398ead30f"},
-]
-
-[[package]]
-name = "phonenumbers"
-version = "8.13.47"
-summary = "Python version of Google's common library for parsing, formatting, storing and validating international phone numbers."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "phonenumbers-8.13.47-py2.py3-none-any.whl", hash = "sha256:5d3c0142ef7055ca5551884352e3b6b93bfe002a0bc95b8eaba39b0e2184541b"},
-    {file = "phonenumbers-8.13.47.tar.gz", hash = "sha256:53c5e7c6d431cafe4efdd44956078404ae9bc8b0eacc47be3105d3ccc88aaffa"},
-]
-
-[[package]]
-name = "pluggy"
-version = "1.5.0"
-requires_python = ">=3.8"
-summary = "plugin and hook calling mechanisms for python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = "prompt-toolkit"
-version = "3.0.48"
-requires_python = ">=3.7.0"
-summary = "Library for building powerful interactive command lines in Python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "wcwidth",
-]
-files = [
-    {file = "prompt_toolkit-3.0.48-py3-none-any.whl", hash = "sha256:f49a827f90062e411f1ce1f854f2aedb3c23353244f8108b89283587397ac10e"},
-    {file = "prompt_toolkit-3.0.48.tar.gz", hash = "sha256:d6623ab0477a80df74e646bdbc93621143f5caf104206aa29294d53de1a03d90"},
-]
-
-[[package]]
-name = "psutil"
-version = "6.0.0"
-requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
-summary = "Cross-platform lib for process and system monitoring in Python."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "psutil-6.0.0-cp36-abi3-manylinux_2_12_x86_64.manylinux2010_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5fd9a97c8e94059b0ef54a7d4baf13b405011176c3b6ff257c247cae0d560ecd"},
-    {file = "psutil-6.0.0-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:ffe7fc9b6b36beadc8c322f84e1caff51e8703b88eee1da46d1e3a6ae11b4fd0"},
-    {file = "psutil-6.0.0.tar.gz", hash = "sha256:8faae4f310b6d969fa26ca0545338b21f73c6b15db7c4a8d934a5482faa818f2"},
-]
-
-[[package]]
-name = "ptyprocess"
-version = "0.7.0"
-summary = "Run a subprocess in a pseudo terminal"
-groups = ["default"]
-marker = "(sys_platform != \"win32\" and sys_platform != \"emscripten\") and python_version == \"3.12\""
-files = [
-    {file = "ptyprocess-0.7.0-py2.py3-none-any.whl", hash = "sha256:4b41f3967fce3af57cc7e94b888626c18bf37a083e3651ca8feeb66d492fef35"},
-    {file = "ptyprocess-0.7.0.tar.gz", hash = "sha256:5c5d0a3b48ceee0b48485e0c26037c0acd7d29765ca3fbb5cb3831d347423220"},
-]
-
-[[package]]
-name = "pure-eval"
-version = "0.2.3"
-summary = "Safely evaluate AST nodes without side effects"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "pure_eval-0.2.3-py3-none-any.whl", hash = "sha256:1db8e35b67b3d218d818ae653e27f06c3aa420901fa7b081ca98cbedc874e0d0"},
-    {file = "pure_eval-0.2.3.tar.gz", hash = "sha256:5f4e983f40564c576c7c8635ae88db5956bb2229d7e9237d03b3c0b0190eaf42"},
-]
-
-[[package]]
-name = "py-machineid"
-version = "0.6.0"
-summary = "Get the unique machine ID of any host (without admin privileges)"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "winregistry; sys_platform == \"win32\"",
-]
-files = [
-    {file = "py-machineid-0.6.0.tar.gz", hash = "sha256:00c38d8521d429a4539bdd92967234db28a1a2b4b263062b351ca002332e633f"},
-    {file = "py_machineid-0.6.0-py3-none-any.whl", hash = "sha256:63214f8a98737311716b29d279716dc121a6495f16486caf5c032433f81cdfd6"},
-]
-
-[[package]]
-name = "pyasn1"
-version = "0.6.1"
-requires_python = ">=3.8"
-summary = "Pure-Python implementation of ASN.1 types and DER/BER/CER codecs (X.208)"
-groups = ["default", "all", "ldap"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "pyasn1-0.6.1-py3-none-any.whl", hash = "sha256:0d632f46f2ba09143da3a8afe9e33fb6f92fa2320ab7e886e2d0f7672af84629"},
-    {file = "pyasn1-0.6.1.tar.gz", hash = "sha256:6f580d2bdd84365380830acf45550f2511469f673cb4a5ae3857a3170128b034"},
-]
-
-[[package]]
-name = "pyasn1-modules"
-version = "0.4.1"
-requires_python = ">=3.8"
-summary = "A collection of ASN.1-based protocols modules"
-groups = ["default", "all", "ldap"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "pyasn1<0.7.0,>=0.4.6",
-]
-files = [
-    {file = "pyasn1_modules-0.4.1-py3-none-any.whl", hash = "sha256:49bfa96b45a292b711e986f222502c1c9a5e1f4e568fc30e2574a6c7d07838fd"},
-    {file = "pyasn1_modules-0.4.1.tar.gz", hash = "sha256:c28e2dbf9c06ad61c71a075c7e0f9fd0f1b0bb2d2ad4377f240d33ac2ab60a7c"},
-]
-
-[[package]]
-name = "pycparser"
-version = "2.22"
-requires_python = ">=3.8"
-summary = "C parser in Python"
-groups = ["default"]
-marker = "(platform_python_implementation != \"PyPy\" or implementation_name != \"cpython\") and python_version == \"3.12\""
-files = [
-    {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"},
-    {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"},
-]
-
-[[package]]
-name = "pycryptodomex"
-version = "3.21.0"
-requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7"
-summary = "Cryptographic library for Python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "pycryptodomex-3.21.0-cp36-abi3-macosx_10_9_universal2.whl", hash = "sha256:34325b84c8b380675fd2320d0649cdcbc9cf1e0d1526edbe8fce43ed858cdc7e"},
-    {file = "pycryptodomex-3.21.0-cp36-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9aa0cf13a1a1128b3e964dc667e5fe5c6235f7d7cfb0277213f0e2a783837cc2"},
-    {file = "pycryptodomex-3.21.0.tar.gz", hash = "sha256:222d0bd05381dd25c32dd6065c071ebf084212ab79bab4599ba9e6a3e0009e6c"},
-]
-
-[[package]]
-name = "pydantic"
-version = "2.9.2"
-requires_python = ">=3.8"
-summary = "Data validation using Python type hints"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "annotated-types>=0.6.0",
-    "pydantic-core==2.23.4",
-    "typing-extensions>=4.12.2; python_version >= \"3.13\"",
-    "typing-extensions>=4.6.1; python_version < \"3.13\"",
-]
-files = [
-    {file = "pydantic-2.9.2-py3-none-any.whl", hash = "sha256:f048cec7b26778210e28a0459867920654d48e5e62db0958433636cde4254f12"},
-    {file = "pydantic-2.9.2.tar.gz", hash = "sha256:d155cef71265d1e9807ed1c32b4c8deec042a44a50a4188b25ac67ecd81a9c0f"},
-]
-
-[[package]]
-name = "pydantic-core"
-version = "2.23.4"
-requires_python = ">=3.8"
-summary = "Core functionality for Pydantic validation and serialization"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "typing-extensions!=4.7.0,>=4.6.0",
-]
-files = [
-    {file = "pydantic_core-2.23.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f69a8e0b033b747bb3e36a44e7732f0c99f7edd5cea723d45bc0d6e95377ffee"},
-    {file = "pydantic_core-2.23.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:128585782e5bfa515c590ccee4b727fb76925dd04a98864182b22e89a4e6ed36"},
-    {file = "pydantic_core-2.23.4.tar.gz", hash = "sha256:2584f7cf844ac4d970fba483a717dbe10c1c1c96a969bf65d61ffe94df1b2863"},
-]
-
-[[package]]
-name = "pydantic-pkgr"
-version = "0.4.4"
-requires_python = ">=3.10"
-summary = "System package manager APIs in strongly typed Python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "pydantic-core>=2.18.2",
-    "pydantic>=2.7.1",
-    "typing-extensions>=4.11.0",
-]
-files = [
-    {file = "pydantic_pkgr-0.4.4-py3-none-any.whl", hash = "sha256:f0b050543909cefb979a8ef238b6ba7010b7e05de9924c8a4ba20c567c6b1489"},
-    {file = "pydantic_pkgr-0.4.4.tar.gz", hash = "sha256:b49964f6228b7ab232a00ec638534e38a8f04b892dc396b41a3e121c50248599"},
-]
-
-[[package]]
-name = "pydantic-settings"
-version = "2.5.2"
-requires_python = ">=3.8"
-summary = "Settings management using Pydantic"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "pydantic>=2.7.0",
-    "python-dotenv>=0.21.0",
-]
-files = [
-    {file = "pydantic_settings-2.5.2-py3-none-any.whl", hash = "sha256:2c912e55fd5794a59bf8c832b9de832dcfdf4778d79ff79b708744eed499a907"},
-    {file = "pydantic_settings-2.5.2.tar.gz", hash = "sha256:f90b139682bee4d2065273d5185d71d37ea46cfe57e1b5ae184fc6a0b2484ca0"},
-]
-
-[[package]]
-name = "pygments"
-version = "2.18.0"
-requires_python = ">=3.8"
-summary = "Pygments is a syntax highlighting package written in Python."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = "pyopenssl"
-version = "24.2.1"
-requires_python = ">=3.7"
-summary = "Python wrapper module around the OpenSSL library"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "cryptography<44,>=41.0.5",
-]
-files = [
-    {file = "pyOpenSSL-24.2.1-py3-none-any.whl", hash = "sha256:967d5719b12b243588573f39b0c677637145c7a1ffedcd495a487e58177fbb8d"},
-    {file = "pyopenssl-24.2.1.tar.gz", hash = "sha256:4247f0dbe3748d560dcbb2ff3ea01af0f9a1a001ef5f7c4c647956ed8cbf0e95"},
-]
-
-[[package]]
-name = "python-benedict"
-version = "0.33.2"
-summary = "python-benedict is a dict subclass with keylist/keypath/keyattr support, normalized I/O operations (base64, csv, ini, json, pickle, plist, query-string, toml, xls, xml, yaml) and many utilities... for humans, obviously."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "python-fsutil<1.0.0,>=0.9.3",
-    "python-slugify<9.0.0,>=7.0.0",
-    "requests<3.0.0,>=2.26.0",
-]
-files = [
-    {file = "python-benedict-0.33.2.tar.gz", hash = "sha256:662de43bffb4e127da2056447f8ddd7f6f5c89b72dd66d289cf9abd1cc2720c8"},
-    {file = "python_benedict-0.33.2-py3-none-any.whl", hash = "sha256:50a69b601b34d4ad7b67fe94e3266ec05046bc547a4132fe43fd8fbd41aeefaa"},
-]
-
-[[package]]
-name = "python-benedict"
-version = "0.33.2"
-extras = ["html", "toml", "xls", "xml", "yaml"]
-summary = "python-benedict is a dict subclass with keylist/keypath/keyattr support, normalized I/O operations (base64, csv, ini, json, pickle, plist, query-string, toml, xls, xml, yaml) and many utilities... for humans, obviously."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "beautifulsoup4<5.0.0,>=4.12.0",
-    "openpyxl<4.0.0,>=3.0.0",
-    "python-benedict==0.33.2",
-    "python-benedict[xml]",
-    "pyyaml<7.0,>=6.0",
-    "toml<1.0.0,>=0.10.2",
-    "xlrd<3.0.0,>=2.0.0",
-    "xmltodict<1.0.0,>=0.12.0",
-]
-files = [
-    {file = "python-benedict-0.33.2.tar.gz", hash = "sha256:662de43bffb4e127da2056447f8ddd7f6f5c89b72dd66d289cf9abd1cc2720c8"},
-    {file = "python_benedict-0.33.2-py3-none-any.whl", hash = "sha256:50a69b601b34d4ad7b67fe94e3266ec05046bc547a4132fe43fd8fbd41aeefaa"},
-]
-
-[[package]]
-name = "python-benedict"
-version = "0.33.2"
-extras = ["io", "parse"]
-summary = "python-benedict is a dict subclass with keylist/keypath/keyattr support, normalized I/O operations (base64, csv, ini, json, pickle, plist, query-string, toml, xls, xml, yaml) and many utilities... for humans, obviously."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "ftfy<7.0.0,>=6.0.0",
-    "mailchecker<7.0.0,>=4.1.0",
-    "phonenumbers<9.0.0,>=8.12.0",
-    "python-benedict==0.33.2",
-    "python-benedict[html,toml,xls,xml,yaml]",
-    "python-dateutil<3.0.0,>=2.8.0",
-]
-files = [
-    {file = "python-benedict-0.33.2.tar.gz", hash = "sha256:662de43bffb4e127da2056447f8ddd7f6f5c89b72dd66d289cf9abd1cc2720c8"},
-    {file = "python_benedict-0.33.2-py3-none-any.whl", hash = "sha256:50a69b601b34d4ad7b67fe94e3266ec05046bc547a4132fe43fd8fbd41aeefaa"},
-]
-
-[[package]]
-name = "python-benedict"
-version = "0.33.2"
-extras = ["xml"]
-summary = "python-benedict is a dict subclass with keylist/keypath/keyattr support, normalized I/O operations (base64, csv, ini, json, pickle, plist, query-string, toml, xls, xml, yaml) and many utilities... for humans, obviously."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "python-benedict==0.33.2",
-    "xmltodict<1.0.0,>=0.12.0",
-]
-files = [
-    {file = "python-benedict-0.33.2.tar.gz", hash = "sha256:662de43bffb4e127da2056447f8ddd7f6f5c89b72dd66d289cf9abd1cc2720c8"},
-    {file = "python_benedict-0.33.2-py3-none-any.whl", hash = "sha256:50a69b601b34d4ad7b67fe94e3266ec05046bc547a4132fe43fd8fbd41aeefaa"},
-]
-
-[[package]]
-name = "python-crontab"
-version = "3.2.0"
-summary = "Python Crontab API"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "python-dateutil",
-]
-files = [
-    {file = "python_crontab-3.2.0-py3-none-any.whl", hash = "sha256:82cb9b6a312d41ff66fd3caf3eed7115c28c195bfb50711bc2b4b9592feb9fe5"},
-    {file = "python_crontab-3.2.0.tar.gz", hash = "sha256:40067d1dd39ade3460b2ad8557c7651514cd3851deffff61c5c60e1227c5c36b"},
-]
-
-[[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"]
-marker = "python_version == \"3.12\""
-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"]
-marker = "python_version == \"3.12\""
-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 = "python-fsutil"
-version = "0.14.1"
-summary = "high-level file-system operations for lazy devs."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "python-fsutil-0.14.1.tar.gz", hash = "sha256:8fb204fa8059f37bdeee8a1dc0fff010170202ea47c4225ee71bb3c26f3997be"},
-    {file = "python_fsutil-0.14.1-py3-none-any.whl", hash = "sha256:0d45e623f0f4403f674bdd8ae7aa7d24a4b3132ea45c65416bd2865e6b20b035"},
-]
-
-[[package]]
-name = "python-ldap"
-version = "3.4.4"
-requires_python = ">=3.6"
-summary = "Python modules for implementing LDAP clients"
-groups = ["all", "ldap"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "pyasn1-modules>=0.1.5",
-    "pyasn1>=0.3.7",
-]
-files = [
-    {file = "python-ldap-3.4.4.tar.gz", hash = "sha256:7edb0accec4e037797705f3a05cbf36a9fde50d08c8f67f2aef99a2628fab828"},
-]
-
-[[package]]
-name = "python-slugify"
-version = "8.0.4"
-requires_python = ">=3.7"
-summary = "A Python slugify application that also handles Unicode"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "text-unidecode>=1.3",
-]
-files = [
-    {file = "python-slugify-8.0.4.tar.gz", hash = "sha256:59202371d1d05b54a9e7720c5e038f928f45daaffe41dd10822f3907b937c856"},
-    {file = "python_slugify-8.0.4-py2.py3-none-any.whl", hash = "sha256:276540b79961052b66b7d116620b36518847f52d5fd9e3a70164fc8c50faa6b8"},
-]
-
-[[package]]
-name = "python-stdnum"
-version = "1.20"
-summary = "Python module to handle standardized numbers and codes"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "python-stdnum-1.20.tar.gz", hash = "sha256:ad2a2cf2eb025de408210235f36b4ae31252de3186240ccaa8126e117cb82690"},
-    {file = "python_stdnum-1.20-py2.py3-none-any.whl", hash = "sha256:111008e10391d54fb2afad2a10df70d5cb0c6c0a7ec82fec6f022cb8712961d3"},
-]
-
-[[package]]
-name = "pytz"
-version = "2024.2"
-summary = "World timezone definitions, modern and historical"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"},
-    {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"},
-    {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"},
-]
-
-[[package]]
-name = "regex"
-version = "2024.9.11"
-requires_python = ">=3.8"
-summary = "Alternative regular expression module, to replace re."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "regex-2024.9.11-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b0d0a6c64fcc4ef9c69bd5b3b3626cc3776520a1637d8abaa62b9edc147a58f7"},
-    {file = "regex-2024.9.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5b513b6997a0b2f10e4fd3a1313568e373926e8c252bd76c960f96fd039cd28d"},
-    {file = "regex-2024.9.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:85ab7824093d8f10d44330fe1e6493f756f252d145323dd17ab6b48733ff6c0a"},
-    {file = "regex-2024.9.11.tar.gz", hash = "sha256:6c188c307e8433bcb63dc1915022deb553b4203a70722fc542c363bf120a01fd"},
-]
-
-[[package]]
-name = "requests"
-version = "2.32.3"
-requires_python = ">=3.8"
-summary = "Python HTTP for Humans."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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 = "rich"
-version = "13.9.2"
-requires_python = ">=3.8.0"
-summary = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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.2-py3-none-any.whl", hash = "sha256:8c82a3d3f8dcfe9e734771313e606b39d8247bb6b826e196f4914b333b743cf1"},
-    {file = "rich-13.9.2.tar.gz", hash = "sha256:51a2c62057461aaf7152b4d611168f93a9fc73068f8ded2790f29fe2b5366d0c"},
-]
-
-[[package]]
-name = "rich-argparse"
-version = "1.5.2"
-requires_python = ">=3.8"
-summary = "Rich help formatters for argparse and optparse"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "rich>=11.0.0",
-]
-files = [
-    {file = "rich_argparse-1.5.2-py3-none-any.whl", hash = "sha256:7027503d5849e27fc7cc85fb58504363606f2ec1c8b3c27d9a8ad28788faf877"},
-    {file = "rich_argparse-1.5.2.tar.gz", hash = "sha256:84d348d5b6dafe99fffe2c7ea1ca0afe14096c921693445b9eee65ee4fcbfd2c"},
-]
-
-[[package]]
-name = "service-identity"
-version = "24.1.0"
-requires_python = ">=3.8"
-summary = "Service identity verification for pyOpenSSL & cryptography."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "attrs>=19.1.0",
-    "cryptography",
-    "pyasn1",
-    "pyasn1-modules",
-]
-files = [
-    {file = "service_identity-24.1.0-py3-none-any.whl", hash = "sha256:a28caf8130c8a5c1c7a6f5293faaf239bbfb7751e4862436920ee6f2616f568a"},
-    {file = "service_identity-24.1.0.tar.gz", hash = "sha256:6829c9d62fb832c2e1c435629b0a8c476e1929881f28bee4d20bc24161009221"},
-]
-
-[[package]]
-name = "setuptools"
-version = "75.1.0"
-requires_python = ">=3.8"
-summary = "Easily download, build, install, upgrade, and uninstall Python packages"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "setuptools-75.1.0-py3-none-any.whl", hash = "sha256:35ab7fd3bcd95e6b7fd704e4a1539513edad446c097797f2985e0e4b960772f2"},
-    {file = "setuptools-75.1.0.tar.gz", hash = "sha256:d59a21b17a275fb872a9c3dae73963160ae079f1049ed956880cd7c09b120538"},
-]
-
-[[package]]
-name = "sgmllib3k"
-version = "1.0.0"
-summary = "Py3k port of sgmllib."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "sgmllib3k-1.0.0.tar.gz", hash = "sha256:7868fb1c8bfa764c1ac563d3cf369c381d1325d36124933a726f29fcdaa812e9"},
-]
-
-[[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"]
-marker = "python_version == \"3.12\""
-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"]
-marker = "python_version == \"3.12\""
-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 = "sonic-client"
-version = "1.0.0"
-summary = "python client for sonic search backend"
-groups = ["all", "sonic"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "sonic-client-1.0.0.tar.gz", hash = "sha256:fe324c7354670488ed84847f6a6727d3cb5fb3675cb9b61396dcf5720e5aca66"},
-    {file = "sonic_client-1.0.0-py3-none-any.whl", hash = "sha256:291bf292861e97a2dd765ff0c8754ea9631383680d31a63ec3da6f5aa5f4beda"},
-]
-
-[[package]]
-name = "soupsieve"
-version = "2.6"
-requires_python = ">=3.8"
-summary = "A modern CSS selector implementation for Beautiful Soup."
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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.1"
-requires_python = ">=3.8"
-summary = "A non-validating SQL parser."
-groups = ["default", "all", "ldap"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "sqlparse-0.5.1-py3-none-any.whl", hash = "sha256:773dcbf9a5ab44a090f3441e2180efe2560220203dc2f8c0b0fa141e18b505e4"},
-    {file = "sqlparse-0.5.1.tar.gz", hash = "sha256:bb6b4df465655ef332548e24f08e205afc81b9ab86cb1c45657a7ff173a3a00e"},
-]
-
-[[package]]
-name = "stack-data"
-version = "0.6.3"
-summary = "Extract data from python stack frames and tracebacks for informative displays"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "asttokens>=2.1.0",
-    "executing>=1.2.0",
-    "pure-eval",
-]
-files = [
-    {file = "stack_data-0.6.3-py3-none-any.whl", hash = "sha256:d5558e0c25a4cb0853cddad3d77da9891a08cb85dd9f9f91b9f8cd66e511e695"},
-    {file = "stack_data-0.6.3.tar.gz", hash = "sha256:836a778de4fec4dcd1dcd89ed8abff8a221f58308462e1c4aa2a3cf30148f0b9"},
-]
-
-[[package]]
-name = "supervisor"
-version = "4.2.5"
-summary = "A system for controlling process state under UNIX"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "setuptools",
-]
-files = [
-    {file = "supervisor-4.2.5-py2.py3-none-any.whl", hash = "sha256:2ecaede32fc25af814696374b79e42644ecaba5c09494c51016ffda9602d0f08"},
-    {file = "supervisor-4.2.5.tar.gz", hash = "sha256:34761bae1a23c58192281a5115fb07fbf22c9b0133c08166beffc70fed3ebc12"},
-]
-
-[[package]]
-name = "text-unidecode"
-version = "1.3"
-summary = "The most basic Text::Unidecode port"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "text-unidecode-1.3.tar.gz", hash = "sha256:bad6603bb14d279193107714b288be206cac565dfa49aa5b105294dd5c4aab93"},
-    {file = "text_unidecode-1.3-py2.py3-none-any.whl", hash = "sha256:1311f10e8b895935241623731c2ba64f4c455287888b18189350b67134a822e8"},
-]
-
-[[package]]
-name = "toml"
-version = "0.10.2"
-requires_python = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*"
-summary = "Python Library for Tom's Obvious, Minimal Language"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "toml-0.10.2-py2.py3-none-any.whl", hash = "sha256:806143ae5bfb6a3c6e736a764057db0e6a0e05e338b5630894a5f779cabb4f9b"},
-    {file = "toml-0.10.2.tar.gz", hash = "sha256:b3bda1d108d5dd99f4a20d24d9c348e91c4db7ab1b749200bded2f839ccbe68f"},
-]
-
-[[package]]
-name = "traitlets"
-version = "5.14.3"
-requires_python = ">=3.8"
-summary = "Traitlets Python configuration system"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "traitlets-5.14.3-py3-none-any.whl", hash = "sha256:b74e89e397b1ed28cc831db7aea759ba6640cb3de13090ca145426688ff1ac4f"},
-    {file = "traitlets-5.14.3.tar.gz", hash = "sha256:9ed0579d3502c94b4b3732ac120375cda96f923114522847de4b3bb98b96b6b7"},
-]
-
-[[package]]
-name = "twisted"
-version = "24.7.0"
-requires_python = ">=3.8.0"
-summary = "An asynchronous networking framework written in Python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "attrs>=21.3.0",
-    "automat>=0.8.0",
-    "constantly>=15.1",
-    "hyperlink>=17.1.1",
-    "incremental>=24.7.0",
-    "typing-extensions>=4.2.0",
-    "zope-interface>=5",
-]
-files = [
-    {file = "twisted-24.7.0-py3-none-any.whl", hash = "sha256:734832ef98108136e222b5230075b1079dad8a3fc5637319615619a7725b0c81"},
-    {file = "twisted-24.7.0.tar.gz", hash = "sha256:5a60147f044187a127ec7da96d170d49bcce50c6fd36f594e60f4587eff4d394"},
-]
-
-[[package]]
-name = "twisted"
-version = "24.7.0"
-extras = ["tls"]
-requires_python = ">=3.8.0"
-summary = "An asynchronous networking framework written in Python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "idna>=2.4",
-    "pyopenssl>=21.0.0",
-    "service-identity>=18.1.0",
-    "twisted==24.7.0",
-]
-files = [
-    {file = "twisted-24.7.0-py3-none-any.whl", hash = "sha256:734832ef98108136e222b5230075b1079dad8a3fc5637319615619a7725b0c81"},
-    {file = "twisted-24.7.0.tar.gz", hash = "sha256:5a60147f044187a127ec7da96d170d49bcce50c6fd36f594e60f4587eff4d394"},
-]
-
-[[package]]
-name = "txaio"
-version = "23.1.1"
-requires_python = ">=3.7"
-summary = "Compatibility API between asyncio/Twisted/Trollius"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "txaio-23.1.1-py2.py3-none-any.whl", hash = "sha256:aaea42f8aad50e0ecfb976130ada140797e9dcb85fad2cf72b0f37f8cefcb490"},
-    {file = "txaio-23.1.1.tar.gz", hash = "sha256:f9a9216e976e5e3246dfd112ad7ad55ca915606b60b84a757ac769bd404ff704"},
-]
-
-[[package]]
-name = "typeid-python"
-version = "0.3.1"
-requires_python = "<4,>=3.8"
-summary = "Python implementation of TypeIDs: type-safe, K-sortable, and globally unique identifiers inspired by Stripe IDs"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "uuid6>=2023.5.2",
-]
-files = [
-    {file = "typeid_python-0.3.1-py3-none-any.whl", hash = "sha256:62a6747933b3323d65f0bf91c8e8c7768b0292eaf9c176fb0c934ff3a61acce5"},
-    {file = "typeid_python-0.3.1.tar.gz", hash = "sha256:f96a78c5dc6d8df1d058b72598bcc2c1c5bb8d8343f53f910e074dae01458417"},
-]
-
-[[package]]
-name = "types-pyyaml"
-version = "6.0.12.20240917"
-requires_python = ">=3.8"
-summary = "Typing stubs for PyYAML"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-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"]
-marker = "python_version == \"3.12\""
-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 = "tzlocal"
-version = "5.2"
-requires_python = ">=3.8"
-summary = "tzinfo object for the local timezone"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "backports-zoneinfo; python_version < \"3.9\"",
-    "tzdata; platform_system == \"Windows\"",
-]
-files = [
-    {file = "tzlocal-5.2-py3-none-any.whl", hash = "sha256:49816ef2fe65ea8ac19d19aa7a1ae0551c834303d5014c6d5a62e4cbda8047b8"},
-    {file = "tzlocal-5.2.tar.gz", hash = "sha256:8d399205578f1a9342816409cc1e46a93ebd5755e39ea2d85334bea911bf0e6e"},
-]
-
-[[package]]
-name = "ulid-py"
-version = "1.1.0"
-summary = "Universally Unique Lexicographically Sortable Identifier"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "ulid-py-1.1.0.tar.gz", hash = "sha256:dc6884be91558df077c3011b9fb0c87d1097cb8fc6534b11f310161afd5738f0"},
-    {file = "ulid_py-1.1.0-py2.py3-none-any.whl", hash = "sha256:b56a0f809ef90d6020b21b89a87a48edc7c03aea80e5ed5174172e82d76e3987"},
-]
-
-[[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"]
-marker = "python_version == \"3.12\""
-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 = "uuid6"
-version = "2024.7.10"
-requires_python = ">=3.8"
-summary = "New time-based UUID formats which are suited for use as a database key"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "uuid6-2024.7.10-py3-none-any.whl", hash = "sha256:93432c00ba403751f722829ad21759ff9db051dea140bf81493271e8e4dd18b7"},
-    {file = "uuid6-2024.7.10.tar.gz", hash = "sha256:2d29d7f63f593caaeea0e0d0dd0ad8129c9c663b29e19bdf882e864bedf18fb0"},
-]
-
-[[package]]
-name = "w3lib"
-version = "2.2.1"
-requires_python = ">=3.8"
-summary = "Library of web-related functions"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "w3lib-2.2.1-py3-none-any.whl", hash = "sha256:e56d81c6a6bf507d7039e0c95745ab80abd24b465eb0f248af81e3eaa46eb510"},
-    {file = "w3lib-2.2.1.tar.gz", hash = "sha256:756ff2d94c64e41c8d7c0c59fea12a5d0bc55e33a531c7988b4a163deb9b07dd"},
-]
-
-[[package]]
-name = "wcwidth"
-version = "0.2.13"
-summary = "Measures the displayed width of unicode strings in a terminal"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "backports-functools-lru-cache>=1.2.1; python_version < \"3.2\"",
-]
-files = [
-    {file = "wcwidth-0.2.13-py2.py3-none-any.whl", hash = "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859"},
-    {file = "wcwidth-0.2.13.tar.gz", hash = "sha256:72ea0c06399eb286d978fdedb6923a9eb47e1c486ce63e9b4e64fc18303972b5"},
-]
-
-[[package]]
-name = "websockets"
-version = "13.1"
-requires_python = ">=3.8"
-summary = "An implementation of the WebSocket Protocol (RFC 6455 & 7692)"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "websockets-13.1-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:9d75baf00138f80b48f1eac72ad1535aac0b6461265a0bcad391fc5aba875cfc"},
-    {file = "websockets-13.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:de58647e3f9c42f13f90ac7e5f58900c80a39019848c5547bc691693098ae1bd"},
-    {file = "websockets-13.1-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d23b88b9388ed85c6faf0e74d8dec4f4d3baf3ecf20a65a47b836d56260d4b9"},
-    {file = "websockets-13.1-py3-none-any.whl", hash = "sha256:a9a396a6ad26130cdae92ae10c36af09d9bfe6cafe69670fd3b6da9b07b4044f"},
-    {file = "websockets-13.1.tar.gz", hash = "sha256:a3b3366087c1bc0a2795111edcadddb8b3b59509d5db5d7ea3fdd69f954a8878"},
-]
-
-[[package]]
-name = "xlrd"
-version = "2.0.1"
-requires_python = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*"
-summary = "Library for developers to extract data from Microsoft Excel (tm) .xls spreadsheet files"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "xlrd-2.0.1-py2.py3-none-any.whl", hash = "sha256:6a33ee89877bd9abc1158129f6e94be74e2679636b8a205b43b85206c3f0bbdd"},
-    {file = "xlrd-2.0.1.tar.gz", hash = "sha256:f72f148f54442c6b056bf931dbc34f986fd0c3b0b6b5a58d013c9aef274d0c88"},
-]
-
-[[package]]
-name = "xmltodict"
-version = "0.13.0"
-requires_python = ">=3.4"
-summary = "Makes working with XML feel like you are working with JSON"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-files = [
-    {file = "xmltodict-0.13.0-py2.py3-none-any.whl", hash = "sha256:aa89e8fd76320154a40d19a0df04a4695fb9dc5ba977cbb68ab3e4eb225e7852"},
-    {file = "xmltodict-0.13.0.tar.gz", hash = "sha256:341595a488e3e01a85a9d8911d8912fd922ede5fecc4dce437eb4b6c8d037e56"},
-]
-
-[[package]]
-name = "yt-dlp"
-version = "2024.9.27"
-requires_python = ">=3.8"
-summary = "A feature-rich command-line audio/video downloader"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "brotli; implementation_name == \"cpython\"",
-    "brotlicffi; implementation_name != \"cpython\"",
-    "certifi",
-    "mutagen",
-    "pycryptodomex",
-    "requests<3,>=2.32.2",
-    "urllib3<3,>=1.26.17",
-    "websockets>=13.0",
-]
-files = [
-    {file = "yt_dlp-2024.9.27-py3-none-any.whl", hash = "sha256:2717468dd697fcfcf9a89f493ba30a3830cdfb276c09750e5b561b08b9ef5f69"},
-    {file = "yt_dlp-2024.9.27.tar.gz", hash = "sha256:86605542e17e2e23ad23145b637ec308133762a15a5dedac4ae50b7973237026"},
-]
-
-[[package]]
-name = "zope-interface"
-version = "7.0.3"
-requires_python = ">=3.8"
-summary = "Interfaces for Python"
-groups = ["default"]
-marker = "python_version == \"3.12\""
-dependencies = [
-    "setuptools",
-]
-files = [
-    {file = "zope.interface-7.0.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3d4b91821305c8d8f6e6207639abcbdaf186db682e521af7855d0bea3047c8ca"},
-    {file = "zope.interface-7.0.3-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e0c151a6c204f3830237c59ee4770cc346868a7a1af6925e5e38650141a7f05"},
-    {file = "zope.interface-7.0.3.tar.gz", hash = "sha256:cd2690d4b08ec9eaf47a85914fe513062b20da78d10d6d789a792c0b20307fb1"},
-]

+ 7 - 13
pyproject.toml

@@ -110,23 +110,19 @@ all = [
     "archivebox[sonic,ldap]"
 ]
 
-# pdm lock --group=':all' --dev
-# pdm install -G:all --dev
-# pdm update --dev --unconstrained
-[tool.pdm.dev-dependencies]
-build = [
+[tool.uv]
+dev-dependencies = [
+    ### BUILD
     # "pdm",                           # usually installed by apt/brew, dont double-install with pip
     "pip>=24.2",
     "setuptools>=75.1.0",
     "wheel>=0.44.0",
     "homebrew-pypi-poet>=0.10.0",      # for: generating archivebox.rb brewfile list of python packages
-]
-docs = [
+    ### DOCS
     "recommonmark>=0.7.1",
     "sphinx",
     "sphinx-rtd-theme>=2.0.0",
-]
-debug = [
+    ### DEBUGGING
     "django-debug-toolbar>=4.4.6",
     "djdt_flamegraph>=0.2.13",
     "ipdb>=0.13.13",
@@ -136,12 +132,10 @@ debug = [
     "opentelemetry-instrumentation-sqlite3>=0.47b0",
     "viztracer",                                     # usage: viztracer ../.venv/bin/archivebox manage check
     # "snakeviz",                                      # usage: python -m cProfile -o flamegraph.prof ../.venv/bin/archivebox manage check
-]
-test = [
+    ### TESTING
     "pytest>=8.3.3",
     "bottle>=0.13.1",
-]
-lint = [
+    ### LINTING
     "ruff>=0.6.6",
     "flake8>=7.1.1",
     "mypy>=1.11.2",

+ 336 - 127
requirements.txt

@@ -1,127 +1,336 @@
-# This file is @generated by PDM.
-# Please do not edit it manually.
-
-annotated-types==0.7.0; python_version == "3.12"
-anyio==4.6.0; python_version == "3.12"
-asgiref==3.8.1; python_version == "3.12"
-asttokens==2.4.1; python_version == "3.12"
-atomicwrites==1.4.1; python_version == "3.12"
-attrs==24.2.0; python_version == "3.12"
-autobahn==24.4.2; python_version == "3.12"
-automat==24.8.1; python_version == "3.12"
-base32-crockford==0.3.0; python_version == "3.12"
-beautifulsoup4==4.12.3; python_version == "3.12"
-brotli==1.1.0; implementation_name == "cpython" and python_version == "3.12"
-brotlicffi==1.1.0.0; implementation_name != "cpython" and python_version == "3.12"
-bx-django-utils==79; python_version == "3.12"
-bx-py-utils==104; python_version == "3.12"
-certifi==2024.8.30; python_version == "3.12"
-cffi==1.17.1; platform_python_implementation != "PyPy" and python_version == "3.12" or implementation_name != "cpython" and python_version == "3.12"
-channels[daphne]==4.1.0; python_version == "3.12"
-charset-normalizer==3.3.2; python_version == "3.12"
-constantly==23.10.4; python_version == "3.12"
-croniter==3.0.3; python_version == "3.12"
-cryptography==43.0.1; python_version == "3.12"
-daphne==4.1.2; python_version == "3.12"
-dateparser==1.2.0; python_version == "3.12"
-decorator==5.1.1; python_version == "3.12"
-django==5.1.1; python_version == "3.12"
-django-admin-data-views==0.4.1; python_version == "3.12"
-django-auth-ldap==4.8.0; python_version == "3.12"
-django-charid-field==0.4; python_version == "3.12"
-django-extensions==3.2.3; python_version == "3.12"
-django-huey==1.2.1; python_version == "3.12"
-django-huey-monitor==0.9.0; python_version == "3.12"
-django-jsonform==2.23.0; python_version == "3.12"
-django-ninja==1.3.0; python_version == "3.12"
-django-object-actions==4.3.0; python_version == "3.12"
-django-pydantic-field==0.3.10; python_version == "3.12"
-django-settings-holder==0.1.2; python_version == "3.12"
-django-signal-webhooks==0.3.0; python_version == "3.12"
-django-stubs==5.1.0; python_version == "3.12"
-django-stubs-ext==5.1.0; python_version == "3.12"
-django-taggit==1.3.0; python_version == "3.12"
-et-xmlfile==1.1.0; python_version == "3.12"
-executing==2.1.0; python_version == "3.12"
-feedparser==6.0.11; python_version == "3.12"
-ftfy==6.2.3; python_version == "3.12"
-h11==0.14.0; python_version == "3.12"
-httpcore==1.0.6; python_version == "3.12"
-httpx==0.27.2; python_version == "3.12"
-huey==2.5.2; python_version == "3.12"
-hyperlink==21.0.0; python_version == "3.12"
-idna==3.10; python_version == "3.12"
-incremental==24.7.2; python_version == "3.12"
-ipython==8.28.0; python_version == "3.12"
-jedi==0.19.1; python_version == "3.12"
-mailchecker==6.0.11; python_version == "3.12"
-markdown-it-py==3.0.0; python_version == "3.12"
-matplotlib-inline==0.1.7; python_version == "3.12"
-mdurl==0.1.2; python_version == "3.12"
-mutagen==1.47.0; python_version == "3.12"
-mypy-extensions==1.0.0; python_version == "3.12"
-openpyxl==3.1.5; python_version == "3.12"
-parso==0.8.4; python_version == "3.12"
-pexpect==4.9.0; (sys_platform != "win32" and sys_platform != "emscripten") and python_version == "3.12"
-phonenumbers==8.13.47; python_version == "3.12"
-pluggy==1.5.0; python_version == "3.12"
-prompt-toolkit==3.0.48; python_version == "3.12"
-psutil==6.0.0; python_version == "3.12"
-ptyprocess==0.7.0; (sys_platform != "win32" and sys_platform != "emscripten") and python_version == "3.12"
-pure-eval==0.2.3; python_version == "3.12"
-py-machineid==0.6.0; python_version == "3.12"
-pyasn1==0.6.1; python_version == "3.12"
-pyasn1-modules==0.4.1; python_version == "3.12"
-pycparser==2.22; platform_python_implementation != "PyPy" and python_version == "3.12" or implementation_name != "cpython" and python_version == "3.12"
-pycryptodomex==3.21.0; python_version == "3.12"
-pydantic==2.9.2; python_version == "3.12"
-pydantic-core==2.23.4; python_version == "3.12"
-pydantic-pkgr==0.4.4; python_version == "3.12"
-pydantic-settings==2.5.2; python_version == "3.12"
-pygments==2.18.0; python_version == "3.12"
-pyopenssl==24.2.1; python_version == "3.12"
-python-benedict[html,toml,xls,xml,yaml]==0.33.2; python_version == "3.12"
-python-benedict[io,parse]==0.33.2; python_version == "3.12"
-python-benedict[xml]==0.33.2; python_version == "3.12"
-python-crontab==3.2.0; python_version == "3.12"
-python-dateutil==2.9.0.post0; python_version == "3.12"
-python-dotenv==1.0.1; python_version == "3.12"
-python-fsutil==0.14.1; python_version == "3.12"
-python-ldap==3.4.4; python_version == "3.12"
-python-slugify==8.0.4; python_version == "3.12"
-python-stdnum==1.20; python_version == "3.12"
-pytz==2024.2; python_version == "3.12"
-pyyaml==6.0.2; python_version == "3.12"
-regex==2024.9.11; python_version == "3.12"
-requests==2.32.3; python_version == "3.12"
-rich==13.9.2; python_version == "3.12"
-rich-argparse==1.5.2; python_version == "3.12"
-service-identity==24.1.0; python_version == "3.12"
-setuptools==75.1.0; python_version == "3.12"
-sgmllib3k==1.0.0; python_version == "3.12"
-six==1.16.0; python_version == "3.12"
-sniffio==1.3.1; python_version == "3.12"
-sonic-client==1.0.0; python_version == "3.12"
-soupsieve==2.6; python_version == "3.12"
-sqlparse==0.5.1; python_version == "3.12"
-stack-data==0.6.3; python_version == "3.12"
-supervisor==4.2.5; python_version == "3.12"
-text-unidecode==1.3; python_version == "3.12"
-toml==0.10.2; python_version == "3.12"
-traitlets==5.14.3; python_version == "3.12"
-twisted[tls]==24.7.0; python_version == "3.12"
-txaio==23.1.1; python_version == "3.12"
-typeid-python==0.3.1; python_version == "3.12"
-types-pyyaml==6.0.12.20240917; python_version == "3.12"
-typing-extensions==4.12.2; python_version == "3.12"
-tzlocal==5.2; python_version == "3.12"
-ulid-py==1.1.0; python_version == "3.12"
-urllib3==2.2.3; python_version == "3.12"
-uuid6==2024.7.10; python_version == "3.12"
-w3lib==2.2.1; python_version == "3.12"
-wcwidth==0.2.13; python_version == "3.12"
-websockets==13.1; python_version == "3.12"
-xlrd==2.0.1; python_version == "3.12"
-xmltodict==0.13.0; python_version == "3.12"
-yt-dlp==2024.9.27; python_version == "3.12"
-zope-interface==7.0.3; python_version == "3.12"
+# This file was autogenerated by uv via the following command:
+#    uv pip compile pyproject.toml --all-extras -o requirements.txt
+annotated-types==0.7.0
+    # via pydantic
+anyio==4.6.0
+    # via httpx
+asgiref==3.8.1
+    # via
+    #   channels
+    #   daphne
+    #   django
+    #   django-signal-webhooks
+    #   django-stubs
+asttokens==2.4.1
+    # via stack-data
+atomicwrites==1.4.1
+    # via archivebox (pyproject.toml)
+attrs==24.2.0
+    # via
+    #   service-identity
+    #   twisted
+autobahn==24.4.2
+    # via daphne
+automat==24.8.1
+    # via twisted
+base32-crockford==0.3.0
+    # via archivebox (pyproject.toml)
+beautifulsoup4==4.12.3
+    # via python-benedict
+brotli==1.1.0
+    # via yt-dlp
+bx-django-utils==79
+    # via django-huey-monitor
+bx-py-utils==104
+    # via
+    #   bx-django-utils
+    #   django-huey-monitor
+certifi==2024.8.30
+    # via
+    #   httpcore
+    #   httpx
+    #   requests
+    #   yt-dlp
+cffi==1.17.1
+    # via cryptography
+channels==4.1.0
+    # via archivebox (pyproject.toml)
+charset-normalizer==3.3.2
+    # via requests
+constantly==23.10.4
+    # via twisted
+croniter==3.0.3
+    # via archivebox (pyproject.toml)
+cryptography==43.0.1
+    # via
+    #   autobahn
+    #   django-signal-webhooks
+    #   pyopenssl
+    #   service-identity
+daphne==4.1.2
+    # via channels
+dateparser==1.2.0
+    # via archivebox (pyproject.toml)
+decorator==5.1.1
+    # via ipython
+django==5.1.1
+    # via
+    #   archivebox (pyproject.toml)
+    #   bx-django-utils
+    #   channels
+    #   django-admin-data-views
+    #   django-auth-ldap
+    #   django-charid-field
+    #   django-extensions
+    #   django-huey
+    #   django-huey-monitor
+    #   django-jsonform
+    #   django-ninja
+    #   django-pydantic-field
+    #   django-signal-webhooks
+    #   django-stubs
+    #   django-stubs-ext
+    #   django-taggit
+django-admin-data-views==0.4.1
+    # via archivebox (pyproject.toml)
+django-auth-ldap==4.8.0
+    # via archivebox (pyproject.toml)
+django-charid-field==0.4
+    # via archivebox (pyproject.toml)
+django-extensions==3.2.3
+    # via archivebox (pyproject.toml)
+django-huey==1.2.1
+    # via archivebox (pyproject.toml)
+django-huey-monitor==0.9.0
+    # via archivebox (pyproject.toml)
+django-jsonform==2.23.0
+    # via archivebox (pyproject.toml)
+django-ninja==1.3.0
+    # via archivebox (pyproject.toml)
+django-object-actions==4.3.0
+    # via archivebox (pyproject.toml)
+django-pydantic-field==0.3.10
+    # via archivebox (pyproject.toml)
+django-settings-holder==0.1.2
+    # via
+    #   django-admin-data-views
+    #   django-signal-webhooks
+django-signal-webhooks==0.3.0
+    # via archivebox (pyproject.toml)
+django-stubs==5.1.0
+    # via archivebox (pyproject.toml)
+django-stubs-ext==5.1.0
+    # via django-stubs
+django-taggit==1.3.0
+    # via archivebox (pyproject.toml)
+et-xmlfile==1.1.0
+    # via openpyxl
+executing==2.1.0
+    # via stack-data
+feedparser==6.0.11
+    # via archivebox (pyproject.toml)
+ftfy==6.2.3
+    # via python-benedict
+h11==0.14.0
+    # via httpcore
+httpcore==1.0.6
+    # via httpx
+httpx==0.27.2
+    # via django-signal-webhooks
+huey==2.5.2
+    # via
+    #   django-huey
+    #   django-huey-monitor
+hyperlink==21.0.0
+    # via
+    #   autobahn
+    #   twisted
+idna==3.10
+    # via
+    #   anyio
+    #   httpx
+    #   hyperlink
+    #   requests
+    #   twisted
+incremental==24.7.2
+    # via twisted
+ipython==8.28.0
+    # via archivebox (pyproject.toml)
+jedi==0.19.1
+    # via ipython
+mailchecker==6.0.11
+    # via python-benedict
+markdown-it-py==3.0.0
+    # via rich
+matplotlib-inline==0.1.7
+    # via ipython
+mdurl==0.1.2
+    # via markdown-it-py
+mutagen==1.47.0
+    # via yt-dlp
+mypy-extensions==1.0.0
+    # via archivebox (pyproject.toml)
+openpyxl==3.1.5
+    # via python-benedict
+parso==0.8.4
+    # via jedi
+pexpect==4.9.0
+    # via ipython
+phonenumbers==8.13.47
+    # via python-benedict
+pluggy==1.5.0
+    # via archivebox (pyproject.toml)
+prompt-toolkit==3.0.48
+    # via ipython
+psutil==6.0.0
+    # via archivebox (pyproject.toml)
+ptyprocess==0.7.0
+    # via pexpect
+pure-eval==0.2.3
+    # via stack-data
+py-machineid==0.6.0
+    # via archivebox (pyproject.toml)
+pyasn1==0.6.1
+    # via
+    #   pyasn1-modules
+    #   python-ldap
+    #   service-identity
+pyasn1-modules==0.4.1
+    # via
+    #   python-ldap
+    #   service-identity
+pycparser==2.22
+    # via cffi
+pycryptodomex==3.21.0
+    # via yt-dlp
+pydantic==2.9.2
+    # via
+    #   django-ninja
+    #   django-pydantic-field
+    #   pydantic-pkgr
+    #   pydantic-settings
+pydantic-core==2.23.4
+    # via
+    #   pydantic
+    #   pydantic-pkgr
+pydantic-pkgr==0.4.4
+    # via archivebox (pyproject.toml)
+pydantic-settings==2.5.2
+    # via archivebox (pyproject.toml)
+pygments==2.18.0
+    # via
+    #   ipython
+    #   rich
+pyopenssl==24.2.1
+    # via twisted
+python-benedict==0.33.2
+    # via archivebox (pyproject.toml)
+python-crontab==3.2.0
+    # via archivebox (pyproject.toml)
+python-dateutil==2.9.0.post0
+    # via
+    #   croniter
+    #   dateparser
+    #   python-benedict
+    #   python-crontab
+python-dotenv==1.0.1
+    # via pydantic-settings
+python-fsutil==0.14.1
+    # via python-benedict
+python-ldap==3.4.4
+    # via
+    #   archivebox (pyproject.toml)
+    #   django-auth-ldap
+python-slugify==8.0.4
+    # via python-benedict
+python-stdnum==1.20
+    # via bx-django-utils
+pytz==2024.2
+    # via
+    #   croniter
+    #   dateparser
+pyyaml==6.0.2
+    # via python-benedict
+regex==2024.9.11
+    # via dateparser
+requests==2.32.3
+    # via
+    #   archivebox (pyproject.toml)
+    #   python-benedict
+    #   yt-dlp
+rich==13.9.2
+    # via
+    #   archivebox (pyproject.toml)
+    #   rich-argparse
+rich-argparse==1.5.2
+    # via archivebox (pyproject.toml)
+service-identity==24.1.0
+    # via twisted
+setuptools==75.1.0
+    # via
+    #   archivebox (pyproject.toml)
+    #   autobahn
+    #   incremental
+    #   supervisor
+    #   zope-interface
+sgmllib3k==1.0.0
+    # via feedparser
+six==1.16.0
+    # via
+    #   asttokens
+    #   python-dateutil
+sniffio==1.3.1
+    # via
+    #   anyio
+    #   httpx
+sonic-client==1.0.0
+    # via archivebox (pyproject.toml)
+soupsieve==2.6
+    # via beautifulsoup4
+sqlparse==0.5.1
+    # via django
+stack-data==0.6.3
+    # via ipython
+supervisor==4.2.5
+    # via archivebox (pyproject.toml)
+text-unidecode==1.3
+    # via python-slugify
+toml==0.10.2
+    # via python-benedict
+traitlets==5.14.3
+    # via
+    #   ipython
+    #   matplotlib-inline
+twisted==24.7.0
+    # via daphne
+txaio==23.1.1
+    # via autobahn
+typeid-python==0.3.1
+    # via archivebox (pyproject.toml)
+types-pyyaml==6.0.12.20240917
+    # via django-stubs
+typing-extensions==4.12.2
+    # via
+    #   django-pydantic-field
+    #   django-stubs
+    #   django-stubs-ext
+    #   pydantic
+    #   pydantic-core
+    #   pydantic-pkgr
+    #   twisted
+tzlocal==5.2
+    # via dateparser
+ulid-py==1.1.0
+    # via archivebox (pyproject.toml)
+urllib3==2.2.3
+    # via
+    #   requests
+    #   yt-dlp
+uuid6==2024.7.10
+    # via typeid-python
+w3lib==2.2.1
+    # via archivebox (pyproject.toml)
+wcwidth==0.2.13
+    # via
+    #   ftfy
+    #   prompt-toolkit
+websockets==13.1
+    # via yt-dlp
+xlrd==2.0.1
+    # via python-benedict
+xmltodict==0.13.0
+    # via python-benedict
+yt-dlp==2024.9.27
+    # via archivebox (pyproject.toml)
+zope-interface==7.0.3
+    # via twisted

Diff do ficheiro suprimidas por serem muito extensas
+ 811 - 1
uv.lock


Alguns ficheiros não foram mostrados porque muitos ficheiros mudaram neste diff