diff --git a/.github/workflows/lint-testing.yml b/.github/workflows/lint-testing.yml index e47bf27..e756e93 100644 --- a/.github/workflows/lint-testing.yml +++ b/.github/workflows/lint-testing.yml @@ -1,4 +1,3 @@ - name: Lints-Tests on: @@ -13,47 +12,21 @@ permissions: contents: read env: - RUSTFLAGS: -C debuginfo=0 # Do not produce debug symbols to keep memory usage down + RUSTFLAGS: -C debuginfo=0 # Do not produce debug symbols to keep memory usage down jobs: - rust-lints-test: - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: Set up Rust - run: rustup override set stable && rustup update - - - name: Install clippy - run: rustup component add clippy - - - name: Cache Rust - uses: Swatinem/rust-cache@v2 - - - name: Run cargo clippy - run: cargo clippy --workspace --all-targets -- -D warnings - - - run: cargo test - env: - RUST_BACKTRACE: 1 - - - test-os: + test-python: name: test ${{ matrix.os }}-${{ matrix.python-version }} strategy: fail-fast: false matrix: - os: [ubuntu, macos, windows] - poetry-version: ["1.5.1"] - python-version: ["3.8", "3.9", "3.10", "3.11", "3.12"] + os: [ubuntu, macos] + python-version: ["3.10", "3.11", "3.12"] runs-on: ${{ matrix.os }}-latest - needs: [rust-lints-test] steps: - uses: actions/checkout@v4 - - name: Install poetry - run: pipx install poetry==${{ matrix.poetry-version }} - name: install rust stable uses: dtolnay/rust-toolchain@stable @@ -63,77 +36,30 @@ jobs: with: key: ${{ matrix.os }}-${{ matrix.python-version }}-v1 - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: 'poetry' - - - name: Create virtual environment - run: | - python -m venv .venv - echo "$GITHUB_WORKSPACE/rusty-logger/.venv/bin" >> $GITHUB_PATH - - - name: Install dependencies - run : make setup.project - - - name: Lints - run : make lints.ci - - - name: Run tests and report coverage - run: make test.unit - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - test-ubuntu-pypy: - name: test ubuntu-${{ matrix.python-version }} - - strategy: - fail-fast: false - matrix: - poetry-version: ["1.5.1"] - python-version: ["pypy3.8", "pypy3.9", "pypy3.10"] - - runs-on: ubuntu-latest - needs: [rust-lints-test] - steps: - - uses: actions/checkout@v4 - - name: Install poetry - run: pipx install poetry==${{ matrix.poetry-version }} - - - name: install rust stable - uses: dtolnay/rust-toolchain@stable - - - name: cache rust - uses: Swatinem/rust-cache@v2 + - name: Install uv + uses: astral-sh/setup-uv@v4 with: - key: ubuntu-${{ matrix.python-version }}-v1 + enable-cache: true - name: set up python uses: actions/setup-python@v5 with: python-version: ${{ matrix.python-version }} - cache: 'poetry' - name: Create virtual environment - run: | - python -m venv .venv - echo "$GITHUB_WORKSPACE/rusty-logger/.venv/bin" >> $GITHUB_PATH - - - name: Install dependencies - run : make setup.project + working-directory: ./py-logger + run: make setup.project - name: Lints - run : make lints.ci - + working-directory: ./py-logger + run: make lints.ci + - name: Run tests and report coverage + working-directory: ./py-logger run: make test.unit test-build: - needs: [test-os] + needs: [test-python] name: build - ubuntu - ${{ matrix.manylinux }} - ${{ matrix.target }} strategy: fail-fast: false @@ -160,8 +86,8 @@ jobs: args: --release --out dist --interpreter 3.11 rust-toolchain: stable docker-options: -e CI + working-directory: ./py-logger - - run: ls -lh dist/ + - run: ls -lh ./py-logger/dist/ - - run: twine check --strict dist/* - + - run: twine check --strict ./py-logger/dist/* diff --git a/.github/workflows/release.yml b/.github/workflows/release.yml index eaff065..3e072e1 100644 --- a/.github/workflows/release.yml +++ b/.github/workflows/release.yml @@ -1,7 +1,6 @@ name: Release on: - release: types: [published] @@ -10,399 +9,319 @@ permissions: env: PACKAGE_NAME: rusty_logger - INTERPRETER: '3.8 3.9 3.10 3.11 3.12 pypy3.8 pypy3.9 pypy3.10' + INTERPRETER: "3.10 3.11 3.12 3.13 pypy3.10" RUSTFLAGS: -C debuginfo=0 jobs: - rust-lints-test: + rust-release: + environment: crates.io + name: Release-Rust runs-on: ubuntu-latest steps: - uses: actions/checkout@v4 - - - name: Set up Rust - run: rustup override set stable && rustup update - - - name: Install clippy - run: rustup component add clippy - - - name: Cache Rust - uses: Swatinem/rust-cache@v2 - - - name: Run cargo clippy - run: cargo clippy --workspace --all-targets -- -D warnings - - - run: cargo test - env: - RUST_BACKTRACE: 1 - - test-os: - name: test ${{ matrix.os }}-${{ matrix.python-version }} - - strategy: - fail-fast: false - matrix: - os: [ubuntu, macos, windows] - poetry-version: ["1.5.1"] - python-version: ["3.8", "3.9", "3.10","3.11", "3.12"] - - runs-on: ${{ matrix.os }}-latest - needs: [rust-lints-test] - steps: - - uses: actions/checkout@v4 - - name: Install poetry - run: pipx install poetry==${{ matrix.poetry-version }} - - - name: install rust stable - uses: dtolnay/rust-toolchain@stable - + with: + fetch-depth: 0 + - uses: dtolnay/rust-toolchain@stable - name: cache rust + id: cargo_release_cache uses: Swatinem/rust-cache@v2 with: - key: ${{ matrix.os }}-${{ matrix.python-version }}-v1 - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: ${{ matrix.python-version }} - cache: 'poetry' - - - name: Create virtual environment - run: | - python -m venv .venv - echo "$GITHUB_WORKSPACE/rusty-logger/.venv/bin" >> $GITHUB_PATH - - - name: Install dependencies - run : make setup.project - - - name: Lints - run : make lints.ci - - - name: Run tests and report coverage - run: make test.unit - - - name: Upload coverage reports to Codecov - uses: codecov/codecov-action@v4 - env: - CODECOV_TOKEN: ${{ secrets.CODECOV_TOKEN }} - - build-sdist: - needs: [test-os] - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - name: Build sdist - uses: PyO3/maturin-action@v1 - with: - command: sdist - args: --out dist - rust-toolchain: stable - - - name: Upload sdist - uses: actions/upload-artifact@v3 - with: - name: wheels - path: dist - - build-ubuntu: - needs: [test-os] - name: build - ubuntu - ${{ matrix.manylinux }} - ${{ matrix.target }} - strategy: - fail-fast: false - matrix: - target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] - manylinux: [auto] - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: "3.11" - - - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions - - - name: build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - manylinux: ${{ matrix.manylinux }} - args: --release --out dist --interpreter ${{ env.INTERPRETER }} - rust-toolchain: stable - docker-options: -e CI - - - run: ls -lh dist/ - - - run: twine check --strict dist/* - - - uses: actions/upload-artifact@v3 + key: ${{ runner.os }}-cargo-release + - name: Switch to main branch + run: git checkout main + - name: Run release-plz + uses: MarcoIeni/release-plz-action@v0.5 with: - name: pypi_files - path: dist - - build-ubuntu-musllinux: - needs: [test-os] - name: build - ubuntu - ${{ matrix.manylinux }} - ${{ matrix.target }} - strategy: - fail-fast: false - matrix: - target: [x86_64, aarch64] - manylinux: ["musllinux_1_1"] - - - runs-on: ubuntu-latest - steps: - - uses: actions/checkout@v4 - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions - - - name: build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - manylinux: ${{ matrix.manylinux }} - args: --release --out dist --interpreter ${{ env.INTERPRETER }} - rust-toolchain: stable - docker-options: -e CI - - - run: ls -lh dist/ - - - run: twine check --strict dist/* - - - uses: actions/upload-artifact@v3 - with: - name: pypi_files - path: dist - - - build-macos: - needs: [test-os] - name: build - macos - (${{ matrix.target }} - auto - strategy: - fail-fast: false - matrix: - target: [x86_64, aarch64] - - runs-on: macos-latest - steps: - - uses: actions/checkout@v4 - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions - - - name: build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ env.INTERPRETER }} - rust-toolchain: stable - docker-options: -e CI - - - run: ls -lh dist/ - - - run: twine check --strict dist/* - - - uses: actions/upload-artifact@v3 - with: - name: pypi_files - path: dist - - build-windows: - needs: [test-os] - name: build - windows - (${{ matrix.target }} - auto - strategy: - fail-fast: false - matrix: - target: [x64, x86] - include: - - target: i686 - python-architecture: x86 - interpreter: 3.8 3.9 3.10 3.11 3.12 - - target: x64 - python-architecture: x64 - interpreter: 3.8 3.9 3.10 3.11 3.12 - - target: x86 - python-architecture: x86 - interpreter: 3.8 3.9 3.10 3.11 3.12 - exclude: - - target: x86 - - target: x64 - - - runs-on: windows-latest - steps: - - uses: actions/checkout@v4 - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - architecture: ${{ matrix.python-architecture }} - - - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions - - - name: build wheels - uses: PyO3/maturin-action@v1 - with: - target: ${{ matrix.target }} - args: --release --out dist --interpreter ${{ matrix.interpreter || env.INTERPRETER }} - rust-toolchain: stable - - - run: dir dist/ - - - run: twine check --strict dist/* - - - uses: actions/upload-artifact@v3 - with: - name: pypi_files - path: dist - - inspect-pypi-assets: - needs: [build-ubuntu, build-ubuntu-musllinux, build-macos, build-windows, build-sdist] - runs-on: ubuntu-latest - - steps: - - uses: actions/checkout@v4 - - - name: get dist artifacts - uses: actions/download-artifact@v3 - with: - name: pypi_files - path: dist - - - name: list dist files - run: | - ls -lh dist/ - ls -l dist/ - echo "`ls dist | wc -l` files" - - - test-builds-arch: - name: test build on ${{ matrix.target }}-${{ matrix.distro }} - needs: [build-ubuntu, build-ubuntu-musllinux, build-macos, build-windows, build-sdist] - runs-on: ubuntu-latest - - strategy: - fail-fast: false - matrix: - target: [aarch64, armv7, s390x, ppc64le] - distro: ['ubuntu22.04'] - include: - - target: aarch64 - distro: alpine_latest - - steps: - - uses: actions/checkout@v4 - - - name: get dist artifacts - uses: actions/download-artifact@v3 - with: - name: pypi_files - path: dist - - - uses: uraimo/run-on-arch-action@v2.5.1 - name: install & test - with: - arch: ${{ matrix.target }} - distro: ${{ matrix.distro }} - githubToken: ${{ github.token }} - install: | - set -x - if command -v apt-get &> /dev/null; then - echo "installing python & pip with apt-get..." - apt-get update - apt-get install -y --no-install-recommends python3 python3-pip python3-venv - else - echo "installing python & pip with apk..." - apk update - apk add python3 py3-pip - fi - run: | - set -x - python3 -m venv venv - source venv/bin/activate - python3 -m pip install -r tests/requirements.txt - python3 -m pip install rusty_logger --no-index --no-deps --find-links dist --force-reinstall - python3 -m pytest - python3 -c 'import rusty_logger; print(rusty_logger.__version__)' - - test-builds-os: - name: test build on ${{ matrix.os }} - needs: [build-ubuntu, build-ubuntu-musllinux, build-macos, build-windows, build-sdist] - - strategy: - fail-fast: false - matrix: - os: [ubuntu, macos, windows] - - runs-on: ${{ matrix.os }}-latest - steps: - - uses: actions/checkout@v4 - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: '3.11' - - - name: Create virtual environment - run: | - python -m venv .venv - echo "$GITHUB_WORKSPACE/rusty-logger/.venv/bin" >> $GITHUB_PATH - - - name: get dist artifacts - uses: actions/download-artifact@v3 - with: - name: pypi_files - path: dist - - - run: pip install -r tests/requirements.txt - - run: pip install rusty_logger --no-index --no-deps --find-links dist --force-reinstall - - run: pytest - - - release: - name: Release - runs-on: ubuntu-latest - needs: [test-builds-os, test-builds-arch] - - steps: - - uses: actions/checkout@v4 - - - name: install rust stable - uses: dtolnay/rust-toolchain@stable - - run: | - export VERSION=$(cargo pkgid | cut -d "#" -f2) - echo "version: $VERSION" - echo "tag: $GITHUB_REF_NAME" - test "v$VERSION" "=" "$GITHUB_REF_NAME" - - - name: set up python - uses: actions/setup-python@v5 - with: - python-version: '3.10' - - - run: pip install -U twine - - - name: get dist artifacts - uses: actions/download-artifact@v3 - with: - name: pypi_files - path: dist - - - run: twine check --strict dist/* - - - name: upload to pypi - run: twine upload dist/* + command: release env: - TWINE_USERNAME: __token__ - TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} \ No newline at end of file + GITHUB_TOKEN: ${{ secrets.RELEASE_PLZ_TOKEN }} + CARGO_REGISTRY_TOKEN: ${{ secrets.CRATES_REGISTRY_TOKEN }} + #est-python: + # name: test ${{ matrix.os }}-${{ matrix.python-version }} + + # strategy: + # fail-fast: false + # matrix: + # os: [ubuntu, macos] + # python-version: ["3.10", "3.11", "3.12"] + + # runs-on: ${{ matrix.os }}-latest + # steps: + # - uses: actions/checkout@v4 + + # - name: install rust stable + # uses: dtolnay/rust-toolchain@stable + + # - name: cache rust + # uses: Swatinem/rust-cache@v2 + # with: + # key: ${{ matrix.os }}-${{ matrix.python-version }}-v1 + + # - name: Install uv + # uses: astral-sh/setup-uv@v4 + # with: + # enable-cache: true + + # - name: set up python + # uses: actions/setup-python@v5 + # with: + # python-version: ${{ matrix.python-version }} + + # - name: Create virtual environment + # working-directory: ./py-logger + # run: make setup.project + + # - name: Lints + # working-directory: ./py-logger + # run: make lints.ci + + # - name: Run tests and report coverage + # working-directory: ./py-logger + # run: make test.unit + + #uild-sdist: + # needs: [test-python] + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + # - name: Build sdist + # uses: PyO3/maturin-action@v1 + # with: + # command: sdist + # args: --out dist + # rust-toolchain: stable + # working-directory: ./py-logger + + # - name: Upload sdist + # uses: actions/upload-artifact@v4 + # with: + # name: wheels + # path: ./py-logger/dist + + #uild-ubuntu: + # needs: [test-python] + # name: build - ubuntu - ${{ matrix.manylinux }} - ${{ matrix.target }} + # strategy: + # fail-fast: false + # matrix: + # target: [x86_64, x86, aarch64, armv7, s390x, ppc64le] + # manylinux: [auto] + + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + + # - name: set up python + # uses: actions/setup-python@v5 + # with: + # python-version: "3.12" + + # - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions + + # - name: build wheels + # uses: PyO3/maturin-action@v1 + # with: + # target: ${{ matrix.target }} + # manylinux: ${{ matrix.manylinux }} + # args: --release --out dist --interpreter ${{ env.INTERPRETER }} + # rust-toolchain: stable + # docker-options: -e CI + # working-directory: ./py-logger + + # - run: ls -lh dist/ + + # - run: twine check --strict dist/* + + # - uses: actions/upload-artifact@v3 + # with: + # name: pypi_files + # path: ./py-logger/dist + + #uild-ubuntu-musllinux: + # needs: [test-python] + # name: build - ubuntu - ${{ matrix.manylinux }} - ${{ matrix.target }} + # strategy: + # fail-fast: false + # matrix: + # target: [x86_64, aarch64] + # manylinux: ["musllinux_1_1"] + + # runs-on: ubuntu-latest + # steps: + # - uses: actions/checkout@v4 + + # - name: set up python + # uses: actions/setup-python@v5 + # with: + # python-version: "3.12" + + # - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions + + # - name: build wheels + # uses: PyO3/maturin-action@v1 + # with: + # target: ${{ matrix.target }} + # manylinux: ${{ matrix.manylinux }} + # args: --release --out dist --interpreter ${{ env.INTERPRETER }} + # rust-toolchain: stable + # docker-options: -e CI + # working-directory: ./py-logger + + # - run: ls -lh dist/ + + # - run: twine check --strict dist/* + + # - uses: actions/upload-artifact@v3 + # with: + # name: pypi_files + # path: ./py-logger/dist + + #uild-macos: + # needs: [test-python] + # name: build - macos - (${{ matrix.target }} - auto + # strategy: + # fail-fast: false + # matrix: + # target: [x86_64, aarch64] + + # runs-on: macos-latest + # steps: + # - uses: actions/checkout@v4 + + # - name: set up python + # uses: actions/setup-python@v5 + # with: + # python-version: "3.12" + + # - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions + + # - name: build wheels + # uses: PyO3/maturin-action@v1 + # with: + # target: ${{ matrix.target }} + # args: --release --out dist --interpreter ${{ env.INTERPRETER }} + # rust-toolchain: stable + # docker-options: -e CI + # working-directory: ./py-logger + + # - run: ls -lh ./py-logger/dist/ + + # - run: twine check --strict ./py-logger/dist/* + + # - uses: actions/upload-artifact@v3 + # with: + # name: pypi_files + # path: ./py-logger/dist + + #uild-windows: + # needs: [test-python] + # name: build - windows - (${{ matrix.target }} - auto + # strategy: + # fail-fast: false + # matrix: + # target: [x64, x86] + # include: + # - target: i686 + # python-architecture: x86 + # interpreter: 3.10 3.11 3.12 3.13 + # - target: x64 + # python-architecture: x64 + # interpreter: 3.10 3.11 3.12 3.13 + # - target: x86 + # python-architecture: x86 + # interpreter: 3.10 3.11 3.12 3.13 + # exclude: + # - target: x86 + # - target: x64 + + # runs-on: windows-latest + # steps: + # - uses: actions/checkout@v4 + + # - name: set up python + # uses: actions/setup-python@v5 + # with: + # python-version: "3.12" + # architecture: ${{ matrix.python-architecture }} + + # - run: pip install -U twine 'black>=22.3.0,<23' typing_extensions + + # - name: build wheels + # uses: PyO3/maturin-action@v1 + # with: + # target: ${{ matrix.target }} + # args: --release --out dist --interpreter ${{ matrix.interpreter || env.INTERPRETER }} + # rust-toolchain: stable + # working-directory: ./py-logger + + # - run: dir dist/ + + # - run: twine check --strict ./py-logger/dist/* + + # - uses: actions/upload-artifact@v3 + # with: + # name: pypi_files + # path: ./py-logger/dist + + #nspect-pypi-assets: + # needs: + # [ + # build-ubuntu, + # build-ubuntu-musllinux, + # build-macos, + # build-windows, + # build-sdist, + # ] + # runs-on: ubuntu-latest + + # steps: + # - uses: actions/checkout@v4 + + # - name: get dist artifacts + # uses: actions/download-artifact@v3 + # with: + # name: pypi_files + # path: dist + + # - name: list dist files + # run: | + # ls -lh dist/ + # ls -l dist/ + # echo "`ls dist | wc -l` files" + + #elease: + # name: Release + # runs-on: ubuntu-latest + # needs: [inspect-pypi-assets] + + # steps: + # - uses: actions/checkout@v4 + + # - name: install rust stable + # uses: dtolnay/rust-toolchain@stable + # - run: | + # export VERSION=$(cargo pkgid | cut -d "#" -f2) + # echo "version: $VERSION" + # echo "tag: $GITHUB_REF_NAME" + # test "v$VERSION" "=" "$GITHUB_REF_NAME" + + # - name: set up python + # uses: actions/setup-python@v5 + # with: + # python-version: "3.10" + + # - run: pip install -U twine + + # - name: get dist artifacts + # uses: actions/download-artifact@v3 + # with: + # name: pypi_files + # path: dist + + # - run: twine check --strict dist/* + + # - name: upload to pypi + # run: twine upload dist/* + # env: + # TWINE_USERNAME: __token__ + # TWINE_PASSWORD: ${{ secrets.PYPI_API_TOKEN }} diff --git a/Cargo.lock b/Cargo.lock index 7e736e3..6311e7f 100644 --- a/Cargo.lock +++ b/Cargo.lock @@ -1,6 +1,6 @@ # This file is automatically @generated by Cargo. # It is not intended for manual editing. -version = 3 +version = 4 [[package]] name = "aho-corasick" @@ -12,16 +12,16 @@ dependencies = [ ] [[package]] -name = "autocfg" -version = "1.3.0" +name = "anyhow" +version = "1.0.95" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0c4b4d0bd25bd0b74681c0ad21497610ce1b7c91b1022cd21c80c6fbdd9476b0" +checksum = "34ac096ce696dc2fcabef30516bb13c0a68a11d30131d3df6f04711467681b04" [[package]] -name = "bitflags" -version = "2.6.0" +name = "autocfg" +version = "1.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b048fb63fd8b5923fc5aa7b340d8e156aec7ec02f0c78fa8a6ddc2613f6f71de" +checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26" [[package]] name = "cfg-if" @@ -29,20 +29,29 @@ version = "1.0.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd" +[[package]] +name = "chrono" +version = "0.4.39" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "7e36cc9d416881d2e24f9a963be5fb1cd90966419ac844274161d10488b3e825" +dependencies = [ + "num-traits", +] + [[package]] name = "crossbeam-channel" -version = "0.5.13" +version = "0.5.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "33480d6946193aa8033910124896ca395333cae7e2d1113d1fef6c3272217df2" +checksum = "06ba6d68e24814cb8de6bb986db8222d3a027d15872cabc0d18817bc3c0e4471" dependencies = [ "crossbeam-utils", ] [[package]] name = "crossbeam-utils" -version = "0.8.20" +version = "0.8.21" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "22ec99545bb0ed0ea7bb9b8e1e9122ea386ff8a48c0922e43f36d45ab09e0e80" +checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28" [[package]] name = "deranged" @@ -64,7 +73,7 @@ dependencies = [ "regex", "serde", "serde_json", - "thiserror", + "thiserror 1.0.69", ] [[package]] @@ -76,17 +85,23 @@ dependencies = [ "serde", ] +[[package]] +name = "heck" +version = "0.5.0" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "2304e00983f87ffb38b55b444b5e3b60a884b5d30c0fca7d82fe33449bbe55ea" + [[package]] name = "indoc" -version = "1.0.9" +version = "2.0.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bfa799dd5ed20a7e349f3b4639aa80d74549c81716d9ec4f994c9b5815598306" +checksum = "b248f5224d1d606005e02c97f5aa4e88eeb230488bcc03bc9ca4d7991399f2b5" [[package]] name = "itoa" -version = "1.0.11" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "49f1f14873335454500d59611f1cf4a4b0f786f9ac11f4312a78e4cf2566695b" +checksum = "d75a2a4b1b190afb6f5425f10f6a8f959d2ea0b9c2b1d79553551850539e4674" [[package]] name = "lazy_static" @@ -96,25 +111,15 @@ checksum = "bbd2bcb4c963f2ddae06a2efc7e9f3591312473c50c6685e1f298068316e66fe" [[package]] name = "libc" -version = "0.2.155" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "97b3888a4aecf77e811145cadf6eef5901f4782c53886191b2f693f24761847c" - -[[package]] -name = "lock_api" -version = "0.4.12" +version = "0.2.169" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "07af8b9cdd281b7915f413fa73f29ebd5d55d0d3f0155584dade1ff18cea1b17" -dependencies = [ - "autocfg", - "scopeguard", -] +checksum = "b5aba8db14291edd000dfcc4d620c7ebfb122c613afb886ca8803fa4e128a20a" [[package]] name = "log" -version = "0.4.22" +version = "0.4.25" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a7a70ba024b9dc04c27ea2f0c0548feb474ec5c54bba33a7f72f873a39d07b24" +checksum = "04cbf5b083de1c7e0222a7a51dbfdba1cbe1c6ab0b15e29fff3f6c077fd9cd9f" [[package]] name = "memchr" @@ -147,11 +152,20 @@ version = "0.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "51d515d32fb182ee37cda2ccdcb92950d6a3c2893aa280e540671c2cd0f3b1d9" +[[package]] +name = "num-traits" +version = "0.2.19" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "071dfc062690e90b734c0b2273ce72ad0ffa95f0c74596bc250dcfd960262841" +dependencies = [ + "autocfg", +] + [[package]] name = "once_cell" -version = "1.19.0" +version = "1.20.2" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3fdb12b2476b595f9358c5161aa467c2438859caa136dec86c26fdd2efe17b92" +checksum = "1261fe7e33c73b354eab43b1273a57c8f967d0391e80353e51f764ac02cf6775" [[package]] name = "overload" @@ -161,38 +175,21 @@ checksum = "b15813163c1d831bf4a13c3610c05c0d03b39feb07f7e09fa234dac9b15aaf39" [[package]] name = "owo-colors" -version = "4.0.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "caff54706df99d2a78a5a4e3455ff45448d81ef1bb63c22cd14052ca0e993a3f" - -[[package]] -name = "parking_lot" -version = "0.12.3" +version = "4.1.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "f1bf18183cf54e8d6059647fc3063646a1801cf30896933ec2311622cc4b9a27" -dependencies = [ - "lock_api", - "parking_lot_core", -] +checksum = "fb37767f6569cd834a413442455e0f066d0d522de8630436e2a1761d9726ba56" [[package]] -name = "parking_lot_core" -version = "0.9.10" +name = "pin-project-lite" +version = "0.2.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "1e401f977ab385c9e4e3ab30627d6f26d00e2c73eef317493c4ec6d468726cf8" -dependencies = [ - "cfg-if", - "libc", - "redox_syscall", - "smallvec", - "windows-targets", -] +checksum = "3b3cff922bd51709b605d9ead9aa71031d81447142d828eb4a6eba76fe619f9b" [[package]] -name = "pin-project-lite" -version = "0.2.14" +name = "portable-atomic" +version = "1.10.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bda66fc9667c18cb2758a2ac84d1167245054bcf85d5d1aaa6923f45801bdd02" +checksum = "280dc24453071f1b63954171985a0b0d30058d287960968b9b2aca264c8d4ee6" [[package]] name = "powerfmt" @@ -202,35 +199,47 @@ checksum = "439ee305def115ba05938db6eb1644ff94165c5ab5e9420d1c1bcedbba909391" [[package]] name = "proc-macro2" -version = "1.0.86" +version = "1.0.93" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5e719e8df665df0d1c8fbfd238015744736151d4445ec0836b8e628aae103b77" +checksum = "60946a68e5f9d28b0dc1c21bb8a97ee7d018a8b322fa57838ba31cc878e22d99" dependencies = [ "unicode-ident", ] +[[package]] +name = "py-rusty-logger" +version = "0.1.0" +dependencies = [ + "pyo3", + "rusty-logger", +] + [[package]] name = "pyo3" -version = "0.19.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e681a6cfdc4adcc93b4d3cf993749a4552018ee0a9b65fc0ccfad74352c72a38" +checksum = "57fe09249128b3173d092de9523eaa75136bf7ba85e0d69eca241c7939c933cc" dependencies = [ + "anyhow", "cfg-if", + "chrono", "indoc", "libc", "memoffset", - "parking_lot", + "once_cell", + "portable-atomic", "pyo3-build-config", "pyo3-ffi", "pyo3-macros", + "serde", "unindent", ] [[package]] name = "pyo3-build-config" -version = "0.19.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "076c73d0bc438f7a4ef6fdd0c3bb4732149136abd952b110ac93e4edb13a6ba5" +checksum = "1cd3927b5a78757a0d71aa9dff669f903b1eb64b54142a9bd9f757f8fde65fd7" dependencies = [ "once_cell", "target-lexicon", @@ -238,9 +247,9 @@ dependencies = [ [[package]] name = "pyo3-ffi" -version = "0.19.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e53cee42e77ebe256066ba8aa77eff722b3bb91f3419177cf4cd0f304d3284d9" +checksum = "dab6bb2102bd8f991e7749f130a70d05dd557613e39ed2deeee8e9ca0c4d548d" dependencies = [ "libc", "pyo3-build-config", @@ -248,50 +257,43 @@ dependencies = [ [[package]] name = "pyo3-macros" -version = "0.19.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dfeb4c99597e136528c6dd7d5e3de5434d1ceaf487436a3f03b2d56b6fc9efd1" +checksum = "91871864b353fd5ffcb3f91f2f703a22a9797c91b9ab497b1acac7b07ae509c7" dependencies = [ "proc-macro2", "pyo3-macros-backend", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "pyo3-macros-backend" -version = "0.19.2" +version = "0.23.4" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "947dc12175c254889edc0c02e399476c2f652b4b9ebd123aa655c224de259536" +checksum = "43abc3b80bc20f3facd86cd3c60beed58c3e2aa26213f3cda368de39c60a27e4" dependencies = [ + "heck", "proc-macro2", + "pyo3-build-config", "quote", - "syn 1.0.109", + "syn", ] [[package]] name = "quote" -version = "1.0.36" +version = "1.0.38" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0fa76aaf39101c457836aec0ce2316dbdc3ab723cdda1c6bd4e6ad4208acaca7" +checksum = "0e4dccaaaf89514f546c693ddc140f729f958c247918a13380cccc6078391acc" dependencies = [ "proc-macro2", ] -[[package]] -name = "redox_syscall" -version = "0.5.3" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "2a908a6e00f1fdd0dfd9c0eb08ce85126f6d8bbda50017e74bc4a4b7d4a926a4" -dependencies = [ - "bitflags", -] - [[package]] name = "regex" -version = "1.10.5" +version = "1.11.1" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "b91213439dad192326a0d7c6ee3955910425f441d7038e0d6933b0aec5c4517f" +checksum = "b544ef1b4eac5dc2db33ea63606ae9ffcfac26c1416a2806ae0bf5f56b201191" dependencies = [ "aho-corasick", "memchr", @@ -301,9 +303,9 @@ dependencies = [ [[package]] name = "regex-automata" -version = "0.4.7" +version = "0.4.9" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "38caf58cc5ef2fed281f89292ef23f6365465ed9a41b7a7754eb4e26496c92df" +checksum = "809e8dc61f6de73b46c85f4c96486310fe304c434cfa43669d7b40f711150908" dependencies = [ "aho-corasick", "memchr", @@ -312,19 +314,20 @@ dependencies = [ [[package]] name = "regex-syntax" -version = "0.8.4" +version = "0.8.5" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "7a66a03ae7c801facd77a29370b4faec201768915ac14a721ba36f20bc9c209b" +checksum = "2b15c43186be67a4fd63bee50d0303afffcef381492ebe2c5d87f324e1b8815c" [[package]] name = "rusty-logger" -version = "0.3.2" +version = "0.1.0" dependencies = [ "dynfmt", "owo-colors", "pyo3", "serde", "serde_json", + "thiserror 2.0.11", "time", "tracing", "tracing-appender", @@ -338,37 +341,31 @@ version = "1.0.18" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "f3cb5ba0dc43242ce17de99c180e96db90b235b8a9fdc9543c96d2209116bd9f" -[[package]] -name = "scopeguard" -version = "1.2.0" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "94143f37725109f92c262ed2cf5e59bce7498c01bcc1502d7b9afe439a4e9f49" - [[package]] name = "serde" -version = "1.0.204" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc76f558e0cbb2a839d37354c575f1dc3fdc6546b5be373ba43d95f231bf7c12" +checksum = "02fc4265df13d6fa1d00ecff087228cc0a2b5f3c0e87e258d8b94a156e984c70" dependencies = [ "serde_derive", ] [[package]] name = "serde_derive" -version = "1.0.204" +version = "1.0.217" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e0cd7e117be63d3c3678776753929474f3b04a43a080c744d6b0ae2a8c28e222" +checksum = "5a9bf7cf98d04a2b28aead066b7496853d4779c9cc183c440dbac457641e19a0" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] name = "serde_json" -version = "1.0.122" +version = "1.0.135" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "784b6203951c57ff748476b126ccb5e8e2959a5c19e5c617ab1956be3dbc68da" +checksum = "2b0d7ba2887406110130a978386c4e1befb98c674b4fba677954e4db976630d9" dependencies = [ "itoa", "memchr", @@ -393,9 +390,9 @@ checksum = "3c5e1a9a646d36c3599cd173a41282daf47c44583ad367b8e6837255952e5c67" [[package]] name = "syn" -version = "1.0.109" +version = "2.0.96" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "72b64191b275b66ffe2469e8af2c1cfe3bafa67b529ead792a6d0160888b4237" +checksum = "d5d0adab1ae378d7f53bdebc67a39f1f151407ef230f0ce2883572f5d8985c80" dependencies = [ "proc-macro2", "quote", @@ -403,40 +400,49 @@ dependencies = [ ] [[package]] -name = "syn" -version = "2.0.72" +name = "target-lexicon" +version = "0.12.16" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "dc4b9b9bf2add8093d3f2c0204471e951b2285580335de42f9d2534f3ae7a8af" +checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" + +[[package]] +name = "thiserror" +version = "1.0.69" +source = "registry+https://github.com/rust-lang/crates.io-index" +checksum = "b6aaf5339b578ea85b50e080feb250a3e8ae8cfcdff9a461c9ec2904bc923f52" dependencies = [ - "proc-macro2", - "quote", - "unicode-ident", + "thiserror-impl 1.0.69", ] [[package]] -name = "target-lexicon" -version = "0.12.16" +name = "thiserror" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "61c41af27dd6d1e27b1b16b489db798443478cef1f06a660c96db617ba5de3b1" +checksum = "d452f284b73e6d76dd36758a0c8684b1d5be31f92b89d07fd5822175732206fc" +dependencies = [ + "thiserror-impl 2.0.11", +] [[package]] -name = "thiserror" -version = "1.0.63" +name = "thiserror-impl" +version = "1.0.69" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c0342370b38b6a11b6cc11d6a805569958d54cfa061a29969c3b5ce2ea405724" +checksum = "4fee6c4efc90059e10f81e6d42c60a18f76588c3d74cb83a0b242a2b6c7504c1" dependencies = [ - "thiserror-impl", + "proc-macro2", + "quote", + "syn", ] [[package]] name = "thiserror-impl" -version = "1.0.63" +version = "2.0.11" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "a4558b58466b9ad7ca0f102865eccc95938dca1a74a856f2b57b6629050da261" +checksum = "26afc1baea8a989337eeb52b6e72a039780ce45c3edfcc9c5b9d112feeb173c2" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] @@ -451,9 +457,9 @@ dependencies = [ [[package]] name = "time" -version = "0.3.36" +version = "0.3.37" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "5dfd88e563464686c916c7e46e623e520ddc6d79fa6641390f2e3fa86e83e885" +checksum = "35e7868883861bd0e56d9ac6efcaaca0d6d5d82a2a7ec8209ff492c07cf37b21" dependencies = [ "deranged", "itoa", @@ -472,9 +478,9 @@ checksum = "ef927ca75afb808a4d64dd374f00a2adf8d0fcff8e7b184af886c3c87ec4a3f3" [[package]] name = "time-macros" -version = "0.2.18" +version = "0.2.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3f252a68540fde3a3877aeea552b832b40ab9a69e318efd078774a01ddee1ccf" +checksum = "2834e6017e3e5e4b9834939793b282bc03b37a3336245fa820e35e233e2a85de" dependencies = [ "num-conv", "time-core", @@ -482,9 +488,9 @@ dependencies = [ [[package]] name = "tracing" -version = "0.1.40" +version = "0.1.41" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c3523ab5a71916ccf420eebdf5521fcef02141234bbc0b8a49f2fdc4544364ef" +checksum = "784e0ac535deb450455cbfa28a6f0df145ea1bb7ae51b821cf5e7927fdcfbdd0" dependencies = [ "pin-project-lite", "tracing-attributes", @@ -498,27 +504,27 @@ source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "3566e8ce28cc0a3fe42519fc80e6b4c943cc4c8cef275620eb8dac2d3d4e06cf" dependencies = [ "crossbeam-channel", - "thiserror", + "thiserror 1.0.69", "time", "tracing-subscriber", ] [[package]] name = "tracing-attributes" -version = "0.1.27" +version = "0.1.28" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "34704c8d6ebcbc939824180af020566b01a7c01f80641264eba0999f6c2b6be7" +checksum = "395ae124c09f9e6918a2310af6038fba074bcf474ac352496d5910dd59a2226d" dependencies = [ "proc-macro2", "quote", - "syn 2.0.72", + "syn", ] [[package]] name = "tracing-core" -version = "0.1.32" +version = "0.1.33" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "c06d3da6113f116aaee68e4d601191614c9053067f9ab7f6edbcb161237daa54" +checksum = "e672c95779cf947c5311f83787af4fa8fffd12fb27e4993211a84bdfd9610f9c" dependencies = [ "once_cell", "valuable", @@ -537,9 +543,9 @@ dependencies = [ [[package]] name = "tracing-serde" -version = "0.1.3" +version = "0.2.0" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "bc6b213177105856957181934e4920de57730fc69bf42c37ee5bb664d406d9e1" +checksum = "704b1aeb7be0d0a84fc9828cae51dab5970fee5088f83d1dd7ee6f6246fc6ff1" dependencies = [ "serde", "tracing-core", @@ -547,9 +553,9 @@ dependencies = [ [[package]] name = "tracing-subscriber" -version = "0.3.18" +version = "0.3.19" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "ad0f048c97dbd9faa9b7df56362b8ebcaa52adb06b498c050d2f4e32f90a7a8b" +checksum = "e8189decb5ac0fa7bc8b96b7cb9b2701d60d48805aca84a238004d665fcc4008" dependencies = [ "nu-ansi-term", "serde", @@ -565,15 +571,15 @@ dependencies = [ [[package]] name = "unicode-ident" -version = "1.0.12" +version = "1.0.14" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "3354b9ac3fae1ff6755cb6db53683adb661634f67557942dea4facebec0fee4b" +checksum = "adb9e6ca4f869e1180728b7950e35922a7fc6397f7b641499e8f3ef06e50dc83" [[package]] name = "unindent" -version = "0.1.11" +version = "0.2.3" source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "e1766d682d402817b5ac4490b3c3002d91dfa0d22812f341609f97b08757359c" +checksum = "c7de7d73e1754487cb58364ee906a499937a0dfabd86bcb980fa99ec8c8fa2ce" [[package]] name = "valuable" @@ -602,67 +608,3 @@ name = "winapi-x86_64-pc-windows-gnu" version = "0.4.0" source = "registry+https://github.com/rust-lang/crates.io-index" checksum = "712e227841d057c1ee1cd2fb22fa7e5a5461ae8e48fa2ca79ec42cfc1931183f" - -[[package]] -name = "windows-targets" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "9b724f72796e036ab90c1021d4780d4d3d648aca59e491e6b98e725b84e99973" -dependencies = [ - "windows_aarch64_gnullvm", - "windows_aarch64_msvc", - "windows_i686_gnu", - "windows_i686_gnullvm", - "windows_i686_msvc", - "windows_x86_64_gnu", - "windows_x86_64_gnullvm", - "windows_x86_64_msvc", -] - -[[package]] -name = "windows_aarch64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "32a4622180e7a0ec044bb555404c800bc9fd9ec262ec147edd5989ccd0c02cd3" - -[[package]] -name = "windows_aarch64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "09ec2a7bb152e2252b53fa7803150007879548bc709c039df7627cabbd05d469" - -[[package]] -name = "windows_i686_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "8e9b5ad5ab802e97eb8e295ac6720e509ee4c243f69d781394014ebfe8bbfa0b" - -[[package]] -name = "windows_i686_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "0eee52d38c090b3caa76c563b86c3a4bd71ef1a819287c19d586d7334ae8ed66" - -[[package]] -name = "windows_i686_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "240948bc05c5e7c6dabba28bf89d89ffce3e303022809e73deaefe4f6ec56c66" - -[[package]] -name = "windows_x86_64_gnu" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "147a5c80aabfbf0c7d901cb5895d1de30ef2907eb21fbbab29ca94c5b08b1a78" - -[[package]] -name = "windows_x86_64_gnullvm" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "24d5b23dc417412679681396f2b49f3de8c1473deb516bd34410872eff51ed0d" - -[[package]] -name = "windows_x86_64_msvc" -version = "0.52.6" -source = "registry+https://github.com/rust-lang/crates.io-index" -checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec" diff --git a/Cargo.toml b/Cargo.toml index 5a9e726..6c96001 100644 --- a/Cargo.toml +++ b/Cargo.toml @@ -1,26 +1,41 @@ -[package] -name = "rusty-logger" -version = "0.3.2" -edition = "2021" +[workspace] +resolver = "2" +members = [ + "crates/*", + "py-logger", +] +default-members = [ + "crates/*", +] -# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html -[lib] -name = "_rusty_logger" -crate-type = ["cdylib", "rlib"] +[workspace.package] +version = "0.1.0" +authors = ["Steven Forrester "] +edition = "2021" +license = "MIT" +repository = "https://github.com/demml/opsml" -[dependencies] -pyo3 = "0.19.0" -tracing = "0.1.37" -tracing-appender = "0.2.2" -tracing-subscriber = {version = "0.3.17", features = ["json", "time"]} -serde = { version = "1.0.163", features = ["derive"] } -tracing-core = "0.1.31" -serde_json = "1.0.107" -time = "0.3.28" -owo-colors = "4.0.0" -dynfmt = { version = "0.1.5", features = ["curly"] } +[workspace.dependencies] +rusty-logger = { path = "crates/rusty_logger" } +dynfmt = { version = "0.*", features = ["curly"] } +owo-colors = "4.*" +pyo3 = { version = "0.23", features = ["extension-module", "anyhow", "serde", "chrono"] } +serde = { version = "1.*", features = ["derive"] } +serde_json = "1.*" +thiserror = "2.*" +time = "0.*" +tracing = "0.*" +tracing-appender = "0.*" +tracing-core = "0.*" +tracing-subscriber = {version = "0.*", features = ["json", "time"]} [profile.release] lto = "fat" codegen-units = 1 strip = true +opt-level = 3 + +[profile.release-no-lto] +inherits = "release" +lto = false + diff --git a/README.md b/README.md index 7dbd91d..61d6391 100644 --- a/README.md +++ b/README.md @@ -3,6 +3,10 @@ rusty logger logo

+# Attention + +## This crate/library is currently undergoing re-writes. + [![Lints-Tests](https://github.com/thorrester/rusty-logger/actions/workflows/lint-testing.yml/badge.svg?branch=main)](https://github.com/thorrester/rusty-logger/actions/workflows/lint-testing.yml) [![codecov](https://codecov.io/gh/thorrester/rusty-logger/graph/badge.svg?token=RVDMQRUEHT)](https://codecov.io/gh/thorrester/rusty-logger) @@ -13,13 +17,20 @@ Simple, opinionated and fast python logging. `Rusty-Logger` is a thin python wra ## Table of contents -- [Supported configuration](#supported-configuration) -- [Constraints](#constraints) -- [Additional metadata](#additional-metadata) -- [Code examples](#show-me-the-code) -- [Additional examples](#additional-examples) -- [Performance](#performance) -- [Contributing](#contributing) +- [Attention](#attention) + - [This crate/library is currently undergoing re-writes.](#this-cratelibrary-is-currently-undergoing-re-writes) + - [Rusty Logger](#rusty-logger) + - [Table of contents](#table-of-contents) + - [Supported Configuration](#supported-configuration) + - [Constraints](#constraints) + - [Show Me The Code!](#show-me-the-code) + - [Basic Usage](#basic-usage) + - [JSON](#json) + - [Log to file](#log-to-file) + - [Record multiple places at once](#record-multiple-places-at-once) + - [Additional examples](#additional-examples) + - [Performance](#performance) + - [Contributing](#contributing) ## Supported Configuration diff --git a/crates/rusty_logger/Cargo.toml b/crates/rusty_logger/Cargo.toml new file mode 100644 index 0000000..c1de506 --- /dev/null +++ b/crates/rusty_logger/Cargo.toml @@ -0,0 +1,22 @@ +[package] +name = "rusty-logger" +version = { workspace = true } +edition = { workspace = true } +repository = { workspace = true } +description = "Logging for OpsML" + +[lib] +doctest = false + +[dependencies] +dynfmt = { workspace = true } +pyo3 = { workspace = true } +serde = { workspace = true } +serde_json = { workspace = true } +owo-colors = { workspace = true } +thiserror = { workspace = true } +time = { workspace = true } +tracing = { workspace = true } +tracing-appender = { workspace = true } +tracing-core = { workspace = true } +tracing-subscriber = { workspace = true } \ No newline at end of file diff --git a/crates/rusty_logger/src/error.rs b/crates/rusty_logger/src/error.rs new file mode 100644 index 0000000..761dcfc --- /dev/null +++ b/crates/rusty_logger/src/error.rs @@ -0,0 +1,14 @@ +use pyo3::PyErr; +use thiserror::Error; + +#[derive(Error, Debug)] +pub enum LoggingError { + #[error("Logging Error: {0}")] + Error(String), +} + +impl From for PyErr { + fn from(err: LoggingError) -> PyErr { + PyErr::new::(err.to_string()) + } +} diff --git a/crates/rusty_logger/src/lib.rs b/crates/rusty_logger/src/lib.rs new file mode 100644 index 0000000..f83f3f3 --- /dev/null +++ b/crates/rusty_logger/src/lib.rs @@ -0,0 +1,2 @@ +pub mod error; +pub mod logger; diff --git a/crates/rusty_logger/src/logger.rs b/crates/rusty_logger/src/logger.rs new file mode 100644 index 0000000..59b3402 --- /dev/null +++ b/crates/rusty_logger/src/logger.rs @@ -0,0 +1,256 @@ +use crate::error::LoggingError; +use dynfmt::{Format, SimpleCurlyFormat}; +use pyo3::prelude::*; +use pyo3::types::PyTuple; +use pyo3::types::PyTupleMethods; +use serde::{Deserialize, Serialize}; +use std::io; +use std::str::FromStr; +use tracing_subscriber; +use tracing_subscriber::fmt::time::UtcTime; + +#[pyclass(eq)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Default)] +pub enum LogLevel { + Debug, + #[default] + Info, + Warn, + Error, + Trace, +} + +impl FromStr for LogLevel { + type Err = LoggingError; + + fn from_str(s: &str) -> Result { + match s { + "debug" => Ok(LogLevel::Debug), + "info" => Ok(LogLevel::Info), + "warn" => Ok(LogLevel::Warn), + "error" => Ok(LogLevel::Error), + "trace" => Ok(LogLevel::Trace), + _ => Ok(LogLevel::Info), + } + } +} + +#[pyclass(eq)] +#[derive(Debug, PartialEq, Clone, Serialize, Deserialize, Default)] +pub enum WriteLevel { + #[default] + Stdout, + Stderror, +} + +#[allow(clippy::len_zero)] // len tends to be faster than is_empty in tests +fn format_string(message: &str, args: &Vec) -> String { + if args.len() > 0 { + SimpleCurlyFormat + .format(message, args) + .unwrap_or_else(|_| message.into()) + .to_string() + } else { + message.to_string() + } +} + +pub fn parse_args(args: &Bound<'_, PyTuple>) -> Option> { + if args.is_empty() { + None + } else { + Some(args.iter().map(|x| x.to_string()).collect()) + } +} + +const DEFAULT_TIME_PATTERN: &str = + "[year]-[month]-[day]T[hour repr:24]:[minute]:[second]::[subsecond digits:4]"; + +fn build_json_subscriber( + log_level: tracing::Level, + config: &LoggingConfig, +) -> Result<(), LoggingError> { + let sub = tracing_subscriber::fmt() + .with_max_level(log_level) + .json() + .with_target(false) + .flatten_event(true) + .with_thread_ids(config.show_threads.clone()) + .with_timer(config.time_format()?); + + if config.write_level == WriteLevel::Stderror { + sub.with_writer(io::stderr).try_init().map_err(|e| { + LoggingError::Error(format!("Failed to setup logging with error: {}", e)) + })?; + } else { + sub.with_writer(io::stdout).try_init().map_err(|e| { + LoggingError::Error(format!("Failed to setup logging with error: {}", e)) + })?; + } + Ok(()) +} + +fn build_subscriber(log_level: tracing::Level, config: &LoggingConfig) -> Result<(), LoggingError> { + let sub = tracing_subscriber::fmt() + .with_max_level(log_level) + .with_target(false) + .with_thread_ids(config.show_threads.clone()) + .with_timer(config.time_format()?); + + if config.write_level == WriteLevel::Stderror { + sub.with_writer(io::stderr).try_init().map_err(|e| { + LoggingError::Error(format!("Failed to setup logging with error: {}", e)) + })?; + } else { + sub.with_writer(io::stdout).try_init().map_err(|e| { + LoggingError::Error(format!("Failed to setup logging with error: {}", e)) + })?; + } + Ok(()) +} + +pub fn setup_logging(config: &LoggingConfig) -> Result<(), LoggingError> { + let display_level = match &config.log_level { + LogLevel::Debug => tracing::Level::DEBUG, + LogLevel::Info => tracing::Level::INFO, + LogLevel::Warn => tracing::Level::WARN, + LogLevel::Error => tracing::Level::ERROR, + LogLevel::Trace => tracing::Level::TRACE, + }; + + if config.use_json { + return build_json_subscriber(display_level, config); + } else { + return build_subscriber(display_level, config); + } +} + +#[pyclass] +#[derive(Clone, Default)] +pub struct LoggingConfig { + #[pyo3(get, set)] + show_threads: bool, + + #[pyo3(get, set)] + log_level: LogLevel, + + #[pyo3(get, set)] + write_level: WriteLevel, + + #[pyo3(get, set)] + use_json: bool, +} + +#[pymethods] +impl LoggingConfig { + #[new] + #[pyo3(signature = (show_threads=None, log_level=None, write_level=WriteLevel::Stdout, use_json=false))] + pub fn new( + show_threads: Option, + log_level: Option, + write_level: Option, + use_json: Option, + ) -> Self { + let show_threads = show_threads.unwrap_or(true); + let log_level = log_level.unwrap_or(LogLevel::Info); + let write_level = write_level.unwrap_or(WriteLevel::Stdout); + let use_json = use_json.unwrap_or(false); + LoggingConfig { + show_threads, + log_level, + write_level, + use_json, + } + } +} + +impl LoggingConfig { + fn time_format( + &self, + ) -> Result>>, LoggingError> { + let formatter = UtcTime::new( + time::format_description::parse(DEFAULT_TIME_PATTERN).map_err(|e| { + LoggingError::Error(format!( + "Failed to parse time format: {} with error: {}", + DEFAULT_TIME_PATTERN, e + )) + })?, + ); + + Ok(formatter) + } +} + +#[pyclass] +pub struct RustyLogger {} + +#[pymethods] +impl RustyLogger { + #[staticmethod] + #[pyo3(signature = (config=None))] + pub fn setup_logging(config: Option) -> Result<(), LoggingError> { + let config = config.unwrap_or(LoggingConfig::default()); + let _ = setup_logging(&config).is_ok(); + + Ok(()) + } + + #[staticmethod] + #[pyo3(signature = (config=None))] + pub fn get_logger(config: Option) -> Result { + let config = config.unwrap_or(LoggingConfig::default()); + let _ = setup_logging(&config).is_ok(); + + Ok(RustyLogger {}) + } + + #[pyo3(signature = (message, *args))] + pub fn info(&self, message: &str, args: &Bound<'_, PyTuple>) { + let args = parse_args(args); + let msg = match args { + Some(val) => format_string(message, &val), + None => message.to_string(), + }; + tracing::info!(msg); + } + + #[pyo3(signature = (message, *args))] + pub fn debug(&self, message: &str, args: &Bound<'_, PyTuple>) { + let args = parse_args(args); + let msg = match args { + Some(val) => format_string(message, &val), + None => message.to_string(), + }; + tracing::debug!(msg); + } + + #[pyo3(signature = (message, *args))] + pub fn warn(&self, message: &str, args: &Bound<'_, PyTuple>) { + let args = parse_args(args); + let msg = match args { + Some(val) => format_string(message, &val), + None => message.to_string(), + }; + tracing::warn!(msg); + } + + #[pyo3(signature = (message, *args))] + pub fn error(&self, message: &str, args: &Bound<'_, PyTuple>) { + let args = parse_args(args); + let msg = match args { + Some(val) => format_string(message, &val), + None => message.to_string(), + }; + tracing::error!(msg); + } + + #[pyo3(signature = (message, *args))] + pub fn trace(&self, message: &str, args: &Bound<'_, PyTuple>) { + let args = parse_args(args); + let msg = match args { + Some(val) => format_string(message, &val), + None => message.to_string(), + }; + tracing::trace!(msg); + } +} diff --git a/poetry.lock b/poetry.lock deleted file mode 100644 index 192a5c2..0000000 --- a/poetry.lock +++ /dev/null @@ -1,1036 +0,0 @@ -# This file is automatically @generated by Poetry 1.8.3 and should not be changed by hand. - -[[package]] -name = "annotated-types" -version = "0.7.0" -description = "Reusable constraint types to use with typing.Annotated" -optional = false -python-versions = ">=3.8" -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.dependencies] -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.9\""} - -[[package]] -name = "anyio" -version = "4.4.0" -description = "High level compatibility layer for multiple asynchronous event loop implementations" -optional = false -python-versions = ">=3.8" -files = [ - {file = "anyio-4.4.0-py3-none-any.whl", hash = "sha256:c1b2d8f46a8a812513012e1107cb0e68c17159a7a594208005a57dc776e1bdc7"}, - {file = "anyio-4.4.0.tar.gz", hash = "sha256:5aadc6a1bbb7cdb0bede386cac5e2940f5e2ff3aa20277e991cf028e0585ce94"}, -] - -[package.dependencies] -exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""} -idna = ">=2.8" -sniffio = ">=1.1" -typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""} - -[package.extras] -doc = ["Sphinx (>=7)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"] -test = ["anyio[trio]", "coverage[toml] (>=7)", "exceptiongroup (>=1.2.0)", "hypothesis (>=4.0)", "psutil (>=5.9)", "pytest (>=7.0)", "pytest-mock (>=3.6.1)", "trustme", "uvloop (>=0.17)"] -trio = ["trio (>=0.23)"] - -[[package]] -name = "astroid" -version = "2.15.8" -description = "An abstract syntax tree for Python with inference support." -optional = false -python-versions = ">=3.7.2" -files = [ - {file = "astroid-2.15.8-py3-none-any.whl", hash = "sha256:1aa149fc5c6589e3d0ece885b4491acd80af4f087baafa3fb5203b113e68cd3c"}, - {file = "astroid-2.15.8.tar.gz", hash = "sha256:6c107453dffee9055899705de3c9ead36e74119cee151e5a9aaf7f0b0e020a6a"}, -] - -[package.dependencies] -lazy-object-proxy = ">=1.4.0" -typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} -wrapt = [ - {version = ">=1.11,<2", markers = "python_version < \"3.11\""}, - {version = ">=1.14,<2", markers = "python_version >= \"3.11\""}, -] - -[[package]] -name = "black" -version = "22.3.0" -description = "The uncompromising code formatter." -optional = false -python-versions = ">=3.6.2" -files = [ - {file = "black-22.3.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:2497f9c2386572e28921fa8bec7be3e51de6801f7459dffd6e62492531c47e09"}, - {file = "black-22.3.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5795a0375eb87bfe902e80e0c8cfaedf8af4d49694d69161e5bd3206c18618bb"}, - {file = "black-22.3.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e3556168e2e5c49629f7b0f377070240bd5511e45e25a4497bb0073d9dda776a"}, - {file = "black-22.3.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67c8301ec94e3bcc8906740fe071391bce40a862b7be0b86fb5382beefecd968"}, - {file = "black-22.3.0-cp310-cp310-win_amd64.whl", hash = "sha256:fd57160949179ec517d32ac2ac898b5f20d68ed1a9c977346efbac9c2f1e779d"}, - {file = "black-22.3.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:cc1e1de68c8e5444e8f94c3670bb48a2beef0e91dddfd4fcc29595ebd90bb9ce"}, - {file = "black-22.3.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6d2fc92002d44746d3e7db7cf9313cf4452f43e9ea77a2c939defce3b10b5c82"}, - {file = "black-22.3.0-cp36-cp36m-win_amd64.whl", hash = "sha256:a6342964b43a99dbc72f72812bf88cad8f0217ae9acb47c0d4f141a6416d2d7b"}, - {file = "black-22.3.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:328efc0cc70ccb23429d6be184a15ce613f676bdfc85e5fe8ea2a9354b4e9015"}, - {file = "black-22.3.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:06f9d8846f2340dfac80ceb20200ea5d1b3f181dd0556b47af4e8e0b24fa0a6b"}, - {file = "black-22.3.0-cp37-cp37m-win_amd64.whl", hash = "sha256:ad4efa5fad66b903b4a5f96d91461d90b9507a812b3c5de657d544215bb7877a"}, - {file = "black-22.3.0-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:e8477ec6bbfe0312c128e74644ac8a02ca06bcdb8982d4ee06f209be28cdf163"}, - {file = "black-22.3.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:637a4014c63fbf42a692d22b55d8ad6968a946b4a6ebc385c5505d9625b6a464"}, - {file = "black-22.3.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:863714200ada56cbc366dc9ae5291ceb936573155f8bf8e9de92aef51f3ad0f0"}, - {file = "black-22.3.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10dbe6e6d2988049b4655b2b739f98785a884d4d6b85bc35133a8fb9a2233176"}, - {file = "black-22.3.0-cp38-cp38-win_amd64.whl", hash = "sha256:cee3e11161dde1b2a33a904b850b0899e0424cc331b7295f2a9698e79f9a69a0"}, - {file = "black-22.3.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:5891ef8abc06576985de8fa88e95ab70641de6c1fca97e2a15820a9b69e51b20"}, - {file = "black-22.3.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:30d78ba6bf080eeaf0b7b875d924b15cd46fec5fd044ddfbad38c8ea9171043a"}, - {file = "black-22.3.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ee8f1f7228cce7dffc2b464f07ce769f478968bfb3dd1254a4c2eeed84928aad"}, - {file = "black-22.3.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6ee227b696ca60dd1c507be80a6bc849a5a6ab57ac7352aad1ffec9e8b805f21"}, - {file = "black-22.3.0-cp39-cp39-win_amd64.whl", hash = "sha256:9b542ced1ec0ceeff5b37d69838106a6348e60db7b8fdd245294dc1d26136265"}, - {file = "black-22.3.0-py3-none-any.whl", hash = "sha256:bc58025940a896d7e5356952228b68f793cf5fcb342be703c3a2669a1488cb72"}, - {file = "black-22.3.0.tar.gz", hash = "sha256:35020b8886c022ced9282b51b5a875b6d1ab0c387b31a065b84db7c33085ca79"}, -] - -[package.dependencies] -click = ">=8.0.0" -mypy-extensions = ">=0.4.3" -pathspec = ">=0.9.0" -platformdirs = ">=2" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = {version = ">=3.10.0.0", markers = "python_version < \"3.10\""} - -[package.extras] -colorama = ["colorama (>=0.4.3)"] -d = ["aiohttp (>=3.7.4)"] -jupyter = ["ipython (>=7.8.0)", "tokenize-rt (>=3.2.0)"] -uvloop = ["uvloop (>=0.15.2)"] - -[[package]] -name = "certifi" -version = "2024.7.4" -description = "Python package for providing Mozilla's CA Bundle." -optional = false -python-versions = ">=3.6" -files = [ - {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, - {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, -] - -[[package]] -name = "click" -version = "8.1.7" -description = "Composable command line interface toolkit" -optional = false -python-versions = ">=3.7" -files = [ - {file = "click-8.1.7-py3-none-any.whl", hash = "sha256:ae74fb96c20a0277a1d615f1e4d73c8414f5a98db8b799a7931d1582f3390c28"}, - {file = "click-8.1.7.tar.gz", hash = "sha256:ca9853ad459e787e2192211578cc907e7594e294c7ccc834310722b41b9ca6de"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "platform_system == \"Windows\""} - -[[package]] -name = "colorama" -version = "0.4.6" -description = "Cross-platform colored terminal text." -optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -files = [ - {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, - {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, -] - -[[package]] -name = "coverage" -version = "7.6.0" -description = "Code coverage measurement for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "coverage-7.6.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:dff044f661f59dace805eedb4a7404c573b6ff0cdba4a524141bc63d7be5c7fd"}, - {file = "coverage-7.6.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a8659fd33ee9e6ca03950cfdcdf271d645cf681609153f218826dd9805ab585c"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7792f0ab20df8071d669d929c75c97fecfa6bcab82c10ee4adb91c7a54055463"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b3cd1ca7cd73d229487fa5caca9e4bc1f0bca96526b922d61053ea751fe791"}, - {file = "coverage-7.6.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e7e128f85c0b419907d1f38e616c4f1e9f1d1b37a7949f44df9a73d5da5cd53c"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a94925102c89247530ae1dab7dc02c690942566f22e189cbd53579b0693c0783"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:dcd070b5b585b50e6617e8972f3fbbee786afca71b1936ac06257f7e178f00f6"}, - {file = "coverage-7.6.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:d50a252b23b9b4dfeefc1f663c568a221092cbaded20a05a11665d0dbec9b8fb"}, - {file = "coverage-7.6.0-cp310-cp310-win32.whl", hash = "sha256:0e7b27d04131c46e6894f23a4ae186a6a2207209a05df5b6ad4caee6d54a222c"}, - {file = "coverage-7.6.0-cp310-cp310-win_amd64.whl", hash = "sha256:54dece71673b3187c86226c3ca793c5f891f9fc3d8aa183f2e3653da18566169"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c7b525ab52ce18c57ae232ba6f7010297a87ced82a2383b1afd238849c1ff933"}, - {file = "coverage-7.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4bea27c4269234e06f621f3fac3925f56ff34bc14521484b8f66a580aacc2e7d"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ed8d1d1821ba5fc88d4a4f45387b65de52382fa3ef1f0115a4f7a20cdfab0e94"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01c322ef2bbe15057bc4bf132b525b7e3f7206f071799eb8aa6ad1940bcf5fb1"}, - {file = "coverage-7.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:03cafe82c1b32b770a29fd6de923625ccac3185a54a5e66606da26d105f37dac"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0d1b923fc4a40c5832be4f35a5dab0e5ff89cddf83bb4174499e02ea089daf57"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4b03741e70fb811d1a9a1d75355cf391f274ed85847f4b78e35459899f57af4d"}, - {file = "coverage-7.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a73d18625f6a8a1cbb11eadc1d03929f9510f4131879288e3f7922097a429f63"}, - {file = "coverage-7.6.0-cp311-cp311-win32.whl", hash = "sha256:65fa405b837060db569a61ec368b74688f429b32fa47a8929a7a2f9b47183713"}, - {file = "coverage-7.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:6379688fb4cfa921ae349c76eb1a9ab26b65f32b03d46bb0eed841fd4cb6afb1"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f7db0b6ae1f96ae41afe626095149ecd1b212b424626175a6633c2999eaad45b"}, - {file = "coverage-7.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bbdf9a72403110a3bdae77948b8011f644571311c2fb35ee15f0f10a8fc082e8"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9cc44bf0315268e253bf563f3560e6c004efe38f76db03a1558274a6e04bf5d5"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:da8549d17489cd52f85a9829d0e1d91059359b3c54a26f28bec2c5d369524807"}, - {file = "coverage-7.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0086cd4fc71b7d485ac93ca4239c8f75732c2ae3ba83f6be1c9be59d9e2c6382"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1fad32ee9b27350687035cb5fdf9145bc9cf0a094a9577d43e909948ebcfa27b"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:044a0985a4f25b335882b0966625270a8d9db3d3409ddc49a4eb00b0ef5e8cee"}, - {file = "coverage-7.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:76d5f82213aa78098b9b964ea89de4617e70e0d43e97900c2778a50856dac605"}, - {file = "coverage-7.6.0-cp312-cp312-win32.whl", hash = "sha256:3c59105f8d58ce500f348c5b56163a4113a440dad6daa2294b5052a10db866da"}, - {file = "coverage-7.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:ca5d79cfdae420a1d52bf177de4bc2289c321d6c961ae321503b2ca59c17ae67"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:d39bd10f0ae453554798b125d2f39884290c480f56e8a02ba7a6ed552005243b"}, - {file = "coverage-7.6.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:beb08e8508e53a568811016e59f3234d29c2583f6b6e28572f0954a6b4f7e03d"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b2e16f4cd2bc4d88ba30ca2d3bbf2f21f00f382cf4e1ce3b1ddc96c634bc48ca"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6616d1c9bf1e3faea78711ee42a8b972367d82ceae233ec0ac61cc7fec09fa6b"}, - {file = "coverage-7.6.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ad4567d6c334c46046d1c4c20024de2a1c3abc626817ae21ae3da600f5779b44"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:d17c6a415d68cfe1091d3296ba5749d3d8696e42c37fca5d4860c5bf7b729f03"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:9146579352d7b5f6412735d0f203bbd8d00113a680b66565e205bc605ef81bc6"}, - {file = "coverage-7.6.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:cdab02a0a941af190df8782aafc591ef3ad08824f97850b015c8c6a8b3877b0b"}, - {file = "coverage-7.6.0-cp38-cp38-win32.whl", hash = "sha256:df423f351b162a702c053d5dddc0fc0ef9a9e27ea3f449781ace5f906b664428"}, - {file = "coverage-7.6.0-cp38-cp38-win_amd64.whl", hash = "sha256:f2501d60d7497fd55e391f423f965bbe9e650e9ffc3c627d5f0ac516026000b8"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7221f9ac9dad9492cecab6f676b3eaf9185141539d5c9689d13fd6b0d7de840c"}, - {file = "coverage-7.6.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:ddaaa91bfc4477d2871442bbf30a125e8fe6b05da8a0015507bfbf4718228ab2"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c4cbe651f3904e28f3a55d6f371203049034b4ddbce65a54527a3f189ca3b390"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:831b476d79408ab6ccfadaaf199906c833f02fdb32c9ab907b1d4aa0713cfa3b"}, - {file = "coverage-7.6.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:46c3d091059ad0b9c59d1034de74a7f36dcfa7f6d3bde782c49deb42438f2450"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:4d5fae0a22dc86259dee66f2cc6c1d3e490c4a1214d7daa2a93d07491c5c04b6"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:07ed352205574aad067482e53dd606926afebcb5590653121063fbf4e2175166"}, - {file = "coverage-7.6.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:49c76cdfa13015c4560702574bad67f0e15ca5a2872c6a125f6327ead2b731dd"}, - {file = "coverage-7.6.0-cp39-cp39-win32.whl", hash = "sha256:482855914928c8175735a2a59c8dc5806cf7d8f032e4820d52e845d1f731dca2"}, - {file = "coverage-7.6.0-cp39-cp39-win_amd64.whl", hash = "sha256:543ef9179bc55edfd895154a51792b01c017c87af0ebaae092720152e19e42ca"}, - {file = "coverage-7.6.0-pp38.pp39.pp310-none-any.whl", hash = "sha256:6fe885135c8a479d3e37a7aae61cbd3a0fb2deccb4dda3c25f92a49189f766d6"}, - {file = "coverage-7.6.0.tar.gz", hash = "sha256:289cc803fa1dc901f84701ac10c9ee873619320f2f9aff38794db4a4a0268d51"}, -] - -[package.dependencies] -tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""} - -[package.extras] -toml = ["tomli"] - -[[package]] -name = "dill" -version = "0.3.8" -description = "serialize all of Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "dill-0.3.8-py3-none-any.whl", hash = "sha256:c36ca9ffb54365bdd2f8eb3eff7d2a21237f8452b57ace88b1ac615b7e815bd7"}, - {file = "dill-0.3.8.tar.gz", hash = "sha256:3ebe3c479ad625c4553aca177444d89b486b1d84982eeacded644afc0cf797ca"}, -] - -[package.extras] -graph = ["objgraph (>=1.7.2)"] -profile = ["gprof2dot (>=2022.7.29)"] - -[[package]] -name = "exceptiongroup" -version = "1.2.2" -description = "Backport of PEP 654 (exception groups)" -optional = false -python-versions = ">=3.7" -files = [ - {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, - {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, -] - -[package.extras] -test = ["pytest (>=6)"] - -[[package]] -name = "fastapi" -version = "0.109.2" -description = "FastAPI framework, high performance, easy to learn, fast to code, ready for production" -optional = false -python-versions = ">=3.8" -files = [ - {file = "fastapi-0.109.2-py3-none-any.whl", hash = "sha256:2c9bab24667293b501cad8dd388c05240c850b58ec5876ee3283c47d6e1e3a4d"}, - {file = "fastapi-0.109.2.tar.gz", hash = "sha256:f3817eac96fe4f65a2ebb4baa000f394e55f5fccdaf7f75250804bc58f354f73"}, -] - -[package.dependencies] -pydantic = ">=1.7.4,<1.8 || >1.8,<1.8.1 || >1.8.1,<2.0.0 || >2.0.0,<2.0.1 || >2.0.1,<2.1.0 || >2.1.0,<3.0.0" -starlette = ">=0.36.3,<0.37.0" -typing-extensions = ">=4.8.0" - -[package.extras] -all = ["email-validator (>=2.0.0)", "httpx (>=0.23.0)", "itsdangerous (>=1.1.0)", "jinja2 (>=2.11.2)", "orjson (>=3.2.1)", "pydantic-extra-types (>=2.0.0)", "pydantic-settings (>=2.0.0)", "python-multipart (>=0.0.7)", "pyyaml (>=5.3.1)", "ujson (>=4.0.1,!=4.0.2,!=4.1.0,!=4.2.0,!=4.3.0,!=5.0.0,!=5.1.0)", "uvicorn[standard] (>=0.12.0)"] - -[[package]] -name = "gunicorn" -version = "22.0.0" -description = "WSGI HTTP Server for UNIX" -optional = false -python-versions = ">=3.7" -files = [ - {file = "gunicorn-22.0.0-py3-none-any.whl", hash = "sha256:350679f91b24062c86e386e198a15438d53a7a8207235a78ba1b53df4c4378d9"}, - {file = "gunicorn-22.0.0.tar.gz", hash = "sha256:4a0b436239ff76fb33f11c07a16482c521a7e09c1ce3cc293c2330afe01bec63"}, -] - -[package.dependencies] -packaging = "*" - -[package.extras] -eventlet = ["eventlet (>=0.24.1,!=0.36.0)"] -gevent = ["gevent (>=1.4.0)"] -setproctitle = ["setproctitle"] -testing = ["coverage", "eventlet", "gevent", "pytest", "pytest-cov"] -tornado = ["tornado (>=0.2)"] - -[[package]] -name = "h11" -version = "0.14.0" -description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" -optional = false -python-versions = ">=3.7" -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.5" -description = "A minimal low-level HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpcore-1.0.5-py3-none-any.whl", hash = "sha256:421f18bac248b25d310f3cacd198d55b8e6125c107797b609ff9b7a6ba7991b5"}, - {file = "httpcore-1.0.5.tar.gz", hash = "sha256:34a38e2f9291467ee3b44e89dd52615370e152954ba21721378a87b2960f7a61"}, -] - -[package.dependencies] -certifi = "*" -h11 = ">=0.13,<0.15" - -[package.extras] -asyncio = ["anyio (>=4.0,<5.0)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] -trio = ["trio (>=0.22.0,<0.26.0)"] - -[[package]] -name = "httpx" -version = "0.27.0" -description = "The next generation HTTP client." -optional = false -python-versions = ">=3.8" -files = [ - {file = "httpx-0.27.0-py3-none-any.whl", hash = "sha256:71d5465162c13681bff01ad59b2cc68dd838ea1f10e51574bac27103f00c91a5"}, - {file = "httpx-0.27.0.tar.gz", hash = "sha256:a0cb88a46f32dc874e04ee956e4c2764aba2aa228f650b06788ba6bda2962ab5"}, -] - -[package.dependencies] -anyio = "*" -certifi = "*" -httpcore = "==1.*" -idna = "*" -sniffio = "*" - -[package.extras] -brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] -http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] - -[[package]] -name = "idna" -version = "3.7" -description = "Internationalized Domain Names in Applications (IDNA)" -optional = false -python-versions = ">=3.5" -files = [ - {file = "idna-3.7-py3-none-any.whl", hash = "sha256:82fee1fc78add43492d3a1898bfa6d8a904cc97d8427f683ed8e798d07761aa0"}, - {file = "idna-3.7.tar.gz", hash = "sha256:028ff3aadf0609c1fd278d8ea3089299412a7a8b9bd005dd08b9f8285bcb5cfc"}, -] - -[[package]] -name = "iniconfig" -version = "2.0.0" -description = "brain-dead simple config-ini parsing" -optional = false -python-versions = ">=3.7" -files = [ - {file = "iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374"}, - {file = "iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3"}, -] - -[[package]] -name = "isort" -version = "5.13.2" -description = "A Python utility / library to sort Python imports." -optional = false -python-versions = ">=3.8.0" -files = [ - {file = "isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6"}, - {file = "isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109"}, -] - -[package.extras] -colors = ["colorama (>=0.4.6)"] - -[[package]] -name = "lazy-object-proxy" -version = "1.10.0" -description = "A fast and thorough lazy object proxy." -optional = false -python-versions = ">=3.8" -files = [ - {file = "lazy-object-proxy-1.10.0.tar.gz", hash = "sha256:78247b6d45f43a52ef35c25b5581459e85117225408a4128a3daf8bf9648ac69"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:855e068b0358ab916454464a884779c7ffa312b8925c6f7401e952dcf3b89977"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7ab7004cf2e59f7c2e4345604a3e6ea0d92ac44e1c2375527d56492014e690c3"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc0d2fc424e54c70c4bc06787e4072c4f3b1aa2f897dfdc34ce1013cf3ceef05"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e2adb09778797da09d2b5ebdbceebf7dd32e2c96f79da9052b2e87b6ea495895"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:b1f711e2c6dcd4edd372cf5dec5c5a30d23bba06ee012093267b3376c079ec83"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-win32.whl", hash = "sha256:76a095cfe6045c7d0ca77db9934e8f7b71b14645f0094ffcd842349ada5c5fb9"}, - {file = "lazy_object_proxy-1.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:b4f87d4ed9064b2628da63830986c3d2dca7501e6018347798313fcf028e2fd4"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fec03caabbc6b59ea4a638bee5fce7117be8e99a4103d9d5ad77f15d6f81020c"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02c83f957782cbbe8136bee26416686a6ae998c7b6191711a04da776dc9e47d4"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:009e6bb1f1935a62889ddc8541514b6a9e1fcf302667dcb049a0be5c8f613e56"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:75fc59fc450050b1b3c203c35020bc41bd2695ed692a392924c6ce180c6f1dc9"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:782e2c9b2aab1708ffb07d4bf377d12901d7a1d99e5e410d648d892f8967ab1f"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-win32.whl", hash = "sha256:edb45bb8278574710e68a6b021599a10ce730d156e5b254941754a9cc0b17d03"}, - {file = "lazy_object_proxy-1.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:e271058822765ad5e3bca7f05f2ace0de58a3f4e62045a8c90a0dfd2f8ad8cc6"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:e98c8af98d5707dcdecc9ab0863c0ea6e88545d42ca7c3feffb6b4d1e370c7ba"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:952c81d415b9b80ea261d2372d2a4a2332a3890c2b83e0535f263ddfe43f0d43"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80b39d3a151309efc8cc48675918891b865bdf742a8616a337cb0090791a0de9"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e221060b701e2aa2ea991542900dd13907a5c90fa80e199dbf5a03359019e7a3"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:92f09ff65ecff3108e56526f9e2481b8116c0b9e1425325e13245abfd79bdb1b"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-win32.whl", hash = "sha256:3ad54b9ddbe20ae9f7c1b29e52f123120772b06dbb18ec6be9101369d63a4074"}, - {file = "lazy_object_proxy-1.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:127a789c75151db6af398b8972178afe6bda7d6f68730c057fbbc2e96b08d282"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9e4ed0518a14dd26092614412936920ad081a424bdcb54cc13349a8e2c6d106a"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ad9e6ed739285919aa9661a5bbed0aaf410aa60231373c5579c6b4801bd883c"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2fc0a92c02fa1ca1e84fc60fa258458e5bf89d90a1ddaeb8ed9cc3147f417255"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:0aefc7591920bbd360d57ea03c995cebc204b424524a5bd78406f6e1b8b2a5d8"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:5faf03a7d8942bb4476e3b62fd0f4cf94eaf4618e304a19865abf89a35c0bbee"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-win32.whl", hash = "sha256:e333e2324307a7b5d86adfa835bb500ee70bfcd1447384a822e96495796b0ca4"}, - {file = "lazy_object_proxy-1.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:cb73507defd385b7705c599a94474b1d5222a508e502553ef94114a143ec6696"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366c32fe5355ef5fc8a232c5436f4cc66e9d3e8967c01fb2e6302fd6627e3d94"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2297f08f08a2bb0d32a4265e98a006643cd7233fb7983032bd61ac7a02956b3b"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:18dd842b49456aaa9a7cf535b04ca4571a302ff72ed8740d06b5adcd41fe0757"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:217138197c170a2a74ca0e05bddcd5f1796c735c37d0eee33e43259b192aa424"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:9a3a87cf1e133e5b1994144c12ca4aa3d9698517fe1e2ca82977781b16955658"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-win32.whl", hash = "sha256:30b339b2a743c5288405aa79a69e706a06e02958eab31859f7f3c04980853b70"}, - {file = "lazy_object_proxy-1.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:a899b10e17743683b293a729d3a11f2f399e8a90c73b089e29f5d0fe3509f0dd"}, - {file = "lazy_object_proxy-1.10.0-pp310.pp311.pp312.pp38.pp39-none-any.whl", hash = "sha256:80fa48bd89c8f2f456fc0765c11c23bf5af827febacd2f523ca5bc1893fcc09d"}, -] - -[[package]] -name = "markdown-it-py" -version = "3.0.0" -description = "Python port of markdown-it. Markdown parsing, done right!" -optional = false -python-versions = ">=3.8" -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.dependencies] -mdurl = ">=0.1,<1.0" - -[package.extras] -benchmarking = ["psutil", "pytest", "pytest-benchmark"] -code-style = ["pre-commit (>=3.0,<4.0)"] -compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] -linkify = ["linkify-it-py (>=1,<3)"] -plugins = ["mdit-py-plugins"] -profiling = ["gprof2dot"] -rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] -testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] - -[[package]] -name = "mccabe" -version = "0.7.0" -description = "McCabe checker, plugin for flake8" -optional = false -python-versions = ">=3.6" -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, -] - -[[package]] -name = "mdurl" -version = "0.1.2" -description = "Markdown URL utilities" -optional = false -python-versions = ">=3.7" -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 = "mypy" -version = "1.11.1" -description = "Optional static typing for Python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "mypy-1.11.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:a32fc80b63de4b5b3e65f4be82b4cfa362a46702672aa6a0f443b4689af7008c"}, - {file = "mypy-1.11.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c1952f5ea8a5a959b05ed5f16452fddadbaae48b5d39235ab4c3fc444d5fd411"}, - {file = "mypy-1.11.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:e1e30dc3bfa4e157e53c1d17a0dad20f89dc433393e7702b813c10e200843b03"}, - {file = "mypy-1.11.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:2c63350af88f43a66d3dfeeeb8d77af34a4f07d760b9eb3a8697f0386c7590b4"}, - {file = "mypy-1.11.1-cp310-cp310-win_amd64.whl", hash = "sha256:a831671bad47186603872a3abc19634f3011d7f83b083762c942442d51c58d58"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:7b6343d338390bb946d449677726edf60102a1c96079b4f002dedff375953fc5"}, - {file = "mypy-1.11.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e4fe9f4e5e521b458d8feb52547f4bade7ef8c93238dfb5bbc790d9ff2d770ca"}, - {file = "mypy-1.11.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:886c9dbecc87b9516eff294541bf7f3655722bf22bb898ee06985cd7269898de"}, - {file = "mypy-1.11.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fca4a60e1dd9fd0193ae0067eaeeb962f2d79e0d9f0f66223a0682f26ffcc809"}, - {file = "mypy-1.11.1-cp311-cp311-win_amd64.whl", hash = "sha256:0bd53faf56de9643336aeea1c925012837432b5faf1701ccca7fde70166ccf72"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:f39918a50f74dc5969807dcfaecafa804fa7f90c9d60506835036cc1bc891dc8"}, - {file = "mypy-1.11.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:0bc71d1fb27a428139dd78621953effe0d208aed9857cb08d002280b0422003a"}, - {file = "mypy-1.11.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:b868d3bcff720dd7217c383474008ddabaf048fad8d78ed948bb4b624870a417"}, - {file = "mypy-1.11.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a707ec1527ffcdd1c784d0924bf5cb15cd7f22683b919668a04d2b9c34549d2e"}, - {file = "mypy-1.11.1-cp312-cp312-win_amd64.whl", hash = "sha256:64f4a90e3ea07f590c5bcf9029035cf0efeae5ba8be511a8caada1a4893f5525"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:749fd3213916f1751fff995fccf20c6195cae941dc968f3aaadf9bb4e430e5a2"}, - {file = "mypy-1.11.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:b639dce63a0b19085213ec5fdd8cffd1d81988f47a2dec7100e93564f3e8fb3b"}, - {file = "mypy-1.11.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c956b49c5d865394d62941b109728c5c596a415e9c5b2be663dd26a1ff07bc0"}, - {file = "mypy-1.11.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:45df906e8b6804ef4b666af29a87ad9f5921aad091c79cc38e12198e220beabd"}, - {file = "mypy-1.11.1-cp38-cp38-win_amd64.whl", hash = "sha256:d44be7551689d9d47b7abc27c71257adfdb53f03880841a5db15ddb22dc63edb"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:2684d3f693073ab89d76da8e3921883019ea8a3ec20fa5d8ecca6a2db4c54bbe"}, - {file = "mypy-1.11.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:79c07eb282cb457473add5052b63925e5cc97dfab9812ee65a7c7ab5e3cb551c"}, - {file = "mypy-1.11.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:11965c2f571ded6239977b14deebd3f4c3abd9a92398712d6da3a772974fad69"}, - {file = "mypy-1.11.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a2b43895a0f8154df6519706d9bca8280cda52d3d9d1514b2d9c3e26792a0b74"}, - {file = "mypy-1.11.1-cp39-cp39-win_amd64.whl", hash = "sha256:1a81cf05975fd61aec5ae16501a091cfb9f605dc3e3c878c0da32f250b74760b"}, - {file = "mypy-1.11.1-py3-none-any.whl", hash = "sha256:0624bdb940255d2dd24e829d99a13cfeb72e4e9031f9492148f410ed30bcab54"}, - {file = "mypy-1.11.1.tar.gz", hash = "sha256:f404a0b069709f18bbdb702eb3dcfe51910602995de00bd39cea3050b5772d08"}, -] - -[package.dependencies] -mypy-extensions = ">=1.0.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -typing-extensions = ">=4.6.0" - -[package.extras] -dmypy = ["psutil (>=4.0)"] -install-types = ["pip"] -mypyc = ["setuptools (>=50)"] -reports = ["lxml"] - -[[package]] -name = "mypy-extensions" -version = "1.0.0" -description = "Type system extensions for programs checked with the mypy type checker." -optional = false -python-versions = ">=3.5" -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 = "packaging" -version = "24.1" -description = "Core utilities for Python packages" -optional = false -python-versions = ">=3.8" -files = [ - {file = "packaging-24.1-py3-none-any.whl", hash = "sha256:5b8f2217dbdbd2f7f384c41c628544e6d52f2d0f53c6d0c3ea61aa5d1d7ff124"}, - {file = "packaging-24.1.tar.gz", hash = "sha256:026ed72c8ed3fcce5bf8950572258698927fd1dbda10a5e981cdf0ac37f4f002"}, -] - -[[package]] -name = "pathspec" -version = "0.12.1" -description = "Utility library for gitignore style pattern matching of file paths." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.2.2" -description = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -optional = false -python-versions = ">=3.8" -files = [ - {file = "platformdirs-4.2.2-py3-none-any.whl", hash = "sha256:2d7a1657e36a80ea911db832a8a6ece5ee53d8de21edd5cc5879af6530b1bfee"}, - {file = "platformdirs-4.2.2.tar.gz", hash = "sha256:38b7b51f512eed9e84a22788b4bce1de17c0adb134d6becb09836e37d8654cd3"}, -] - -[package.extras] -docs = ["furo (>=2023.9.10)", "proselint (>=0.13)", "sphinx (>=7.2.6)", "sphinx-autodoc-typehints (>=1.25.2)"] -test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4.3)", "pytest-cov (>=4.1)", "pytest-mock (>=3.12)"] -type = ["mypy (>=1.8)"] - -[[package]] -name = "pluggy" -version = "1.5.0" -description = "plugin and hook calling mechanisms for python" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, -] - -[package.extras] -dev = ["pre-commit", "tox"] -testing = ["pytest", "pytest-benchmark"] - -[[package]] -name = "pydantic" -version = "2.8.2" -description = "Data validation using Python type hints" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, - {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, -] - -[package.dependencies] -annotated-types = ">=0.4.0" -pydantic-core = "2.20.1" -typing-extensions = {version = ">=4.6.1", markers = "python_version < \"3.13\""} - -[package.extras] -email = ["email-validator (>=2.0.0)"] - -[[package]] -name = "pydantic-core" -version = "2.20.1" -description = "Core functionality for Pydantic validation and serialization" -optional = false -python-versions = ">=3.8" -files = [ - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, - {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, - {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, - {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, - {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, - {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, - {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, - {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, - {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, - {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, - {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, - {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, - {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, - {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, - {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, - {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, - {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, - {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, - {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, - {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, - {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, - {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, - {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, - {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, - {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, - {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, - {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, - {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, - {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, - {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, - {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, - {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, - {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, -] - -[package.dependencies] -typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" - -[[package]] -name = "pygments" -version = "2.18.0" -description = "Pygments is a syntax highlighting package written in Python." -optional = false -python-versions = ">=3.8" -files = [ - {file = "pygments-2.18.0-py3-none-any.whl", hash = "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a"}, - {file = "pygments-2.18.0.tar.gz", hash = "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199"}, -] - -[package.extras] -windows-terminal = ["colorama (>=0.4.6)"] - -[[package]] -name = "pylint" -version = "2.17.7" -description = "python code static checker" -optional = false -python-versions = ">=3.7.2" -files = [ - {file = "pylint-2.17.7-py3-none-any.whl", hash = "sha256:27a8d4c7ddc8c2f8c18aa0050148f89ffc09838142193fdbe98f172781a3ff87"}, - {file = "pylint-2.17.7.tar.gz", hash = "sha256:f4fcac7ae74cfe36bc8451e931d8438e4a476c20314b1101c458ad0f05191fad"}, -] - -[package.dependencies] -astroid = ">=2.15.8,<=2.17.0-dev0" -colorama = {version = ">=0.4.5", markers = "sys_platform == \"win32\""} -dill = [ - {version = ">=0.2", markers = "python_version < \"3.11\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\""}, -] -isort = ">=4.2.5,<6" -mccabe = ">=0.6,<0.8" -platformdirs = ">=2.2.0" -tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""} -tomlkit = ">=0.10.1" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[package.extras] -spelling = ["pyenchant (>=3.2,<4.0)"] -testutils = ["gitpython (>3)"] - -[[package]] -name = "pytest" -version = "7.4.4" -description = "pytest: simple powerful testing with Python" -optional = false -python-versions = ">=3.7" -files = [ - {file = "pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8"}, - {file = "pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280"}, -] - -[package.dependencies] -colorama = {version = "*", markers = "sys_platform == \"win32\""} -exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} -iniconfig = "*" -packaging = "*" -pluggy = ">=0.12,<2.0" -tomli = {version = ">=1.0.0", markers = "python_version < \"3.11\""} - -[package.extras] -testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "nose", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] - -[[package]] -name = "pytest-cov" -version = "3.0.0" -description = "Pytest plugin for measuring coverage." -optional = false -python-versions = ">=3.6" -files = [ - {file = "pytest-cov-3.0.0.tar.gz", hash = "sha256:e7f0f5b1617d2210a2cabc266dfe2f4c75a8d32fb89eafb7ad9d06f6d076d470"}, - {file = "pytest_cov-3.0.0-py3-none-any.whl", hash = "sha256:578d5d15ac4a25e5f961c938b85a05b09fdaae9deef3bb6de9a6e766622ca7a6"}, -] - -[package.dependencies] -coverage = {version = ">=5.2.1", extras = ["toml"]} -pytest = ">=4.6" - -[package.extras] -testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtualenv"] - -[[package]] -name = "python-json-logger" -version = "2.0.7" -description = "A python library adding a json log formatter" -optional = false -python-versions = ">=3.6" -files = [ - {file = "python-json-logger-2.0.7.tar.gz", hash = "sha256:23e7ec02d34237c5aa1e29a070193a4ea87583bb4e7f8fd06d3de8264c4b2e1c"}, - {file = "python_json_logger-2.0.7-py3-none-any.whl", hash = "sha256:f380b826a991ebbe3de4d897aeec42760035ac760345e57b812938dc8b35e2bd"}, -] - -[[package]] -name = "rich" -version = "13.7.1" -description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" -optional = false -python-versions = ">=3.7.0" -files = [ - {file = "rich-13.7.1-py3-none-any.whl", hash = "sha256:4edbae314f59eb482f54e9e30bf00d33350aaa94f4bfcd4e9e3110e64d0d7222"}, - {file = "rich-13.7.1.tar.gz", hash = "sha256:9be308cb1fe2f1f57d67ce99e95af38a1e2bc71ad9813b0e247cf7ffbcc3a432"}, -] - -[package.dependencies] -markdown-it-py = ">=2.2.0" -pygments = ">=2.13.0,<3.0.0" -typing-extensions = {version = ">=4.0.0,<5.0", markers = "python_version < \"3.9\""} - -[package.extras] -jupyter = ["ipywidgets (>=7.5.1,<9)"] - -[[package]] -name = "ruff" -version = "0.1.15" -description = "An extremely fast Python linter and code formatter, written in Rust." -optional = false -python-versions = ">=3.7" -files = [ - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:5fe8d54df166ecc24106db7dd6a68d44852d14eb0729ea4672bb4d96c320b7df"}, - {file = "ruff-0.1.15-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:6f0bfbb53c4b4de117ac4d6ddfd33aa5fc31beeaa21d23c45c6dd249faf9126f"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e0d432aec35bfc0d800d4f70eba26e23a352386be3a6cf157083d18f6f5881c8"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9405fa9ac0e97f35aaddf185a1be194a589424b8713e3b97b762336ec79ff807"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c66ec24fe36841636e814b8f90f572a8c0cb0e54d8b5c2d0e300d28a0d7bffec"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:6f8ad828f01e8dd32cc58bc28375150171d198491fc901f6f98d2a39ba8e3ff5"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:86811954eec63e9ea162af0ffa9f8d09088bab51b7438e8b6488b9401863c25e"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fd4025ac5e87d9b80e1f300207eb2fd099ff8200fa2320d7dc066a3f4622dc6b"}, - {file = "ruff-0.1.15-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b17b93c02cdb6aeb696effecea1095ac93f3884a49a554a9afa76bb125c114c1"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:ddb87643be40f034e97e97f5bc2ef7ce39de20e34608f3f829db727a93fb82c5"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:abf4822129ed3a5ce54383d5f0e964e7fef74a41e48eb1dfad404151efc130a2"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_i686.whl", hash = "sha256:6c629cf64bacfd136c07c78ac10a54578ec9d1bd2a9d395efbee0935868bf852"}, - {file = "ruff-0.1.15-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:1bab866aafb53da39c2cadfb8e1c4550ac5340bb40300083eb8967ba25481447"}, - {file = "ruff-0.1.15-py3-none-win32.whl", hash = "sha256:2417e1cb6e2068389b07e6fa74c306b2810fe3ee3476d5b8a96616633f40d14f"}, - {file = "ruff-0.1.15-py3-none-win_amd64.whl", hash = "sha256:3837ac73d869efc4182d9036b1405ef4c73d9b1f88da2413875e34e0d6919587"}, - {file = "ruff-0.1.15-py3-none-win_arm64.whl", hash = "sha256:9a933dfb1c14ec7a33cceb1e49ec4a16b51ce3c20fd42663198746efc0427360"}, - {file = "ruff-0.1.15.tar.gz", hash = "sha256:f6dfa8c1b21c913c326919056c390966648b680966febcb796cc9d1aaab8564e"}, -] - -[[package]] -name = "shellingham" -version = "1.5.4" -description = "Tool to Detect Surrounding Shell" -optional = false -python-versions = ">=3.7" -files = [ - {file = "shellingham-1.5.4-py2.py3-none-any.whl", hash = "sha256:7ecfff8f2fd72616f7481040475a65b2bf8af90a56c89140852d1120324e8686"}, - {file = "shellingham-1.5.4.tar.gz", hash = "sha256:8dbca0739d487e5bd35ab3ca4b36e11c4078f3a234bfce294b0a0291363404de"}, -] - -[[package]] -name = "smokeshow" -version = "0.4.0" -description = "Deploy ephemeral websites." -optional = false -python-versions = ">=3.8" -files = [ - {file = "smokeshow-0.4.0-py3-none-any.whl", hash = "sha256:472d975eeeae140d80cc7f289f6ed2e89190984fa12e2cdad67e929e2db48da6"}, - {file = "smokeshow-0.4.0.tar.gz", hash = "sha256:5c767c7a4753187aee065b090d6739cfabbbd04a9cd6648c23e450737d8a6191"}, -] - -[package.dependencies] -httpx = ">=0.24" -typer = ">=0.8.0" - -[[package]] -name = "sniffio" -version = "1.3.1" -description = "Sniff out which async library your code is running under" -optional = false -python-versions = ">=3.7" -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 = "starlette" -version = "0.36.3" -description = "The little ASGI library that shines." -optional = false -python-versions = ">=3.8" -files = [ - {file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"}, - {file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"}, -] - -[package.dependencies] -anyio = ">=3.4.0,<5" -typing-extensions = {version = ">=3.10.0", markers = "python_version < \"3.10\""} - -[package.extras] -full = ["httpx (>=0.22.0)", "itsdangerous", "jinja2", "python-multipart (>=0.0.7)", "pyyaml"] - -[[package]] -name = "tomli" -version = "2.0.1" -description = "A lil' TOML parser" -optional = false -python-versions = ">=3.7" -files = [ - {file = "tomli-2.0.1-py3-none-any.whl", hash = "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc"}, - {file = "tomli-2.0.1.tar.gz", hash = "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f"}, -] - -[[package]] -name = "tomlkit" -version = "0.13.0" -description = "Style preserving TOML library" -optional = false -python-versions = ">=3.8" -files = [ - {file = "tomlkit-0.13.0-py3-none-any.whl", hash = "sha256:7075d3042d03b80f603482d69bf0c8f345c2b30e41699fd8883227f89972b264"}, - {file = "tomlkit-0.13.0.tar.gz", hash = "sha256:08ad192699734149f5b97b45f1f18dad7eb1b6d16bc72ad0c2335772650d7b72"}, -] - -[[package]] -name = "typer" -version = "0.12.3" -description = "Typer, build great CLIs. Easy to code. Based on Python type hints." -optional = false -python-versions = ">=3.7" -files = [ - {file = "typer-0.12.3-py3-none-any.whl", hash = "sha256:070d7ca53f785acbccba8e7d28b08dcd88f79f1fbda035ade0aecec71ca5c914"}, - {file = "typer-0.12.3.tar.gz", hash = "sha256:49e73131481d804288ef62598d97a1ceef3058905aa536a1134f90891ba35482"}, -] - -[package.dependencies] -click = ">=8.0.0" -rich = ">=10.11.0" -shellingham = ">=1.3.0" -typing-extensions = ">=3.7.4.3" - -[[package]] -name = "typing-extensions" -version = "4.12.2" -description = "Backported and Experimental Type Hints for Python 3.8+" -optional = false -python-versions = ">=3.8" -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 = "uvicorn" -version = "0.23.2" -description = "The lightning-fast ASGI server." -optional = false -python-versions = ">=3.8" -files = [ - {file = "uvicorn-0.23.2-py3-none-any.whl", hash = "sha256:1f9be6558f01239d4fdf22ef8126c39cb1ad0addf76c40e760549d2c2f43ab53"}, - {file = "uvicorn-0.23.2.tar.gz", hash = "sha256:4d3cc12d7727ba72b64d12d3cc7743124074c0a69f7b201512fc50c3e3f1569a"}, -] - -[package.dependencies] -click = ">=7.0" -h11 = ">=0.8" -typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""} - -[package.extras] -standard = ["colorama (>=0.4)", "httptools (>=0.5.0)", "python-dotenv (>=0.13)", "pyyaml (>=5.1)", "uvloop (>=0.14.0,!=0.15.0,!=0.15.1)", "watchfiles (>=0.13)", "websockets (>=10.4)"] - -[[package]] -name = "wrapt" -version = "1.16.0" -description = "Module for decorators, wrappers and monkey patching." -optional = false -python-versions = ">=3.6" -files = [ - {file = "wrapt-1.16.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:ffa565331890b90056c01db69c0fe634a776f8019c143a5ae265f9c6bc4bd6d4"}, - {file = "wrapt-1.16.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:e4fdb9275308292e880dcbeb12546df7f3e0f96c6b41197e0cf37d2826359020"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb2dee3874a500de01c93d5c71415fcaef1d858370d405824783e7a8ef5db440"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2a88e6010048489cda82b1326889ec075a8c856c2e6a256072b28eaee3ccf487"}, - {file = "wrapt-1.16.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ac83a914ebaf589b69f7d0a1277602ff494e21f4c2f743313414378f8f50a4cf"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:73aa7d98215d39b8455f103de64391cb79dfcad601701a3aa0dddacf74911d72"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:807cc8543a477ab7422f1120a217054f958a66ef7314f76dd9e77d3f02cdccd0"}, - {file = "wrapt-1.16.0-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:bf5703fdeb350e36885f2875d853ce13172ae281c56e509f4e6eca049bdfb136"}, - {file = "wrapt-1.16.0-cp310-cp310-win32.whl", hash = "sha256:f6b2d0c6703c988d334f297aa5df18c45e97b0af3679bb75059e0e0bd8b1069d"}, - {file = "wrapt-1.16.0-cp310-cp310-win_amd64.whl", hash = "sha256:decbfa2f618fa8ed81c95ee18a387ff973143c656ef800c9f24fb7e9c16054e2"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1a5db485fe2de4403f13fafdc231b0dbae5eca4359232d2efc79025527375b09"}, - {file = "wrapt-1.16.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:75ea7d0ee2a15733684badb16de6794894ed9c55aa5e9903260922f0482e687d"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a452f9ca3e3267cd4d0fcf2edd0d035b1934ac2bd7e0e57ac91ad6b95c0c6389"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:43aa59eadec7890d9958748db829df269f0368521ba6dc68cc172d5d03ed8060"}, - {file = "wrapt-1.16.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:72554a23c78a8e7aa02abbd699d129eead8b147a23c56e08d08dfc29cfdddca1"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:d2efee35b4b0a347e0d99d28e884dfd82797852d62fcd7ebdeee26f3ceb72cf3"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:6dcfcffe73710be01d90cae08c3e548d90932d37b39ef83969ae135d36ef3956"}, - {file = "wrapt-1.16.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:eb6e651000a19c96f452c85132811d25e9264d836951022d6e81df2fff38337d"}, - {file = "wrapt-1.16.0-cp311-cp311-win32.whl", hash = "sha256:66027d667efe95cc4fa945af59f92c5a02c6f5bb6012bff9e60542c74c75c362"}, - {file = "wrapt-1.16.0-cp311-cp311-win_amd64.whl", hash = "sha256:aefbc4cb0a54f91af643660a0a150ce2c090d3652cf4052a5397fb2de549cd89"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5eb404d89131ec9b4f748fa5cfb5346802e5ee8836f57d516576e61f304f3b7b"}, - {file = "wrapt-1.16.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9090c9e676d5236a6948330e83cb89969f433b1943a558968f659ead07cb3b36"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:94265b00870aa407bd0cbcfd536f17ecde43b94fb8d228560a1e9d3041462d73"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f2058f813d4f2b5e3a9eb2eb3faf8f1d99b81c3e51aeda4b168406443e8ba809"}, - {file = "wrapt-1.16.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:98b5e1f498a8ca1858a1cdbffb023bfd954da4e3fa2c0cb5853d40014557248b"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:14d7dc606219cdd7405133c713f2c218d4252f2a469003f8c46bb92d5d095d81"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:49aac49dc4782cb04f58986e81ea0b4768e4ff197b57324dcbd7699c5dfb40b9"}, - {file = "wrapt-1.16.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:418abb18146475c310d7a6dc71143d6f7adec5b004ac9ce08dc7a34e2babdc5c"}, - {file = "wrapt-1.16.0-cp312-cp312-win32.whl", hash = "sha256:685f568fa5e627e93f3b52fda002c7ed2fa1800b50ce51f6ed1d572d8ab3e7fc"}, - {file = "wrapt-1.16.0-cp312-cp312-win_amd64.whl", hash = "sha256:dcdba5c86e368442528f7060039eda390cc4091bfd1dca41e8046af7c910dda8"}, - {file = "wrapt-1.16.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:d462f28826f4657968ae51d2181a074dfe03c200d6131690b7d65d55b0f360f8"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a33a747400b94b6d6b8a165e4480264a64a78c8a4c734b62136062e9a248dd39"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b3646eefa23daeba62643a58aac816945cadc0afaf21800a1421eeba5f6cfb9c"}, - {file = "wrapt-1.16.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ebf019be5c09d400cf7b024aa52b1f3aeebeff51550d007e92c3c1c4afc2a40"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_aarch64.whl", hash = "sha256:0d2691979e93d06a95a26257adb7bfd0c93818e89b1406f5a28f36e0d8c1e1fc"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_i686.whl", hash = "sha256:1acd723ee2a8826f3d53910255643e33673e1d11db84ce5880675954183ec47e"}, - {file = "wrapt-1.16.0-cp36-cp36m-musllinux_1_1_x86_64.whl", hash = "sha256:bc57efac2da352a51cc4658878a68d2b1b67dbe9d33c36cb826ca449d80a8465"}, - {file = "wrapt-1.16.0-cp36-cp36m-win32.whl", hash = "sha256:da4813f751142436b075ed7aa012a8778aa43a99f7b36afe9b742d3ed8bdc95e"}, - {file = "wrapt-1.16.0-cp36-cp36m-win_amd64.whl", hash = "sha256:6f6eac2360f2d543cc875a0e5efd413b6cbd483cb3ad7ebf888884a6e0d2e966"}, - {file = "wrapt-1.16.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:a0ea261ce52b5952bf669684a251a66df239ec6d441ccb59ec7afa882265d593"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7bd2d7ff69a2cac767fbf7a2b206add2e9a210e57947dd7ce03e25d03d2de292"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9159485323798c8dc530a224bd3ffcf76659319ccc7bbd52e01e73bd0241a0c5"}, - {file = "wrapt-1.16.0-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a86373cf37cd7764f2201b76496aba58a52e76dedfaa698ef9e9688bfd9e41cf"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:73870c364c11f03ed072dda68ff7aea6d2a3a5c3fe250d917a429c7432e15228"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:b935ae30c6e7400022b50f8d359c03ed233d45b725cfdd299462f41ee5ffba6f"}, - {file = "wrapt-1.16.0-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:db98ad84a55eb09b3c32a96c576476777e87c520a34e2519d3e59c44710c002c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win32.whl", hash = "sha256:9153ed35fc5e4fa3b2fe97bddaa7cbec0ed22412b85bcdaf54aeba92ea37428c"}, - {file = "wrapt-1.16.0-cp37-cp37m-win_amd64.whl", hash = "sha256:66dfbaa7cfa3eb707bbfcd46dab2bc6207b005cbc9caa2199bcbc81d95071a00"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:1dd50a2696ff89f57bd8847647a1c363b687d3d796dc30d4dd4a9d1689a706f0"}, - {file = "wrapt-1.16.0-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:44a2754372e32ab315734c6c73b24351d06e77ffff6ae27d2ecf14cf3d229202"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8e9723528b9f787dc59168369e42ae1c3b0d3fadb2f1a71de14531d321ee05b0"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:dbed418ba5c3dce92619656802cc5355cb679e58d0d89b50f116e4a9d5a9603e"}, - {file = "wrapt-1.16.0-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:941988b89b4fd6b41c3f0bfb20e92bd23746579736b7343283297c4c8cbae68f"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:6a42cd0cfa8ffc1915aef79cb4284f6383d8a3e9dcca70c445dcfdd639d51267"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:1ca9b6085e4f866bd584fb135a041bfc32cab916e69f714a7d1d397f8c4891ca"}, - {file = "wrapt-1.16.0-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:d5e49454f19ef621089e204f862388d29e6e8d8b162efce05208913dde5b9ad6"}, - {file = "wrapt-1.16.0-cp38-cp38-win32.whl", hash = "sha256:c31f72b1b6624c9d863fc095da460802f43a7c6868c5dda140f51da24fd47d7b"}, - {file = "wrapt-1.16.0-cp38-cp38-win_amd64.whl", hash = "sha256:490b0ee15c1a55be9c1bd8609b8cecd60e325f0575fc98f50058eae366e01f41"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9b201ae332c3637a42f02d1045e1d0cccfdc41f1f2f801dafbaa7e9b4797bfc2"}, - {file = "wrapt-1.16.0-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2076fad65c6736184e77d7d4729b63a6d1ae0b70da4868adeec40989858eb3fb"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c5cd603b575ebceca7da5a3a251e69561bec509e0b46e4993e1cac402b7247b8"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b47cfad9e9bbbed2339081f4e346c93ecd7ab504299403320bf85f7f85c7d46c"}, - {file = "wrapt-1.16.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f8212564d49c50eb4565e502814f694e240c55551a5f1bc841d4fcaabb0a9b8a"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:5f15814a33e42b04e3de432e573aa557f9f0f56458745c2074952f564c50e664"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:db2e408d983b0e61e238cf579c09ef7020560441906ca990fe8412153e3b291f"}, - {file = "wrapt-1.16.0-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:edfad1d29c73f9b863ebe7082ae9321374ccb10879eeabc84ba3b69f2579d537"}, - {file = "wrapt-1.16.0-cp39-cp39-win32.whl", hash = "sha256:ed867c42c268f876097248e05b6117a65bcd1e63b779e916fe2e33cd6fd0d3c3"}, - {file = "wrapt-1.16.0-cp39-cp39-win_amd64.whl", hash = "sha256:eb1b046be06b0fce7249f1d025cd359b4b80fc1c3e24ad9eca33e0dcdb2e4a35"}, - {file = "wrapt-1.16.0-py3-none-any.whl", hash = "sha256:6906c4100a8fcbf2fa735f6059214bb13b97f75b1a61777fcf6432121ef12ef1"}, - {file = "wrapt-1.16.0.tar.gz", hash = "sha256:5f370f952971e7d17c7d1ead40e49f32345a7f7a5373571ef44d800d06b1899d"}, -] - -[metadata] -lock-version = "2.0" -python-versions = ">=3.8,<3.13" -content-hash = "dd0e6170c529b64cb1d5e84a7944c73c5ca71eea49e0bcd71b5c7ece0bc1df58" diff --git a/py-logger/Cargo.toml b/py-logger/Cargo.toml new file mode 100644 index 0000000..a30f87c --- /dev/null +++ b/py-logger/Cargo.toml @@ -0,0 +1,12 @@ +[package] +name = "py-rusty-logger" +version = { workspace = true } +edition = "2021" + +[lib] +name = "py_rusty_logger" +crate-type = ["cdylib", "rlib"] + +[dependencies] +rusty-logger = { workspace = true } +pyo3 = { workspace = true } diff --git a/py-logger/README.md b/py-logger/README.md new file mode 100644 index 0000000..61d6391 --- /dev/null +++ b/py-logger/README.md @@ -0,0 +1,153 @@ + +

+rusty logger logo +

+ +# Attention + +## This crate/library is currently undergoing re-writes. + + +[![Lints-Tests](https://github.com/thorrester/rusty-logger/actions/workflows/lint-testing.yml/badge.svg?branch=main)](https://github.com/thorrester/rusty-logger/actions/workflows/lint-testing.yml) +[![codecov](https://codecov.io/gh/thorrester/rusty-logger/graph/badge.svg?token=RVDMQRUEHT)](https://codecov.io/gh/thorrester/rusty-logger) + +## Rusty Logger + +Simple, opinionated and fast python logging. `Rusty-Logger` is a thin python wrapper for `Rust's` `tracing` library that provides a *mostly* drop-in replacement for `python's` default logging. + +## Table of contents + +- [Attention](#attention) + - [This crate/library is currently undergoing re-writes.](#this-cratelibrary-is-currently-undergoing-re-writes) + - [Rusty Logger](#rusty-logger) + - [Table of contents](#table-of-contents) + - [Supported Configuration](#supported-configuration) + - [Constraints](#constraints) + - [Show Me The Code!](#show-me-the-code) + - [Basic Usage](#basic-usage) + - [JSON](#json) + - [Log to file](#log-to-file) + - [Record multiple places at once](#record-multiple-places-at-once) + - [Additional examples](#additional-examples) + - [Performance](#performance) + - [Contributing](#contributing) + +## Supported Configuration + +| Arg | Description | Default | +| ------------- | :-------------:| :-------------: | +| `stdout` | Log to stdout | `True` | +| `stderr` | Log to stderr | `False` | +| `level` | Level to log | `INFO` | +| `app_env` | Application environment (APP_ENV env var) | `development` | +| `lock_guard` | Whether to lock logger to current context | `False` | +| `thread_id` | Whether to display the thread id | `False` | +| `color` | Whether to enable ansi coloring of logs for standard logger | `False` | +| `time_format` | Custom time format for logger | `[year]-[month]-[day]T[hour repr:24]:[minute]:[second]::[subsecond digits:4]` | +| `json_config` | `JsonConig` | `None` | +| `json_config.flatten` | Whether to flatten any passed fields | `True` | +| `file_config` | `LogFileConfig` | `None` | +| `file_config.filename` | Filename for log | `log/logs.log` | +| `file_config.rotate` | File rotation specification. `daily`, `hourly`, `minutely` or `never` | `never` | + +## Constraints + +Time is currently limited to UTC; however, you can customize time format to your liking using the `time_format` arg. Please refer to (time docs)[https://time-rs.github.io/book/api/format-description.html] for formatting guidelines. In addition, because `Rusty-Logger` calls `Rust` directly, it's not currently possible to pull the specific line number where logging takes place unless python is directly used (if you're even interested in this feature :smile:). If you'd like to see this feature implemented, and you want to contribute, please refer to the [contributing](https://github.com/thorrester/rusty-logger/blob/main/CONTRIBUTING.md) guide. + +In addition, `Rusty-Logger` is a *mostly* drop-in replacement, meaning that you may need to make some minor changes to your existing code. For example, `Rusty-Logger` does not support current python lazy formatting (e.g. `logger.info("Number: %s", 10)`). Instead, `Rusty-Logger` uses Rust's default bracket ({}) formatting. + +```python +# This is not supported +logger.info("Number: %s", 10) + +# This is supported +logger.info("Number: {}", 10) +``` + +## Show Me The Code! + +### Basic Usage + +```python +from rusty_logger import Logger + +logger = Logger.get_logger(__file__) +logger.info("Loggy McLogface") +``` + +output +```shell +2023-10-18T00:11:43::3194 INFO Loggy McLogface app_env="development" name="your_file.py" +``` + +### JSON + +```python +from rusty_logger import Logger, LogConfig, JsonConfig + +logger = Logger.get_logger(__file__, LogConfig(json_config=JsonConfig())) +logger.info("Loggy McLogface logs") +``` + +output +```shell +{"timestamp":"2023-10-18T00:10:59::9732","level":"INFO","message":"Loggy McLogface logs","app_env":"development","name":"your_file.py"} +``` + +### Log to file + +```python +from rusty_logger import Logger, LogConfig, JsonConfig, LogLevel, LogFileConfig + +logger = Logger.get_logger( + name=__file__, + config=LogConfig( + stdout=False, + level=LogLevel.WARN, + json_config=JsonConfig(), + file_config=LogFileConfig(filename="logs/test.log"), + ), +) +logger.warning("Loggy McLogface logs logs") +``` + +output from `log/test.log` +```shell +{"timestamp":"2023-10-18T00:10:10::9364","level":"WARN","message":"Loggy McLogface logs logs","app_env":"development","name":"your_file.py"} + +``` + + +### Record multiple places at once + +```python +from rusty_logger import Logger, LogConfig, JsonConfig, LogMetadata, LogLevel, LogFileConfig + +logger = Logger.get_logger( + __file__, + LogConfig( + stdout=True, + level=LogLevel.ERROR, + json_config=JsonConfig(), + file_config=LogFileConfig(filename="logs/test.log") + ), +) +logger.error("Loggy McLogface logs logs that are logs") +``` + +output +```shell +{"timestamp":"2023-10-18T00:09:32::4053","level":"ERROR","message":"Loggy McLogface logs logs that are logs","app_env":"development","name":"your_file.py"} +``` +## Additional examples + +For additional examples, please see the [examples](https://github.com/thorrester/rusty-logger/tree/main/examples) directory which contains timed example of vanilla logger vs `Rusty-Logger`, `python-json-logger` vs `Rusty-Logger` as well as a multi-worker API example. + +## Performance +Why would we do this when python logging is fine? Because we wanted something faster :smile:. From our own benchmarks, `Rusty-Logger` tends to be ~`4x` faster than vanilla python logging and ~`8x` faster than vanilla `JSON` logging. And while speed may not be mission critical for a few thousands logs, it can be for millions, which many companies deal with on a daily basis. Time is money and compute, and we want to save you both :moneybag: :computer:. + +## Contributing +While `Rusty-Logger` is production ready out of the box, it is still in it's infancy and is ripe for additional contributions. If you'd like to contribute, please see the [contributing](https://github.com/thorrester/rusty-logger/blob/main/CONTRIBUTING.md) guide. + + +Thank You!!! :heart: :heart: :heart: diff --git a/py-logger/makefile b/py-logger/makefile new file mode 100644 index 0000000..2551a32 --- /dev/null +++ b/py-logger/makefile @@ -0,0 +1,33 @@ +PROJECT=rusty-logger +PYTHON_VERSION=3.12.8 +SOURCE_OBJECTS=python/rusty_logger + +format.isort: + uv run isort ${SOURCE_OBJECTS} +format.black: + uv run black ${SOURCE_OBJECTS} +format.ruff: + uv run ruff check --silent --exit-zero ${SOURCE_OBJECTS} +format: format.isort format.ruff format.black + +lints.format_check: + uv run black --check ${SOURCE_OBJECTS} +lints.ruff: + uv run ruff check ${SOURCE_OBJECTS} +lints.mypy: + uv run mypy ${SOURCE_OBJECTS} +lints.pylint: + uv run pylint ${SOURCE_OBJECTS} +lints: lints.ruff lints.pylint lints.mypy +lints.ci: lints.format_check lints.ruff lints.pylint lints.mypy + +setup.project: + uv sync --all-extras --group dev + uv run maturin develop --uv + +test.unit: + uv run pytest \ + --cov \ + --cov-fail-under=0 \ + --cov-report xml:./coverage.xml \ + --cov-report term \ No newline at end of file diff --git a/py-logger/pyproject.toml b/py-logger/pyproject.toml new file mode 100644 index 0000000..2748dc9 --- /dev/null +++ b/py-logger/pyproject.toml @@ -0,0 +1,93 @@ +[project] +name = "rusty-logger" +requires-python = ">=3.10" +classifiers = [ + "Programming Language :: Rust", + "Programming Language :: Python :: Implementation :: CPython", + "Programming Language :: Python :: Implementation :: PyPy", +] +version = "0.4.0" +description = "" +authors = [{name = "Thorrester", email = ""}] +readme = "README.md" + +[dependency-groups] +dev = [ + "maturin >= 1.4.0, < 2.0.0", + "pytest >= 7.0.0, < 8.0.0", + "pytest-cov >= 5.0.0, < 6.0.0", + "ruff >= 0.1.0, < 1.0.0", + "mypy >= 1.0.0, < 2.0.0", + "black >= 24.3.0, < 25.0.0", + "pylint >= 3.0.0, < 4.0.0", + "isort >= 5.13.2, < 6.0.0", +] + +[tool.isort] +profile = "black" + +[tool.black] +line-length = 120 +target-version = ['py310'] +include = '\.pyi?$' + +[tool.pylint.MASTER] +load-plugins = ["pylint.extensions.docparams"] + +[tool.pylint.messages_control] +max-line-length = 130 +disable = [ + "too-few-public-methods", + "design", + "duplicate-code", + "missing-class-docstring", + "missing-function-docstring", + "missing-module-docstring", + "too-many-nested-blocks", + "unused-argument", + "fixme", + "import-outside-toplevel", + "import-self", + "too-many-lines", +] + +[tool.flake8] +# This section is just a doc placeholder..see setup.cfg +max-complexity = 10 +format = "pylint" +statistics = "True" +max-line-length = 125 +# ignore non-PEP8 lints +ignore = ["E203", "W503", "W0511"] + +[tool.pytest.ini_options] +log_cli = true +log_cli_level = "INFO" +testpaths = ["tests"] + +[tool.coverage.run] +omit = [ + "tests/*", +] + +[tool.mypy] +# platform configuration +python_version = "3.12" +platform = "linux" +mypy_path = "stubs" +ignore_missing_imports = true +exclude = [] + +[build-system] +requires = ["maturin>=1.4,<2.0"] +build-backend = "maturin" + +[tool.maturin] +python-source = "python" +module-name = "rusty_logger.rusty_logger" +bindings = 'pyo3' +features = ["pyo3/extension-module"] + +[tool.uv] +package = false + diff --git a/tests/__init__.py b/py-logger/python/py.typed similarity index 100% rename from tests/__init__.py rename to py-logger/python/py.typed diff --git a/py-logger/python/rusty_logger/__init__.py b/py-logger/python/rusty_logger/__init__.py new file mode 100644 index 0000000..95f30c4 --- /dev/null +++ b/py-logger/python/rusty_logger/__init__.py @@ -0,0 +1,14 @@ +# type: ignore +# pylint: disable=no-name-in-module + + +from .rusty_logger import LoggingConfig, LogLevel, RustyLogger, WriteLevel +from .version import __version__ + +__all__ = [ + "RustyLogger", + "LogLevel", + "LoggingConfig", + "WriteLevel", + "__version__", +] diff --git a/py-logger/python/rusty_logger/rusty_logger.pyi b/py-logger/python/rusty_logger/rusty_logger.pyi new file mode 100644 index 0000000..d72dfce --- /dev/null +++ b/py-logger/python/rusty_logger/rusty_logger.pyi @@ -0,0 +1,118 @@ +from typing import Optional + +class LogLevel: + Debug: "LogLevel" + Info: "LogLevel" + Warn: "LogLevel" + Error: "LogLevel" + Trace: "LogLevel" + +class WriteLevel: + Stdout: "WriteLevel" + Stderr: "WriteLevel" + +class LoggingConfig: + show_threads: bool + log_level: LogLevel + write_level: WriteLevel + use_json: bool + + def __init__( + self, + show_threads: Optional[bool] = False, + log_level: Optional[LogLevel] = LogLevel.Info, + write_level: Optional[WriteLevel] = WriteLevel.Stdout, + use_json: Optional[bool] = False, + ) -> None: + """Initializes the LoggingConfig. + + Args: + show_threads (Optional[bool]): + Whether to show thread information in the logs. Defaults to False. + log_level (Optional[LogLevel]): + The log level to use. Defaults to LogLevel.Info. + write_level (Optional[WriteLevel]): + The write level to use. Defaults to WriteLevel.Stdout. + use_json (Optional[bool]): + Whether to use JSON format for logs. Defaults to False. + """ + +class RustyLogger: + """The Rusty Logger class to use with your python and rust-backed projects.""" + + @staticmethod + def setup_logging(config: Optional[LoggingConfig] = None) -> None: + """Sets up the logger with the given configuration. + + Args: + config (LoggingConfig): + The configuration to use for the logger. + """ + + @staticmethod + def get_logger(config: Optional[LoggingConfig] = None) -> "RustyLogger": + """Gets the logger instance. + + Args: + config (LoggingConfig): + The configuration to use for the logger. + + Returns: + RustyLogger: + The logger instance. + """ + + def debug(self, message: str, *args) -> None: + """Logs a debug message. + + Args: + message (str): + The message to log. + + *args: + Additional arguments to log. + """ + + def info(self, message: str, *args) -> None: + """Logs an info message. + + Args: + message (str): + The message to log. + + *args: + Additional arguments to log. + """ + + def warn(self, message: str, *args) -> None: + """Logs a warning message. + + Args: + message (str): + The message to log. + + *args: + Additional arguments to log. + """ + + def error(self, message: str, *args) -> None: + """Logs an error message. + + Args: + message (str): + The message to log. + + *args: + Additional arguments to log. + """ + + def trace(self, message: str, *args) -> None: + """Logs a trace message. + + Args: + message (str): + The message to log. + + *args: + Additional arguments to log. + """ diff --git a/python/rusty_logger/version.py b/py-logger/python/rusty_logger/version.py similarity index 62% rename from python/rusty_logger/version.py rename to py-logger/python/rusty_logger/version.py index c4272ad..7c71606 100644 --- a/python/rusty_logger/version.py +++ b/py-logger/python/rusty_logger/version.py @@ -1,5 +1,4 @@ -from importlib.metadata import version, PackageNotFoundError - +from importlib.metadata import PackageNotFoundError, version try: __version__ = version("rusty_logger") diff --git a/py-logger/src/lib.rs b/py-logger/src/lib.rs new file mode 100644 index 0000000..458778c --- /dev/null +++ b/py-logger/src/lib.rs @@ -0,0 +1,12 @@ +use ::rusty_logger::logger::{LogLevel, LoggingConfig, RustyLogger, WriteLevel}; +use pyo3::prelude::*; +/// Python implementation for the Rusty Logger +/// +#[pymodule] +fn rusty_logger(m: &Bound<'_, PyModule>) -> PyResult<()> { + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + m.add_class::()?; + Ok(()) +} diff --git a/tests/color_logger.py b/py-logger/tests/__init__.py similarity index 100% rename from tests/color_logger.py rename to py-logger/tests/__init__.py diff --git a/py-logger/tests/test_logger.py b/py-logger/tests/test_logger.py new file mode 100644 index 0000000..11c70d0 --- /dev/null +++ b/py-logger/tests/test_logger.py @@ -0,0 +1,24 @@ +from rusty_logger import RustyLogger, LoggingConfig # type: ignore + + +def test_config(): + LoggingConfig() + + +def test_logger(): + logger = RustyLogger.get_logger() + logger.debug("Debug message") + logger.info("Info message") + logger.warn("Warning message") + logger.error("Error message") + logger.trace("Trace message") + + +def test_json_logger(): + config = LoggingConfig(use_json=True) + logger = RustyLogger.get_logger(config) + logger.debug("Debug message") + logger.info("Info message") + logger.warn("Warning message") + logger.error("Error message") + logger.trace("Trace message") diff --git a/py-logger/uv.lock b/py-logger/uv.lock new file mode 100644 index 0000000..da391a6 --- /dev/null +++ b/py-logger/uv.lock @@ -0,0 +1,451 @@ +version = 1 +requires-python = ">=3.10" +resolution-markers = [ + "python_full_version < '3.11'", + "python_full_version == '3.11.*'", + "python_full_version >= '3.12'", +] + +[[package]] +name = "astroid" +version = "3.3.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/c5/5c83c48bbf547f3dd8b587529db7cf5a265a3368b33e85e76af8ff6061d3/astroid-3.3.8.tar.gz", hash = "sha256:a88c7994f914a4ea8572fac479459f4955eeccc877be3f2d959a33273b0cf40b", size = 398196 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/07/28/0bc8a17d6cd4cc3c79ae41b7105a2b9a327c110e5ddd37a8a27b29a5c8a2/astroid-3.3.8-py3-none-any.whl", hash = "sha256:187ccc0c248bfbba564826c26f070494f7bc964fd286b6d9fff4420e55de828c", size = 275153 }, +] + +[[package]] +name = "black" +version = "24.10.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "click" }, + { name = "mypy-extensions" }, + { name = "packaging" }, + { name = "pathspec" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/d8/0d/cc2fb42b8c50d80143221515dd7e4766995bd07c56c9a3ed30baf080b6dc/black-24.10.0.tar.gz", hash = "sha256:846ea64c97afe3bc677b761787993be4991810ecc7a4a937816dd6bddedc4875", size = 645813 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/a3/f3/465c0eb5cddf7dbbfe1fecd9b875d1dcf51b88923cd2c1d7e9ab95c6336b/black-24.10.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:e6668650ea4b685440857138e5fe40cde4d652633b1bdffc62933d0db4ed9812", size = 1623211 }, + { url = "https://files.pythonhosted.org/packages/df/57/b6d2da7d200773fdfcc224ffb87052cf283cec4d7102fab450b4a05996d8/black-24.10.0-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1c536fcf674217e87b8cc3657b81809d3c085d7bf3ef262ead700da345bfa6ea", size = 1457139 }, + { url = "https://files.pythonhosted.org/packages/6e/c5/9023b7673904a5188f9be81f5e129fff69f51f5515655fbd1d5a4e80a47b/black-24.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:649fff99a20bd06c6f727d2a27f401331dc0cc861fb69cde910fe95b01b5928f", size = 1753774 }, + { url = "https://files.pythonhosted.org/packages/e1/32/df7f18bd0e724e0d9748829765455d6643ec847b3f87e77456fc99d0edab/black-24.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:fe4d6476887de70546212c99ac9bd803d90b42fc4767f058a0baa895013fbb3e", size = 1414209 }, + { url = "https://files.pythonhosted.org/packages/c2/cc/7496bb63a9b06a954d3d0ac9fe7a73f3bf1cd92d7a58877c27f4ad1e9d41/black-24.10.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5a2221696a8224e335c28816a9d331a6c2ae15a2ee34ec857dcf3e45dbfa99ad", size = 1607468 }, + { url = "https://files.pythonhosted.org/packages/2b/e3/69a738fb5ba18b5422f50b4f143544c664d7da40f09c13969b2fd52900e0/black-24.10.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:f9da3333530dbcecc1be13e69c250ed8dfa67f43c4005fb537bb426e19200d50", size = 1437270 }, + { url = "https://files.pythonhosted.org/packages/c9/9b/2db8045b45844665c720dcfe292fdaf2e49825810c0103e1191515fc101a/black-24.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4007b1393d902b48b36958a216c20c4482f601569d19ed1df294a496eb366392", size = 1737061 }, + { url = "https://files.pythonhosted.org/packages/a3/95/17d4a09a5be5f8c65aa4a361444d95edc45def0de887810f508d3f65db7a/black-24.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:394d4ddc64782e51153eadcaaca95144ac4c35e27ef9b0a42e121ae7e57a9175", size = 1423293 }, + { url = "https://files.pythonhosted.org/packages/90/04/bf74c71f592bcd761610bbf67e23e6a3cff824780761f536512437f1e655/black-24.10.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b5e39e0fae001df40f95bd8cc36b9165c5e2ea88900167bddf258bacef9bbdc3", size = 1644256 }, + { url = "https://files.pythonhosted.org/packages/4c/ea/a77bab4cf1887f4b2e0bce5516ea0b3ff7d04ba96af21d65024629afedb6/black-24.10.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d37d422772111794b26757c5b55a3eade028aa3fde43121ab7b673d050949d65", size = 1448534 }, + { url = "https://files.pythonhosted.org/packages/4e/3e/443ef8bc1fbda78e61f79157f303893f3fddf19ca3c8989b163eb3469a12/black-24.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:14b3502784f09ce2443830e3133dacf2c0110d45191ed470ecb04d0f5f6fcb0f", size = 1761892 }, + { url = "https://files.pythonhosted.org/packages/52/93/eac95ff229049a6901bc84fec6908a5124b8a0b7c26ea766b3b8a5debd22/black-24.10.0-cp312-cp312-win_amd64.whl", hash = "sha256:30d2c30dc5139211dda799758559d1b049f7f14c580c409d6ad925b74a4208a8", size = 1434796 }, + { url = "https://files.pythonhosted.org/packages/d0/a0/a993f58d4ecfba035e61fca4e9f64a2ecae838fc9f33ab798c62173ed75c/black-24.10.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:1cbacacb19e922a1d75ef2b6ccaefcd6e93a2c05ede32f06a21386a04cedb981", size = 1643986 }, + { url = "https://files.pythonhosted.org/packages/37/d5/602d0ef5dfcace3fb4f79c436762f130abd9ee8d950fa2abdbf8bbc555e0/black-24.10.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:1f93102e0c5bb3907451063e08b9876dbeac810e7da5a8bfb7aeb5a9ef89066b", size = 1448085 }, + { url = "https://files.pythonhosted.org/packages/47/6d/a3a239e938960df1a662b93d6230d4f3e9b4a22982d060fc38c42f45a56b/black-24.10.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ddacb691cdcdf77b96f549cf9591701d8db36b2f19519373d60d31746068dbf2", size = 1760928 }, + { url = "https://files.pythonhosted.org/packages/dd/cf/af018e13b0eddfb434df4d9cd1b2b7892bab119f7a20123e93f6910982e8/black-24.10.0-cp313-cp313-win_amd64.whl", hash = "sha256:680359d932801c76d2e9c9068d05c6b107f2584b2a5b88831c83962eb9984c1b", size = 1436875 }, + { url = "https://files.pythonhosted.org/packages/8d/a7/4b27c50537ebca8bec139b872861f9d2bf501c5ec51fcf897cb924d9e264/black-24.10.0-py3-none-any.whl", hash = "sha256:3bb2b7a1f7b685f85b11fed1ef10f8a9148bceb49853e47a294a3dd963c1dd7d", size = 206898 }, +] + +[[package]] +name = "click" +version = "8.1.8" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "platform_system == 'Windows'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/2e/0090cbf739cee7d23781ad4b89a9894a41538e4fcf4c31dcdd705b78eb8b/click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a", size = 226593 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/7e/d4/7ebdbd03970677812aac39c869717059dbb71a4cfc033ca6e5221787892c/click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2", size = 98188 }, +] + +[[package]] +name = "colorama" +version = "0.4.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d8/53/6f443c9a4a8358a93a6792e2acffb9d9d5cb0a5cfd8802644b7b1c9a02e4/colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44", size = 27697 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/d6/3965ed04c63042e047cb6a3e6ed1a63a35087b6a609aa3a15ed8ac56c221/colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6", size = 25335 }, +] + +[[package]] +name = "coverage" +version = "7.6.10" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/84/ba/ac14d281f80aab516275012e8875991bb06203957aa1e19950139238d658/coverage-7.6.10.tar.gz", hash = "sha256:7fb105327c8f8f0682e29843e2ff96af9dcbe5bab8eeb4b398c6a33a16d80a23", size = 803868 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/c5/12/2a2a923edf4ddabdffed7ad6da50d96a5c126dae7b80a33df7310e329a1e/coverage-7.6.10-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:5c912978f7fbf47ef99cec50c4401340436d200d41d714c7a4766f377c5b7b78", size = 207982 }, + { url = "https://files.pythonhosted.org/packages/ca/49/6985dbca9c7be3f3cb62a2e6e492a0c88b65bf40579e16c71ae9c33c6b23/coverage-7.6.10-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a01ec4af7dfeb96ff0078ad9a48810bb0cc8abcb0115180c6013a6b26237626c", size = 208414 }, + { url = "https://files.pythonhosted.org/packages/35/93/287e8f1d1ed2646f4e0b2605d14616c9a8a2697d0d1b453815eb5c6cebdb/coverage-7.6.10-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a3b204c11e2b2d883946fe1d97f89403aa1811df28ce0447439178cc7463448a", size = 236860 }, + { url = "https://files.pythonhosted.org/packages/de/e1/cfdb5627a03567a10031acc629b75d45a4ca1616e54f7133ca1fa366050a/coverage-7.6.10-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:32ee6d8491fcfc82652a37109f69dee9a830e9379166cb73c16d8dc5c2915165", size = 234758 }, + { url = "https://files.pythonhosted.org/packages/6d/85/fc0de2bcda3f97c2ee9fe8568f7d48f7279e91068958e5b2cc19e0e5f600/coverage-7.6.10-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:675cefc4c06e3b4c876b85bfb7c59c5e2218167bbd4da5075cbe3b5790a28988", size = 235920 }, + { url = "https://files.pythonhosted.org/packages/79/73/ef4ea0105531506a6f4cf4ba571a214b14a884630b567ed65b3d9c1975e1/coverage-7.6.10-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:f4f620668dbc6f5e909a0946a877310fb3d57aea8198bde792aae369ee1c23b5", size = 234986 }, + { url = "https://files.pythonhosted.org/packages/c6/4d/75afcfe4432e2ad0405c6f27adeb109ff8976c5e636af8604f94f29fa3fc/coverage-7.6.10-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:4eea95ef275de7abaef630c9b2c002ffbc01918b726a39f5a4353916ec72d2f3", size = 233446 }, + { url = "https://files.pythonhosted.org/packages/86/5b/efee56a89c16171288cafff022e8af44f8f94075c2d8da563c3935212871/coverage-7.6.10-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e2f0280519e42b0a17550072861e0bc8a80a0870de260f9796157d3fca2733c5", size = 234566 }, + { url = "https://files.pythonhosted.org/packages/f2/db/67770cceb4a64d3198bf2aa49946f411b85ec6b0a9b489e61c8467a4253b/coverage-7.6.10-cp310-cp310-win32.whl", hash = "sha256:bc67deb76bc3717f22e765ab3e07ee9c7a5e26b9019ca19a3b063d9f4b874244", size = 210675 }, + { url = "https://files.pythonhosted.org/packages/8d/27/e8bfc43f5345ec2c27bc8a1fa77cdc5ce9dcf954445e11f14bb70b889d14/coverage-7.6.10-cp310-cp310-win_amd64.whl", hash = "sha256:0f460286cb94036455e703c66988851d970fdfd8acc2a1122ab7f4f904e4029e", size = 211518 }, + { url = "https://files.pythonhosted.org/packages/85/d2/5e175fcf6766cf7501a8541d81778fd2f52f4870100e791f5327fd23270b/coverage-7.6.10-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:ea3c8f04b3e4af80e17bab607c386a830ffc2fb88a5484e1df756478cf70d1d3", size = 208088 }, + { url = "https://files.pythonhosted.org/packages/4b/6f/06db4dc8fca33c13b673986e20e466fd936235a6ec1f0045c3853ac1b593/coverage-7.6.10-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:507a20fc863cae1d5720797761b42d2d87a04b3e5aeb682ef3b7332e90598f43", size = 208536 }, + { url = "https://files.pythonhosted.org/packages/0d/62/c6a0cf80318c1c1af376d52df444da3608eafc913b82c84a4600d8349472/coverage-7.6.10-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d37a84878285b903c0fe21ac8794c6dab58150e9359f1aaebbeddd6412d53132", size = 240474 }, + { url = "https://files.pythonhosted.org/packages/a3/59/750adafc2e57786d2e8739a46b680d4fb0fbc2d57fbcb161290a9f1ecf23/coverage-7.6.10-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a534738b47b0de1995f85f582d983d94031dffb48ab86c95bdf88dc62212142f", size = 237880 }, + { url = "https://files.pythonhosted.org/packages/2c/f8/ef009b3b98e9f7033c19deb40d629354aab1d8b2d7f9cfec284dbedf5096/coverage-7.6.10-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0d7a2bf79378d8fb8afaa994f91bfd8215134f8631d27eba3e0e2c13546ce994", size = 239750 }, + { url = "https://files.pythonhosted.org/packages/a6/e2/6622f3b70f5f5b59f705e680dae6db64421af05a5d1e389afd24dae62e5b/coverage-7.6.10-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:6713ba4b4ebc330f3def51df1d5d38fad60b66720948112f114968feb52d3f99", size = 238642 }, + { url = "https://files.pythonhosted.org/packages/2d/10/57ac3f191a3c95c67844099514ff44e6e19b2915cd1c22269fb27f9b17b6/coverage-7.6.10-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ab32947f481f7e8c763fa2c92fd9f44eeb143e7610c4ca9ecd6a36adab4081bd", size = 237266 }, + { url = "https://files.pythonhosted.org/packages/ee/2d/7016f4ad9d553cabcb7333ed78ff9d27248ec4eba8dd21fa488254dff894/coverage-7.6.10-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7bbd8c8f1b115b892e34ba66a097b915d3871db7ce0e6b9901f462ff3a975377", size = 238045 }, + { url = "https://files.pythonhosted.org/packages/a7/fe/45af5c82389a71e0cae4546413266d2195c3744849669b0bab4b5f2c75da/coverage-7.6.10-cp311-cp311-win32.whl", hash = "sha256:299e91b274c5c9cdb64cbdf1b3e4a8fe538a7a86acdd08fae52301b28ba297f8", size = 210647 }, + { url = "https://files.pythonhosted.org/packages/db/11/3f8e803a43b79bc534c6a506674da9d614e990e37118b4506faf70d46ed6/coverage-7.6.10-cp311-cp311-win_amd64.whl", hash = "sha256:489a01f94aa581dbd961f306e37d75d4ba16104bbfa2b0edb21d29b73be83609", size = 211508 }, + { url = "https://files.pythonhosted.org/packages/86/77/19d09ea06f92fdf0487499283b1b7af06bc422ea94534c8fe3a4cd023641/coverage-7.6.10-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:27c6e64726b307782fa5cbe531e7647aee385a29b2107cd87ba7c0105a5d3853", size = 208281 }, + { url = "https://files.pythonhosted.org/packages/b6/67/5479b9f2f99fcfb49c0d5cf61912a5255ef80b6e80a3cddba39c38146cf4/coverage-7.6.10-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c56e097019e72c373bae32d946ecf9858fda841e48d82df7e81c63ac25554078", size = 208514 }, + { url = "https://files.pythonhosted.org/packages/15/d1/febf59030ce1c83b7331c3546d7317e5120c5966471727aa7ac157729c4b/coverage-7.6.10-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c7827a5bc7bdb197b9e066cdf650b2887597ad124dd99777332776f7b7c7d0d0", size = 241537 }, + { url = "https://files.pythonhosted.org/packages/4b/7e/5ac4c90192130e7cf8b63153fe620c8bfd9068f89a6d9b5f26f1550f7a26/coverage-7.6.10-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:204a8238afe787323a8b47d8be4df89772d5c1e4651b9ffa808552bdf20e1d50", size = 238572 }, + { url = "https://files.pythonhosted.org/packages/dc/03/0334a79b26ecf59958f2fe9dd1f5ab3e2f88db876f5071933de39af09647/coverage-7.6.10-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e67926f51821b8e9deb6426ff3164870976fe414d033ad90ea75e7ed0c2e5022", size = 240639 }, + { url = "https://files.pythonhosted.org/packages/d7/45/8a707f23c202208d7b286d78ad6233f50dcf929319b664b6cc18a03c1aae/coverage-7.6.10-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:e78b270eadb5702938c3dbe9367f878249b5ef9a2fcc5360ac7bff694310d17b", size = 240072 }, + { url = "https://files.pythonhosted.org/packages/66/02/603ce0ac2d02bc7b393279ef618940b4a0535b0868ee791140bda9ecfa40/coverage-7.6.10-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:714f942b9c15c3a7a5fe6876ce30af831c2ad4ce902410b7466b662358c852c0", size = 238386 }, + { url = "https://files.pythonhosted.org/packages/04/62/4e6887e9be060f5d18f1dd58c2838b2d9646faf353232dec4e2d4b1c8644/coverage-7.6.10-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:abb02e2f5a3187b2ac4cd46b8ced85a0858230b577ccb2c62c81482ca7d18852", size = 240054 }, + { url = "https://files.pythonhosted.org/packages/5c/74/83ae4151c170d8bd071924f212add22a0e62a7fe2b149edf016aeecad17c/coverage-7.6.10-cp312-cp312-win32.whl", hash = "sha256:55b201b97286cf61f5e76063f9e2a1d8d2972fc2fcfd2c1272530172fd28c359", size = 210904 }, + { url = "https://files.pythonhosted.org/packages/c3/54/de0893186a221478f5880283119fc40483bc460b27c4c71d1b8bba3474b9/coverage-7.6.10-cp312-cp312-win_amd64.whl", hash = "sha256:e4ae5ac5e0d1e4edfc9b4b57b4cbecd5bc266a6915c500f358817a8496739247", size = 211692 }, + { url = "https://files.pythonhosted.org/packages/25/6d/31883d78865529257bf847df5789e2ae80e99de8a460c3453dbfbe0db069/coverage-7.6.10-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:05fca8ba6a87aabdd2d30d0b6c838b50510b56cdcfc604d40760dae7153b73d9", size = 208308 }, + { url = "https://files.pythonhosted.org/packages/70/22/3f2b129cc08de00c83b0ad6252e034320946abfc3e4235c009e57cfeee05/coverage-7.6.10-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9e80eba8801c386f72e0712a0453431259c45c3249f0009aff537a517b52942b", size = 208565 }, + { url = "https://files.pythonhosted.org/packages/97/0a/d89bc2d1cc61d3a8dfe9e9d75217b2be85f6c73ebf1b9e3c2f4e797f4531/coverage-7.6.10-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a372c89c939d57abe09e08c0578c1d212e7a678135d53aa16eec4430adc5e690", size = 241083 }, + { url = "https://files.pythonhosted.org/packages/4c/81/6d64b88a00c7a7aaed3a657b8eaa0931f37a6395fcef61e53ff742b49c97/coverage-7.6.10-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ec22b5e7fe7a0fa8509181c4aac1db48f3dd4d3a566131b313d1efc102892c18", size = 238235 }, + { url = "https://files.pythonhosted.org/packages/9a/0b/7797d4193f5adb4b837207ed87fecf5fc38f7cc612b369a8e8e12d9fa114/coverage-7.6.10-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26bcf5c4df41cad1b19c84af71c22cbc9ea9a547fc973f1f2cc9a290002c8b3c", size = 240220 }, + { url = "https://files.pythonhosted.org/packages/65/4d/6f83ca1bddcf8e51bf8ff71572f39a1c73c34cf50e752a952c34f24d0a60/coverage-7.6.10-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4e4630c26b6084c9b3cb53b15bd488f30ceb50b73c35c5ad7871b869cb7365fd", size = 239847 }, + { url = "https://files.pythonhosted.org/packages/30/9d/2470df6aa146aff4c65fee0f87f58d2164a67533c771c9cc12ffcdb865d5/coverage-7.6.10-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2396e8116db77789f819d2bc8a7e200232b7a282c66e0ae2d2cd84581a89757e", size = 237922 }, + { url = "https://files.pythonhosted.org/packages/08/dd/723fef5d901e6a89f2507094db66c091449c8ba03272861eaefa773ad95c/coverage-7.6.10-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:79109c70cc0882e4d2d002fe69a24aa504dec0cc17169b3c7f41a1d341a73694", size = 239783 }, + { url = "https://files.pythonhosted.org/packages/3d/f7/64d3298b2baf261cb35466000628706ce20a82d42faf9b771af447cd2b76/coverage-7.6.10-cp313-cp313-win32.whl", hash = "sha256:9e1747bab246d6ff2c4f28b4d186b205adced9f7bd9dc362051cc37c4a0c7bd6", size = 210965 }, + { url = "https://files.pythonhosted.org/packages/d5/58/ec43499a7fc681212fe7742fe90b2bc361cdb72e3181ace1604247a5b24d/coverage-7.6.10-cp313-cp313-win_amd64.whl", hash = "sha256:254f1a3b1eef5f7ed23ef265eaa89c65c8c5b6b257327c149db1ca9d4a35f25e", size = 211719 }, + { url = "https://files.pythonhosted.org/packages/ab/c9/f2857a135bcff4330c1e90e7d03446b036b2363d4ad37eb5e3a47bbac8a6/coverage-7.6.10-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:2ccf240eb719789cedbb9fd1338055de2761088202a9a0b73032857e53f612fe", size = 209050 }, + { url = "https://files.pythonhosted.org/packages/aa/b3/f840e5bd777d8433caa9e4a1eb20503495709f697341ac1a8ee6a3c906ad/coverage-7.6.10-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:0c807ca74d5a5e64427c8805de15b9ca140bba13572d6d74e262f46f50b13273", size = 209321 }, + { url = "https://files.pythonhosted.org/packages/85/7d/125a5362180fcc1c03d91850fc020f3831d5cda09319522bcfa6b2b70be7/coverage-7.6.10-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2bcfa46d7709b5a7ffe089075799b902020b62e7ee56ebaed2f4bdac04c508d8", size = 252039 }, + { url = "https://files.pythonhosted.org/packages/a9/9c/4358bf3c74baf1f9bddd2baf3756b54c07f2cfd2535f0a47f1e7757e54b3/coverage-7.6.10-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4e0de1e902669dccbf80b0415fb6b43d27edca2fbd48c74da378923b05316098", size = 247758 }, + { url = "https://files.pythonhosted.org/packages/cf/c7/de3eb6fc5263b26fab5cda3de7a0f80e317597a4bad4781859f72885f300/coverage-7.6.10-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3f7b444c42bbc533aaae6b5a2166fd1a797cdb5eb58ee51a92bee1eb94a1e1cb", size = 250119 }, + { url = "https://files.pythonhosted.org/packages/3e/e6/43de91f8ba2ec9140c6a4af1102141712949903dc732cf739167cfa7a3bc/coverage-7.6.10-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:b330368cb99ef72fcd2dc3ed260adf67b31499584dc8a20225e85bfe6f6cfed0", size = 249597 }, + { url = "https://files.pythonhosted.org/packages/08/40/61158b5499aa2adf9e37bc6d0117e8f6788625b283d51e7e0c53cf340530/coverage-7.6.10-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:9a7cfb50515f87f7ed30bc882f68812fd98bc2852957df69f3003d22a2aa0abf", size = 247473 }, + { url = "https://files.pythonhosted.org/packages/50/69/b3f2416725621e9f112e74e8470793d5b5995f146f596f133678a633b77e/coverage-7.6.10-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:6f93531882a5f68c28090f901b1d135de61b56331bba82028489bc51bdd818d2", size = 248737 }, + { url = "https://files.pythonhosted.org/packages/3c/6e/fe899fb937657db6df31cc3e61c6968cb56d36d7326361847440a430152e/coverage-7.6.10-cp313-cp313t-win32.whl", hash = "sha256:89d76815a26197c858f53c7f6a656686ec392b25991f9e409bcef020cd532312", size = 211611 }, + { url = "https://files.pythonhosted.org/packages/1c/55/52f5e66142a9d7bc93a15192eba7a78513d2abf6b3558d77b4ca32f5f424/coverage-7.6.10-cp313-cp313t-win_amd64.whl", hash = "sha256:54a5f0f43950a36312155dae55c505a76cd7f2b12d26abeebbe7a0b36dbc868d", size = 212781 }, + { url = "https://files.pythonhosted.org/packages/a1/70/de81bfec9ed38a64fc44a77c7665e20ca507fc3265597c28b0d989e4082e/coverage-7.6.10-pp39.pp310-none-any.whl", hash = "sha256:fd34e7b3405f0cc7ab03d54a334c17a9e802897580d964bd8c2001f4b9fd488f", size = 200223 }, +] + +[package.optional-dependencies] +toml = [ + { name = "tomli", marker = "python_full_version <= '3.11'" }, +] + +[[package]] +name = "dill" +version = "0.3.9" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/70/43/86fe3f9e130c4137b0f1b50784dd70a5087b911fe07fa81e53e0c4c47fea/dill-0.3.9.tar.gz", hash = "sha256:81aa267dddf68cbfe8029c42ca9ec6a4ab3b22371d1c450abc54422577b4512c", size = 187000 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/46/d1/e73b6ad76f0b1fb7f23c35c6d95dbc506a9c8804f43dda8cb5b0fa6331fd/dill-0.3.9-py3-none-any.whl", hash = "sha256:468dff3b89520b474c0397703366b7b95eebe6303f108adf9b19da1f702be87a", size = 119418 }, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/09/35/2495c4ac46b980e4ca1f6ad6db102322ef3ad2410b79fdde159a4b0f3b92/exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc", size = 28883 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/02/cc/b7e31358aac6ed1ef2bb790a9746ac2c69bcb3c8588b41616914eb106eaf/exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b", size = 16453 }, +] + +[[package]] +name = "iniconfig" +version = "2.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d7/4b/cbd8e699e64a6f16ca3a8220661b5f83792b3017d0f79807cb8708d33913/iniconfig-2.0.0.tar.gz", hash = "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", size = 4646 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/ef/a6/62565a6e1cf69e10f5727360368e451d4b7f58beeac6173dc9db836a5b46/iniconfig-2.0.0-py3-none-any.whl", hash = "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374", size = 5892 }, +] + +[[package]] +name = "isort" +version = "5.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/87/f9/c1eb8635a24e87ade2efce21e3ce8cd6b8630bb685ddc9cdaca1349b2eb5/isort-5.13.2.tar.gz", hash = "sha256:48fdfcb9face5d58a4f6dde2e72a1fb8dcaf8ab26f95ab49fab84c2ddefb0109", size = 175303 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/d1/b3/8def84f539e7d2289a02f0524b944b15d7c75dab7628bedf1c4f0992029c/isort-5.13.2-py3-none-any.whl", hash = "sha256:8ca5e72a8d85860d5a3fa69b8745237f2939afe12dbf656afbcb47fe72d947a6", size = 92310 }, +] + +[[package]] +name = "maturin" +version = "1.8.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/9a/08/ccb0f917722a35ab0d758be9bb5edaf645c3a3d6170061f10d396ecd273f/maturin-1.8.1.tar.gz", hash = "sha256:49cd964aabf59f8b0a6969f9860d2cdf194ac331529caae14c884f5659568857", size = 197397 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/4c/00/f34077315f34db8ad2ccf6bfe11b864ca27baab3a1320634da8e3cf89a48/maturin-1.8.1-py3-none-linux_armv6l.whl", hash = "sha256:7e590a23d9076b8a994f2e67bc63dc9a2d1c9a41b1e7b45ac354ba8275254e89", size = 7568415 }, + { url = "https://files.pythonhosted.org/packages/5c/07/9219976135ce0cb32d2fa6ea5c6d0ad709013d9a17967312e149b98153a6/maturin-1.8.1-py3-none-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:8d8251a95682c83ea60988c804b620c181911cd824aa107b4a49ac5333c92968", size = 14527816 }, + { url = "https://files.pythonhosted.org/packages/e6/04/fa009a00903acdd1785d58322193140bfe358595347c39f315112dabdf9e/maturin-1.8.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9fc1a4354cac5e32c190410208039812ea88c4a36bd2b6499268ec49ef5de00", size = 7580446 }, + { url = "https://files.pythonhosted.org/packages/9b/d4/414b2aab9bbfe88182b734d3aa1b4fef7d7701e50f6be48500378b8c8721/maturin-1.8.1-py3-none-manylinux_2_12_i686.manylinux2010_i686.musllinux_1_1_i686.whl", hash = "sha256:621e171c6b39f95f1d0df69a118416034fbd59c0f89dcaea8c2ea62019deecba", size = 7650535 }, + { url = "https://files.pythonhosted.org/packages/f0/64/879418a8a0196013ec1fb19eada0781c04a30e8d6d9227e80f91275a4f5b/maturin-1.8.1-py3-none-manylinux_2_12_x86_64.manylinux2010_x86_64.musllinux_1_1_x86_64.whl", hash = "sha256:98f638739a5132962347871b85c91f525c9246ef4d99796ae98a2031e3df029f", size = 8006702 }, + { url = "https://files.pythonhosted.org/packages/39/c2/605829324f8371294f70303aca130682df75318958efed246873d3d604ab/maturin-1.8.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.musllinux_1_1_aarch64.whl", hash = "sha256:f9f5c47521924b6e515cbc652a042fe5f17f8747445be9d931048e5d8ddb50a4", size = 7368164 }, + { url = "https://files.pythonhosted.org/packages/be/6c/30e136d397bb146b94b628c0ef7f17708281611b97849e2cf37847025ac7/maturin-1.8.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.musllinux_1_1_armv7l.whl", hash = "sha256:0f4407c7353c31bfbb8cdeb82bc2170e474cbfb97b5ba27568f440c9d6c1fdd4", size = 7450889 }, + { url = "https://files.pythonhosted.org/packages/1b/50/e1f5023512696d4e56096f702e2f68d6d9a30afe0a4eec82b0e27b8eb4e4/maturin-1.8.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.musllinux_1_1_ppc64le.whl", hash = "sha256:ec49cd70cad3c389946c6e2bc0bd50772a7fcb463040dd800720345897eec9bf", size = 9585819 }, + { url = "https://files.pythonhosted.org/packages/b7/80/b24b5248d89d2e5982553900237a337ea098ca9297b8369ca2aa95549e0f/maturin-1.8.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c08767d794de8f8a11c5c8b1b47a4ff9fb6ae2d2d97679e27030f2f509c8c2a0", size = 10920801 }, + { url = "https://files.pythonhosted.org/packages/6e/f4/8ede7a662fabf93456b44390a5ad22630e25fb5ddaecf787251071b2e143/maturin-1.8.1-py3-none-win32.whl", hash = "sha256:d678407713f3e10df33c5b3d7a343ec0551eb7f14d8ad9ba6febeb96f4e4c75c", size = 6873556 }, + { url = "https://files.pythonhosted.org/packages/9c/22/757f093ed0e319e9648155b8c9d716765442bea5bc98ebc58ad4ad5b0524/maturin-1.8.1-py3-none-win_amd64.whl", hash = "sha256:a526f90fe0e5cb59ffb81f4ff547ddc42e823bbdeae4a31012c0893ca6dcaf46", size = 7823153 }, + { url = "https://files.pythonhosted.org/packages/a4/f5/051413e04f6da25069db5e76759ecdb8cd2a8ab4a94045b5a3bf548c66fa/maturin-1.8.1-py3-none-win_arm64.whl", hash = "sha256:e95f077fd2ddd2f048182880eed458c308571a534be3eb2add4d3dac55bf57f4", size = 6552131 }, +] + +[[package]] +name = "mccabe" +version = "0.7.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/e7/ff/0ffefdcac38932a54d2b5eed4e0ba8a408f215002cd178ad1df0f2806ff8/mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325", size = 9658 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/27/1a/1f68f9ba0c207934b35b86a8ca3aad8395a3d6dd7921c0686e23853ff5a9/mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e", size = 7350 }, +] + +[[package]] +name = "mypy" +version = "1.14.1" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "mypy-extensions" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "typing-extensions" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/b9/eb/2c92d8ea1e684440f54fa49ac5d9a5f19967b7b472a281f419e69a8d228e/mypy-1.14.1.tar.gz", hash = "sha256:7ec88144fe9b510e8475ec2f5f251992690fcf89ccb4500b214b4226abcd32d6", size = 3216051 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/9b/7a/87ae2adb31d68402da6da1e5f30c07ea6063e9f09b5e7cfc9dfa44075e74/mypy-1.14.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:52686e37cf13d559f668aa398dd7ddf1f92c5d613e4f8cb262be2fb4fedb0fcb", size = 11211002 }, + { url = "https://files.pythonhosted.org/packages/e1/23/eada4c38608b444618a132be0d199b280049ded278b24cbb9d3fc59658e4/mypy-1.14.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1fb545ca340537d4b45d3eecdb3def05e913299ca72c290326be19b3804b39c0", size = 10358400 }, + { url = "https://files.pythonhosted.org/packages/43/c9/d6785c6f66241c62fd2992b05057f404237deaad1566545e9f144ced07f5/mypy-1.14.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:90716d8b2d1f4cd503309788e51366f07c56635a3309b0f6a32547eaaa36a64d", size = 12095172 }, + { url = "https://files.pythonhosted.org/packages/c3/62/daa7e787770c83c52ce2aaf1a111eae5893de9e004743f51bfcad9e487ec/mypy-1.14.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2ae753f5c9fef278bcf12e1a564351764f2a6da579d4a81347e1d5a15819997b", size = 12828732 }, + { url = "https://files.pythonhosted.org/packages/1b/a2/5fb18318a3637f29f16f4e41340b795da14f4751ef4f51c99ff39ab62e52/mypy-1.14.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:e0fe0f5feaafcb04505bcf439e991c6d8f1bf8b15f12b05feeed96e9e7bf1427", size = 13012197 }, + { url = "https://files.pythonhosted.org/packages/28/99/e153ce39105d164b5f02c06c35c7ba958aaff50a2babba7d080988b03fe7/mypy-1.14.1-cp310-cp310-win_amd64.whl", hash = "sha256:7d54bd85b925e501c555a3227f3ec0cfc54ee8b6930bd6141ec872d1c572f81f", size = 9780836 }, + { url = "https://files.pythonhosted.org/packages/da/11/a9422850fd506edbcdc7f6090682ecceaf1f87b9dd847f9df79942da8506/mypy-1.14.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f995e511de847791c3b11ed90084a7a0aafdc074ab88c5a9711622fe4751138c", size = 11120432 }, + { url = "https://files.pythonhosted.org/packages/b6/9e/47e450fd39078d9c02d620545b2cb37993a8a8bdf7db3652ace2f80521ca/mypy-1.14.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d64169ec3b8461311f8ce2fd2eb5d33e2d0f2c7b49116259c51d0d96edee48d1", size = 10279515 }, + { url = "https://files.pythonhosted.org/packages/01/b5/6c8d33bd0f851a7692a8bfe4ee75eb82b6983a3cf39e5e32a5d2a723f0c1/mypy-1.14.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ba24549de7b89b6381b91fbc068d798192b1b5201987070319889e93038967a8", size = 12025791 }, + { url = "https://files.pythonhosted.org/packages/f0/4c/e10e2c46ea37cab5c471d0ddaaa9a434dc1d28650078ac1b56c2d7b9b2e4/mypy-1.14.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:183cf0a45457d28ff9d758730cd0210419ac27d4d3f285beda038c9083363b1f", size = 12749203 }, + { url = "https://files.pythonhosted.org/packages/88/55/beacb0c69beab2153a0f57671ec07861d27d735a0faff135a494cd4f5020/mypy-1.14.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:f2a0ecc86378f45347f586e4163d1769dd81c5a223d577fe351f26b179e148b1", size = 12885900 }, + { url = "https://files.pythonhosted.org/packages/a2/75/8c93ff7f315c4d086a2dfcde02f713004357d70a163eddb6c56a6a5eff40/mypy-1.14.1-cp311-cp311-win_amd64.whl", hash = "sha256:ad3301ebebec9e8ee7135d8e3109ca76c23752bac1e717bc84cd3836b4bf3eae", size = 9777869 }, + { url = "https://files.pythonhosted.org/packages/43/1b/b38c079609bb4627905b74fc6a49849835acf68547ac33d8ceb707de5f52/mypy-1.14.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:30ff5ef8519bbc2e18b3b54521ec319513a26f1bba19a7582e7b1f58a6e69f14", size = 11266668 }, + { url = "https://files.pythonhosted.org/packages/6b/75/2ed0d2964c1ffc9971c729f7a544e9cd34b2cdabbe2d11afd148d7838aa2/mypy-1.14.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:cb9f255c18052343c70234907e2e532bc7e55a62565d64536dbc7706a20b78b9", size = 10254060 }, + { url = "https://files.pythonhosted.org/packages/a1/5f/7b8051552d4da3c51bbe8fcafffd76a6823779101a2b198d80886cd8f08e/mypy-1.14.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8b4e3413e0bddea671012b063e27591b953d653209e7a4fa5e48759cda77ca11", size = 11933167 }, + { url = "https://files.pythonhosted.org/packages/04/90/f53971d3ac39d8b68bbaab9a4c6c58c8caa4d5fd3d587d16f5927eeeabe1/mypy-1.14.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:553c293b1fbdebb6c3c4030589dab9fafb6dfa768995a453d8a5d3b23784af2e", size = 12864341 }, + { url = "https://files.pythonhosted.org/packages/03/d2/8bc0aeaaf2e88c977db41583559319f1821c069e943ada2701e86d0430b7/mypy-1.14.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:fad79bfe3b65fe6a1efaed97b445c3d37f7be9fdc348bdb2d7cac75579607c89", size = 12972991 }, + { url = "https://files.pythonhosted.org/packages/6f/17/07815114b903b49b0f2cf7499f1c130e5aa459411596668267535fe9243c/mypy-1.14.1-cp312-cp312-win_amd64.whl", hash = "sha256:8fa2220e54d2946e94ab6dbb3ba0a992795bd68b16dc852db33028df2b00191b", size = 9879016 }, + { url = "https://files.pythonhosted.org/packages/9e/15/bb6a686901f59222275ab228453de741185f9d54fecbaacec041679496c6/mypy-1.14.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:92c3ed5afb06c3a8e188cb5da4984cab9ec9a77ba956ee419c68a388b4595255", size = 11252097 }, + { url = "https://files.pythonhosted.org/packages/f8/b3/8b0f74dfd072c802b7fa368829defdf3ee1566ba74c32a2cb2403f68024c/mypy-1.14.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:dbec574648b3e25f43d23577309b16534431db4ddc09fda50841f1e34e64ed34", size = 10239728 }, + { url = "https://files.pythonhosted.org/packages/c5/9b/4fd95ab20c52bb5b8c03cc49169be5905d931de17edfe4d9d2986800b52e/mypy-1.14.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8c6d94b16d62eb3e947281aa7347d78236688e21081f11de976376cf010eb31a", size = 11924965 }, + { url = "https://files.pythonhosted.org/packages/56/9d/4a236b9c57f5d8f08ed346914b3f091a62dd7e19336b2b2a0d85485f82ff/mypy-1.14.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:d4b19b03fdf54f3c5b2fa474c56b4c13c9dbfb9a2db4370ede7ec11a2c5927d9", size = 12867660 }, + { url = "https://files.pythonhosted.org/packages/40/88/a61a5497e2f68d9027de2bb139c7bb9abaeb1be1584649fa9d807f80a338/mypy-1.14.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:0c911fde686394753fff899c409fd4e16e9b294c24bfd5e1ea4675deae1ac6fd", size = 12969198 }, + { url = "https://files.pythonhosted.org/packages/54/da/3d6fc5d92d324701b0c23fb413c853892bfe0e1dbe06c9138037d459756b/mypy-1.14.1-cp313-cp313-win_amd64.whl", hash = "sha256:8b21525cb51671219f5307be85f7e646a153e5acc656e5cebf64bfa076c50107", size = 9885276 }, + { url = "https://files.pythonhosted.org/packages/a0/b5/32dd67b69a16d088e533962e5044e51004176a9952419de0370cdaead0f8/mypy-1.14.1-py3-none-any.whl", hash = "sha256:b66a60cc4073aeb8ae00057f9c1f64d49e90f918fbcef9a977eb121da8b8f1d1", size = 2752905 }, +] + +[[package]] +name = "mypy-extensions" +version = "1.0.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/98/a4/1ab47638b92648243faf97a5aeb6ea83059cc3624972ab6b8d2316078d3f/mypy_extensions-1.0.0.tar.gz", hash = "sha256:75dbf8955dc00442a438fc4d0666508a9a97b6bd41aa2f0ffe9d2f2725af0782", size = 4433 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/2a/e2/5d3f6ada4297caebe1a2add3b126fe800c96f56dbe5d1988a2cbe0b267aa/mypy_extensions-1.0.0-py3-none-any.whl", hash = "sha256:4392f6c0eb8a5668a69e23d168ffa70f0be9ccfd32b5cc2d26a34ae5b844552d", size = 4695 }, +] + +[[package]] +name = "packaging" +version = "24.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/d0/63/68dbb6eb2de9cb10ee4c9c14a0148804425e13c4fb20d61cce69f53106da/packaging-24.2.tar.gz", hash = "sha256:c228a6dc5e932d346bc5739379109d49e8853dd8223571c7c5b55260edc0b97f", size = 163950 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/ef/eb23f262cca3c0c4eb7ab1933c3b1f03d021f2c48f54763065b6f0e321be/packaging-24.2-py3-none-any.whl", hash = "sha256:09abb1bccd265c01f4a3aa3f7a7db064b36514d2cba19a2f694fe6150451a759", size = 65451 }, +] + +[[package]] +name = "pathspec" +version = "0.12.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/ca/bc/f35b8446f4531a7cb215605d100cd88b7ac6f44ab3fc94870c120ab3adbf/pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712", size = 51043 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/cc/20/ff623b09d963f88bfde16306a54e12ee5ea43e9b597108672ff3a408aad6/pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08", size = 31191 }, +] + +[[package]] +name = "platformdirs" +version = "4.3.6" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/13/fc/128cc9cb8f03208bdbf93d3aa862e16d376844a14f9a0ce5cf4507372de4/platformdirs-4.3.6.tar.gz", hash = "sha256:357fb2acbc885b0419afd3ce3ed34564c13c9b95c89360cd9563f73aa5e2b907", size = 21302 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/3c/a6/bc1012356d8ece4d66dd75c4b9fc6c1f6650ddd5991e421177d9f8f671be/platformdirs-4.3.6-py3-none-any.whl", hash = "sha256:73e575e1408ab8103900836b97580d5307456908a03e92031bab39e4554cc3fb", size = 18439 }, +] + +[[package]] +name = "pluggy" +version = "1.5.0" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/96/2d/02d4312c973c6050a18b314a5ad0b3210edb65a906f868e31c111dede4a6/pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1", size = 67955 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/88/5f/e351af9a41f866ac3f1fac4ca0613908d9a41741cfcf2228f4ad853b697d/pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669", size = 20556 }, +] + +[[package]] +name = "pylint" +version = "3.3.3" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "astroid" }, + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "dill" }, + { name = "isort" }, + { name = "mccabe" }, + { name = "platformdirs" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, + { name = "tomlkit" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/17/fd/e9a739afac274a39596bbe562e9d966db6f3917fdb2bd7322ffc56da0ba2/pylint-3.3.3.tar.gz", hash = "sha256:07c607523b17e6d16e2ae0d7ef59602e332caa762af64203c24b41c27139f36a", size = 1516550 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/91/e1/26d55acea92b1ea4d33672e48f09ceeb274e84d7d542a4fb9a32a556db46/pylint-3.3.3-py3-none-any.whl", hash = "sha256:26e271a2bc8bce0fc23833805a9076dd9b4d5194e2a02164942cb3cdc37b4183", size = 521918 }, +] + +[[package]] +name = "pytest" +version = "7.4.4" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "colorama", marker = "sys_platform == 'win32'" }, + { name = "exceptiongroup", marker = "python_full_version < '3.11'" }, + { name = "iniconfig" }, + { name = "packaging" }, + { name = "pluggy" }, + { name = "tomli", marker = "python_full_version < '3.11'" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/80/1f/9d8e98e4133ffb16c90f3b405c43e38d3abb715bb5d7a63a5a684f7e46a3/pytest-7.4.4.tar.gz", hash = "sha256:2cf0005922c6ace4a3e2ec8b4080eb0d9753fdc93107415332f50ce9e7994280", size = 1357116 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/51/ff/f6e8b8f39e08547faece4bd80f89d5a8de68a38b2d179cc1c4490ffa3286/pytest-7.4.4-py3-none-any.whl", hash = "sha256:b090cdf5ed60bf4c45261be03239c2c1c22df034fbffe691abe93cd80cea01d8", size = 325287 }, +] + +[[package]] +name = "pytest-cov" +version = "5.0.0" +source = { registry = "https://pypi.org/simple" } +dependencies = [ + { name = "coverage", extra = ["toml"] }, + { name = "pytest" }, +] +sdist = { url = "https://files.pythonhosted.org/packages/74/67/00efc8d11b630c56f15f4ad9c7f9223f1e5ec275aaae3fa9118c6a223ad2/pytest-cov-5.0.0.tar.gz", hash = "sha256:5837b58e9f6ebd335b0f8060eecce69b662415b16dc503883a02f45dfeb14857", size = 63042 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/78/3a/af5b4fa5961d9a1e6237b530eb87dd04aea6eb83da09d2a4073d81b54ccf/pytest_cov-5.0.0-py3-none-any.whl", hash = "sha256:4f0764a1219df53214206bf1feea4633c3b558a2925c8b59f144f682861ce652", size = 21990 }, +] + +[[package]] +name = "ruff" +version = "0.9.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/80/63/77ecca9d21177600f551d1c58ab0e5a0b260940ea7312195bd2a4798f8a8/ruff-0.9.2.tar.gz", hash = "sha256:b5eceb334d55fae5f316f783437392642ae18e16dcf4f1858d55d3c2a0f8f5d0", size = 3553799 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/af/b9/0e168e4e7fb3af851f739e8f07889b91d1a33a30fca8c29fa3149d6b03ec/ruff-0.9.2-py3-none-linux_armv6l.whl", hash = "sha256:80605a039ba1454d002b32139e4970becf84b5fee3a3c3bf1c2af6f61a784347", size = 11652408 }, + { url = "https://files.pythonhosted.org/packages/2c/22/08ede5db17cf701372a461d1cb8fdde037da1d4fa622b69ac21960e6237e/ruff-0.9.2-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:b9aab82bb20afd5f596527045c01e6ae25a718ff1784cb92947bff1f83068b00", size = 11587553 }, + { url = "https://files.pythonhosted.org/packages/42/05/dedfc70f0bf010230229e33dec6e7b2235b2a1b8cbb2a991c710743e343f/ruff-0.9.2-py3-none-macosx_11_0_arm64.whl", hash = "sha256:fbd337bac1cfa96be615f6efcd4bc4d077edbc127ef30e2b8ba2a27e18c054d4", size = 11020755 }, + { url = "https://files.pythonhosted.org/packages/df/9b/65d87ad9b2e3def67342830bd1af98803af731243da1255537ddb8f22209/ruff-0.9.2-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:82b35259b0cbf8daa22a498018e300b9bb0174c2bbb7bcba593935158a78054d", size = 11826502 }, + { url = "https://files.pythonhosted.org/packages/93/02/f2239f56786479e1a89c3da9bc9391120057fc6f4a8266a5b091314e72ce/ruff-0.9.2-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8b6a9701d1e371bf41dca22015c3f89769da7576884d2add7317ec1ec8cb9c3c", size = 11390562 }, + { url = "https://files.pythonhosted.org/packages/c9/37/d3a854dba9931f8cb1b2a19509bfe59e00875f48ade632e95aefcb7a0aee/ruff-0.9.2-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9cc53e68b3c5ae41e8faf83a3b89f4a5d7b2cb666dff4b366bb86ed2a85b481f", size = 12548968 }, + { url = "https://files.pythonhosted.org/packages/fa/c3/c7b812bb256c7a1d5553433e95980934ffa85396d332401f6b391d3c4569/ruff-0.9.2-py3-none-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:8efd9da7a1ee314b910da155ca7e8953094a7c10d0c0a39bfde3fcfd2a015684", size = 13187155 }, + { url = "https://files.pythonhosted.org/packages/bd/5a/3c7f9696a7875522b66aa9bba9e326e4e5894b4366bd1dc32aa6791cb1ff/ruff-0.9.2-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3292c5a22ea9a5f9a185e2d131dc7f98f8534a32fb6d2ee7b9944569239c648d", size = 12704674 }, + { url = "https://files.pythonhosted.org/packages/be/d6/d908762257a96ce5912187ae9ae86792e677ca4f3dc973b71e7508ff6282/ruff-0.9.2-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a605fdcf6e8b2d39f9436d343d1f0ff70c365a1e681546de0104bef81ce88df", size = 14529328 }, + { url = "https://files.pythonhosted.org/packages/2d/c2/049f1e6755d12d9cd8823242fa105968f34ee4c669d04cac8cea51a50407/ruff-0.9.2-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c547f7f256aa366834829a08375c297fa63386cbe5f1459efaf174086b564247", size = 12385955 }, + { url = "https://files.pythonhosted.org/packages/91/5a/a9bdb50e39810bd9627074e42743b00e6dc4009d42ae9f9351bc3dbc28e7/ruff-0.9.2-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:d18bba3d3353ed916e882521bc3e0af403949dbada344c20c16ea78f47af965e", size = 11810149 }, + { url = "https://files.pythonhosted.org/packages/e5/fd/57df1a0543182f79a1236e82a79c68ce210efb00e97c30657d5bdb12b478/ruff-0.9.2-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:b338edc4610142355ccf6b87bd356729b62bf1bc152a2fad5b0c7dc04af77bfe", size = 11479141 }, + { url = "https://files.pythonhosted.org/packages/dc/16/bc3fd1d38974f6775fc152a0554f8c210ff80f2764b43777163c3c45d61b/ruff-0.9.2-py3-none-musllinux_1_2_i686.whl", hash = "sha256:492a5e44ad9b22a0ea98cf72e40305cbdaf27fac0d927f8bc9e1df316dcc96eb", size = 12014073 }, + { url = "https://files.pythonhosted.org/packages/47/6b/e4ca048a8f2047eb652e1e8c755f384d1b7944f69ed69066a37acd4118b0/ruff-0.9.2-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:af1e9e9fe7b1f767264d26b1075ac4ad831c7db976911fa362d09b2d0356426a", size = 12435758 }, + { url = "https://files.pythonhosted.org/packages/c2/40/4d3d6c979c67ba24cf183d29f706051a53c36d78358036a9cd21421582ab/ruff-0.9.2-py3-none-win32.whl", hash = "sha256:71cbe22e178c5da20e1514e1e01029c73dc09288a8028a5d3446e6bba87a5145", size = 9796916 }, + { url = "https://files.pythonhosted.org/packages/c3/ef/7f548752bdb6867e6939489c87fe4da489ab36191525fadc5cede2a6e8e2/ruff-0.9.2-py3-none-win_amd64.whl", hash = "sha256:c5e1d6abc798419cf46eed03f54f2e0c3adb1ad4b801119dedf23fcaf69b55b5", size = 10773080 }, + { url = "https://files.pythonhosted.org/packages/0e/4e/33df635528292bd2d18404e4daabcd74ca8a9853b2e1df85ed3d32d24362/ruff-0.9.2-py3-none-win_arm64.whl", hash = "sha256:a1b63fa24149918f8b37cef2ee6fff81f24f0d74b6f0bdc37bc3e1f2143e41c6", size = 10001738 }, +] + +[[package]] +name = "rusty-logger" +version = "0.4.0" +source = { virtual = "." } + +[package.dev-dependencies] +dev = [ + { name = "black" }, + { name = "isort" }, + { name = "maturin" }, + { name = "mypy" }, + { name = "pylint" }, + { name = "pytest" }, + { name = "pytest-cov" }, + { name = "ruff" }, +] + +[package.metadata] + +[package.metadata.requires-dev] +dev = [ + { name = "black", specifier = ">=24.3.0,<25.0.0" }, + { name = "isort", specifier = ">=5.13.2,<6.0.0" }, + { name = "maturin", specifier = ">=1.4.0,<2.0.0" }, + { name = "mypy", specifier = ">=1.0.0,<2.0.0" }, + { name = "pylint", specifier = ">=3.0.0,<4.0.0" }, + { name = "pytest", specifier = ">=7.0.0,<8.0.0" }, + { name = "pytest-cov", specifier = ">=5.0.0,<6.0.0" }, + { name = "ruff", specifier = ">=0.1.0,<1.0.0" }, +] + +[[package]] +name = "tomli" +version = "2.2.1" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 }, + { url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 }, + { url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 }, + { url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 }, + { url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 }, + { url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 }, + { url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 }, + { url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 }, + { url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 }, + { url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 }, + { url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 }, + { url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 }, + { url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 }, + { url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 }, + { url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 }, + { url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 }, + { url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 }, + { url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 }, + { url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 }, + { url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 }, + { url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 }, + { url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 }, + { url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 }, + { url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 }, + { url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 }, + { url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 }, + { url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 }, + { url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 }, + { url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 }, + { url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 }, + { url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 }, +] + +[[package]] +name = "tomlkit" +version = "0.13.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/b1/09/a439bec5888f00a54b8b9f05fa94d7f901d6735ef4e55dcec9bc37b5d8fa/tomlkit-0.13.2.tar.gz", hash = "sha256:fff5fe59a87295b278abd31bec92c15d9bc4a06885ab12bcea52c71119392e79", size = 192885 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/f9/b6/a447b5e4ec71e13871be01ba81f5dfc9d0af7e473da256ff46bc0e24026f/tomlkit-0.13.2-py3-none-any.whl", hash = "sha256:7a974427f6e119197f670fbbbeae7bef749a6c14e793db934baefc1b5f03efde", size = 37955 }, +] + +[[package]] +name = "typing-extensions" +version = "4.12.2" +source = { registry = "https://pypi.org/simple" } +sdist = { url = "https://files.pythonhosted.org/packages/df/db/f35a00659bc03fec321ba8bce9420de607a1d37f8342eee1863174c69557/typing_extensions-4.12.2.tar.gz", hash = "sha256:1a7ead55c7e559dd4dee8856e3a88b41225abfe1ce8df57b7c13915fe121ffb8", size = 85321 } +wheels = [ + { url = "https://files.pythonhosted.org/packages/26/9f/ad63fc0248c5379346306f8668cda6e2e2e9c95e01216d2b8ffd9ff037d0/typing_extensions-4.12.2-py3-none-any.whl", hash = "sha256:04e5ca0351e0f3f85c6853954072df659d0d13fac324d0072316b67d7794700d", size = 37438 }, +] diff --git a/pyproject.toml b/pyproject.toml deleted file mode 100644 index 5cd05de..0000000 --- a/pyproject.toml +++ /dev/null @@ -1,133 +0,0 @@ -[tool.poetry] -name = "rusty-logger" -version = "0.3.2" -description = "Rust-based python logger" -readme = "README.md" -authors = ["Thorrester <48217609+thorrester@users.noreply.github.com>"] - -[tool.poetry.dependencies] -# required dependencies -python = ">=3.8,<3.13" -smokeshow = "^0.4.0" - - -[tool.poetry.group.dev] -optional = true - -[tool.poetry.group.dev.dependencies] -pytest = "^7.1.2" -pytest-cov = "^3.0.0" -ruff = "^0.1.0" -mypy = "^1" -black = "22.3.0" -pylint = "^2.17.5" -python-json-logger = "^2.0.7" -fastapi = "^0.109.2" -uvicorn = "^0.23" -gunicorn = "^22" - -[tool.ruff] -line-length = 120 - - -[tool.isort] -profile = "black" - -[tool.black] -line-length = 120 -target-version = ['py310'] -include = '\.pyi?$' - -[tool.pylint.MASTER] -load-plugins = ["pylint.extensions.docparams"] - -[tool.pylint.messages_control] -max-line-length = 120 -disable = [ - "too-few-public-methods", - "design", - "duplicate-code", - "missing-class-docstring", - "missing-function-docstring", - "missing-module-docstring", - "too-many-nested-blocks", - "unused-argument", - "fixme", - "import-outside-toplevel" -] - - -[tool.flake8] -# This section is just a doc placeholder..see setup.cfg -max-complexity = 10 -format = "pylint" -statistics = "True" -max-line-length = 125 -# ignore non-PEP8 lints -ignore = ["E203", "W503", "W0511"] - -[tool.pytest.ini_options] -log_cli = true -log_cli_level = "INFO" -testpaths = ["tests"] - - -[tool.mypy] -# platform configuration -python_version = "3.9" -platform = "linux" -mypy_path = "stubs" -ignore_missing_imports = true - - -[build-system] -requires = ["maturin>=1.2,<2.0"] -build-backend = "maturin" - -[project] -name = "rusty-logger" -description = 'Super fast logging for python' -requires-python = ">=3.8, <3.13" -authors = [ - {name = 'Steven Forrester', email = 'sjforrester32@gmail.com'} -] -classifiers = [ - "Programming Language :: Rust", - "Programming Language :: Python :: Implementation :: CPython", - "Programming Language :: Python :: Implementation :: PyPy", - "Development Status :: 5 - Production/Stable", - "Environment :: Console", - "License :: OSI Approved :: MIT License", - "Operating System :: OS Independent", - "Programming Language :: Python", - "Programming Language :: Python :: 3", - "Programming Language :: Python :: 3 :: Only", - "Programming Language :: Python :: 3.9", - "Programming Language :: Python :: 3.10", - "Programming Language :: Python :: 3.11", - "Programming Language :: Python :: 3.12", - "Topic :: Scientific/Engineering", - 'Intended Audience :: Developers', - 'Intended Audience :: Information Technology', - "Intended Audience :: Science/Research", - 'Operating System :: POSIX :: Linux', - 'Operating System :: Microsoft :: Windows', - 'Operating System :: MacOS', - 'Typing :: Typed', -] -dynamic = [ - 'license', - 'readme', -] - -[project.urls] -"Homepage" = "https://github.com/thorrester/rusty-logger" -"Source Code" = "https://github.com/thorrester/rusty-logger" -"Issues" = "https://github.com/thorrester/rusty-logger/issues" - - -[tool.maturin] -python-source = "python" -module-name = "rusty_logger._rusty_logger" -bindings = 'pyo3' -features = ["pyo3/extension-module"] \ No newline at end of file diff --git a/python/rusty_logger/__init__.py b/python/rusty_logger/__init__.py deleted file mode 100644 index a86a016..0000000 --- a/python/rusty_logger/__init__.py +++ /dev/null @@ -1,14 +0,0 @@ -# pylint: disable=no-name-in-module - - -from ._rusty_logger import Logger, LogConfig, JsonConfig, LogLevel, LogFileConfig -from .version import __version__ - -__all__ = [ - "Logger", - "LogConfig", - "JsonConfig", - "LogLevel", - "LogFileConfig", - "__version__", -] diff --git a/python/rusty_logger/_rusty_logger.pyi b/python/rusty_logger/_rusty_logger.pyi deleted file mode 100644 index 653c8bd..0000000 --- a/python/rusty_logger/_rusty_logger.pyi +++ /dev/null @@ -1,225 +0,0 @@ -from typing import Optional - -class LogLevel: - """Enum for log levels""" - - @property - def INFO(self) -> str: - """The INFO log level""" - ... - @property - def DEBUG(self) -> str: - """The DEBUG log level""" - ... - @property - def WARN(self) -> str: - """The WARNING log level""" - ... - @property - def ERROR(self) -> str: - """The ERROR log level""" - ... - @property - def TRACE(self) -> str: - """The TRACE log level""" - ... - -class JsonConfig: - def __init__( - self, - flatten: bool = True, - ): - """Creates logger json configuration - - Args: - flatten: - Whether to flatten the any fields that are passed - """ - ... - @property - def flatten(self) -> bool: - """Whether to flatten any fields that are passed""" - ... - -class LogFileConfig: - def __init__(self, filename: str = "log/logs.log", rotate: str = "never"): - """Creates logger file configuration for recording logs - - Args: - filename: - The name of the file to write logs to - rotate: - The rotation policy for the log file. Can be "never", "daily", "hourly", or "minutely" - """ - ... - -class LogConfig: - def __init__( - self, - stdout: bool = True, - stderr: bool = False, - level: str = "INFO", - name: Optional[str] = None, - app_env: str = "development", - time_format: str = "[year]-[month]-[day]T[hour repr:24]:[minute]:[second]::[subsecond digits:4]", - lock_guard: bool = False, - thread_id: bool = False, - color: bool = False, - json_config: Optional[JsonConfig] = None, - file_config: Optional[LogFileConfig] = None, - ): - """Creates logger configuration - - Args: - stdout: - Whether to log to stdout - stderr: - Whether to log to stderr - filename: - Optional name of log file to write to. Can be a path (logs/test.log) - or just a name (test.log) - level: - The level to log at - app_env: - The environment name to associate with logs. Defaults to "development" - name: - Name to record when logging events. Usually this is the name of the module that is using the logger - time_format: - The time format to use for logs - lock_guard: - Boolean indicating whether to lock this logger to current context. Usually this will be false - thread_id: - Whether to record the thread id in logs - color: - Whether to colorize logs - json_config: - Optional json logger configuration - file_config: - Optional file logger configuration - """ - ... - @property - def stdout(self) -> bool: - """Whether to log to stdout""" - ... - @property - def stderr(self) -> bool: - """Whether to log to stderr""" - ... - @property - def filename(self) -> Optional[str]: - """Optional name of log file to write to. Can be a path (logs/test.log) - or just a name (test.log)""" - ... - @property - def level(self) -> str: - """The level to log at""" - ... - @property - def app_env(self) -> Optional[str]: - """The environment name to associate with logs. Defaults to "development""" - ... - @property - def name(self) -> bool: - """Name to record when logging events. Usually this is the name of the module that is using the logger""" - ... - @property - def time_format(self) -> Optional[str]: - """The time format to use for logs""" - ... - @property - def json_config(self) -> Optional[JsonConfig]: - """Optional json logger configuration""" - ... - @property - def lock_guard(self) -> bool: - """Boolean indicating whether to lock this logger to current context""" - ... - @property - def thread_id(self) -> bool: - """Whether to record the thread id in logs""" - ... - @property - def color(self) -> bool: - """Whether to colorize logs""" - ... - -class Logger: - @classmethod - def get_logger(self, name: Optional[str] = None, config: Optional[LogConfig] = None) -> Logger: - """Gets a new logger. - - Args: - name: - Name to record with logger. Usually this is the name of the module that is using the logger - config: - The configuration for the logger - - Returns: - `RustyLogger` - """ - ... - def set_level(self, level: str) -> None: - """Sets the log level of the logger. - - Args: - level: - The level to log at. - """ - ... - @property - def config(self) -> LogConfig: - """The configuration for the logger.""" - ... - def info(self, message: str, *args, **kwargs) -> None: - """Logs a message at the INFO level. - - Args: - message: - The message to log - args: - Args to format the message with - kwargs: - Kwargs to format the message with - """ - ... - def debug(self, message: str, *args) -> None: - """Logs a message at the DEBUG level. - - Args: - message: - The message to log - args: - Args to format the message with - """ - ... - def warning(self, message: str, *args) -> None: - """Logs a message at the WARNING level. - - Args: - message: - The message to log - args: - Args to format the message with - """ - ... - def error(self, message: str, *args) -> None: - """Logs a message at the ERROR level. - - Args: - message: - The message to log - args: - Args to format the message with - """ - ... - def trace(self, message: str, *args) -> None: - """Logs a message at the TRACE level. - - Args: - message: - The message to log - args: - Args to format the message with - """ - ... diff --git a/release-plz.toml b/release-plz.toml new file mode 100644 index 0000000..5d5c369 --- /dev/null +++ b/release-plz.toml @@ -0,0 +1,14 @@ +[workspace] +dependencies_update = true +changelog_update = true +pr_labels = ["release"] +semver_check = true +publish_timeout = "10m" # set a timeout for `cargo publish` +git_tag_enable = false +git_release_enable = false +publish = true +repo_url = "https://github.com/demml/rusty-logger" + +[[package]] +name = "py-rusty-logger" +publish = false \ No newline at end of file diff --git a/src/lib.rs b/src/lib.rs deleted file mode 100644 index 1faed58..0000000 --- a/src/lib.rs +++ /dev/null @@ -1,16 +0,0 @@ -mod logger; - -use crate::logger::pylogger::{LogLevel, PyLogger}; -use crate::logger::rust_logger::{JsonConfig, LogConfig, LogFileConfig}; -use pyo3::prelude::*; - -/// Python implementation for the Rusty Logger -#[pymodule] -fn _rusty_logger(_py: Python, m: &PyModule) -> PyResult<()> { - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - m.add_class::()?; - Ok(()) -} diff --git a/src/logger/mod.rs b/src/logger/mod.rs deleted file mode 100644 index 53e4c20..0000000 --- a/src/logger/mod.rs +++ /dev/null @@ -1,2 +0,0 @@ -pub mod pylogger; -pub mod rust_logger; diff --git a/src/logger/pylogger.rs b/src/logger/pylogger.rs deleted file mode 100644 index 9562419..0000000 --- a/src/logger/pylogger.rs +++ /dev/null @@ -1,226 +0,0 @@ -use crate::logger::rust_logger::{get_file_name, LogConfig, RustLogger}; -use owo_colors::AnsiColors; -use owo_colors::OwoColorize; -use pyo3::prelude::*; -use pyo3::types::{PyTuple, PyType}; -use serde_json::{json, to_string_pretty}; -use std::collections::HashMap; - -#[derive(FromPyObject, Debug)] -enum PyTypes<'a> { - CatchAll(&'a PyAny), -} - -#[pyclass] -pub struct LogLevel {} - -#[pymethods] -#[allow(non_snake_case)] -impl LogLevel { - #[classattr] - fn DEBUG() -> String { - "DEBUG".to_string() - } - - #[classattr] - fn WARN() -> String { - "WARN".to_string() - } - - #[classattr] - fn INFO() -> String { - "INFO".to_string() - } - - #[classattr] - fn ERROR() -> String { - "ERROR".to_string() - } - - #[classattr] - fn TRACE() -> String { - "TRACE".to_string() - } -} - -pub fn parse_args(args: &PyTuple) -> Option> { - let args: Option> = if args.is_empty() { - None - } else { - Some( - args.iter() - .map(|x| match x.extract::() { - Ok(PyTypes::CatchAll(c)) => c.to_string(), - Err(e) => { - println!("Error: {}", e); - "".to_string() - } - }) - .collect::>(), - ) - }; - - args -} - -#[pyclass(name = "Logger", subclass)] -pub struct PyLogger { - logger: RustLogger, - - #[pyo3(get, set)] - pub config: LogConfig, -} - -#[pymethods] -#[allow(unused_variables)] -impl PyLogger { - /// Create a new logger - /// - /// # Arguments - /// * `config` - The log config to use - /// - /// # Returns - /// A new logger - #[classmethod] - pub fn get_logger(cls: &PyType, name: Option, config: Option) -> PyLogger { - let mut log_config = config.unwrap_or_else(|| { - // get default - LogConfig::new( - None, None, None, None, None, None, None, None, None, None, None, - ) - }); - - // in case where user provides log config and name - // check if user provided name in log config first - if log_config.name.is_none() { - log_config.name = name.map(|val| get_file_name(&val)); - } - - let logger = RustLogger::new(&log_config); - - PyLogger { - logger, - config: log_config, - } - } - - /// Set the log level for the logger - /// - /// # Arguments - /// * `level` - The log level to set - /// - pub fn set_level(&mut self, level: String) { - let mut config = self.config.clone(); - config.log_level(level); - self.logger.reload_level(&config.level).unwrap() - } - - fn check_format_kwargs(&self, message: &str, kwargs: Option>) -> String { - if self.config.file_config.is_some() { - return message.to_string(); - }; - - if kwargs.is_some() { - let kwargs = kwargs.unwrap(); - let color = kwargs.get("color").expect("No color provided"); - - let ansi_color = match *color { - "red" => AnsiColors::Red, - "green" => AnsiColors::Green, - "yellow" => AnsiColors::Yellow, - "blue" => AnsiColors::Blue, - "magenta" => AnsiColors::Magenta, - "cyan" => AnsiColors::Cyan, - "white" => AnsiColors::White, - "black" => AnsiColors::Black, - _ => AnsiColors::Black, - }; - - message.color(ansi_color).to_string() - } else { - message.to_string() - } - } - - /// Log at INFO level - /// - /// # Arguments - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `kwargs` - Optional formatting kwargs - /// - #[pyo3(signature = (message, *args, **kwargs))] - pub fn info(&self, message: &str, args: &PyTuple, kwargs: Option>) { - let args = parse_args(args); - let message = self.check_format_kwargs(message, kwargs); - self.logger.info(&message, args, &self.config); - } - - /// Log at DEBUG level - /// - /// # Arguments - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `kwargs` - Optional formatting kwargs - /// - #[pyo3(signature = (message, *args, **kwargs))] - pub fn debug(&self, message: &str, args: &PyTuple, kwargs: Option>) { - let args = parse_args(args); - let message = self.check_format_kwargs(message, kwargs); - self.logger.debug(&message, args, &self.config); - } - - /// Log at WARN level - /// - /// # Arguments - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `kwargs` - Optional formatting kwargs - /// - #[pyo3(signature = (message, *args, **kwargs))] - pub fn warning(&self, message: &str, args: &PyTuple, kwargs: Option>) { - let args = parse_args(args); - let message = self.check_format_kwargs(message, kwargs); - self.logger.warning(&message, args, &self.config); - } - - /// Log at ERROR level - /// - /// # Arguments - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `kwargs` - Optional formatting kwargs - /// - #[pyo3(signature = (message, *args, **kwargs))] - pub fn error(&self, message: &str, args: &PyTuple, kwargs: Option>) { - let args = parse_args(args); - let message = self.check_format_kwargs(message, kwargs); - self.logger.error(&message, args, &self.config); - } - - /// Log at TRACE level - /// - /// # Arguments - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `kwargs` - Optional formatting kwargs - /// - #[pyo3(signature = (message, *args, **kwargs))] - pub fn trace(&self, message: &str, args: &PyTuple, kwargs: Option>) { - let args = parse_args(args); - let message = self.check_format_kwargs(message, kwargs); - self.logger.trace(&message, args, &self.config); - } - - /// String magic method for PyLogger class - pub fn __str__(&self) -> PyResult { - let json = json!({ - "type": "Logger", - "name": self.config.name, - "level": self.config.app_env, - "config": self.config, - }); - - Ok(to_string_pretty(&json).unwrap()) - } -} diff --git a/src/logger/rust_logger.rs b/src/logger/rust_logger.rs deleted file mode 100644 index 2bf6270..0000000 --- a/src/logger/rust_logger.rs +++ /dev/null @@ -1,768 +0,0 @@ -use pyo3::prelude::*; -use serde::{Deserialize, Serialize}; -use std::env; -use std::io; -use std::path::Path; -use tracing_core::dispatcher::DefaultGuard; -use tracing_subscriber::filter::LevelFilter; -use tracing_subscriber::layer::Layered; - -use dynfmt::{Format, SimpleCurlyFormat}; -use owo_colors::OwoColorize; -use time::format_description::FormatItem; -use tracing_subscriber::fmt::time::UtcTime; -use tracing_subscriber::fmt::MakeWriter; -use tracing_subscriber::prelude::__tracing_subscriber_Layer; -use tracing_subscriber::prelude::__tracing_subscriber_SubscriberExt; -use tracing_subscriber::registry::LookupSpan; -use tracing_subscriber::reload; -use tracing_subscriber::util::SubscriberInitExt; -use tracing_subscriber::Layer; -use tracing_subscriber::Registry; - -static DEFAULT_TIME_PATTERN: &str = - "[year]-[month]-[day]T[hour repr:24]:[minute]:[second]::[subsecond digits:4]"; - -type ReloadHandle = - reload::Handle + Send + Sync>>, Registry>>; - -#[pyclass(dict)] -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct JsonConfig { - #[pyo3(get, set)] - pub flatten: bool, -} - -#[pymethods] -impl JsonConfig { - #[new] - pub fn new(flatten: Option) -> Self { - JsonConfig { - flatten: flatten.unwrap_or(true), - } - } - - pub fn __str__(&self) -> PyResult { - Ok(serde_json::to_string_pretty(&self).unwrap()) - } -} - -#[pyclass(dict)] -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct LogFileConfig { - #[pyo3(get, set)] - pub filename: String, - - #[pyo3(get, set)] - pub rotate: String, -} - -#[pymethods] -impl LogFileConfig { - #[new] - pub fn new(filename: Option, rotate: Option) -> Self { - LogFileConfig { - filename: filename.unwrap_or("log/logs.log".to_string()), - rotate: rotate.unwrap_or("never".to_string()), - } - } - - pub fn __str__(&self) -> PyResult { - Ok(serde_json::to_string_pretty(&self).unwrap()) - } -} - -#[pyclass] -#[derive(Debug, Serialize, Deserialize, Clone)] -pub struct LogConfig { - #[pyo3(get, set)] - pub stdout: bool, - - #[pyo3(get, set)] - pub stderr: bool, - - #[pyo3(get, set)] - pub level: String, - - #[pyo3(get, set)] - pub app_env: String, - - #[pyo3(get, set)] - pub name: Option, - - #[pyo3(get, set)] - pub time_format: String, - - #[pyo3(get, set)] - pub json_config: Option, - - #[pyo3(get, set)] - pub file_config: Option, - - #[pyo3(get, set)] - pub lock_guard: bool, - - #[pyo3(get, set)] - pub thread_id: bool, - - #[pyo3(get, set)] - pub color: bool, -} - -#[pymethods] -#[allow(clippy::too_many_arguments)] -impl LogConfig { - // py init - #[new] - pub fn new( - stdout: Option, - stderr: Option, - level: Option, - app_env: Option, - name: Option, - time_format: Option, - json_config: Option, - file_config: Option, - lock_guard: Option, - thread_id: Option, - color: Option, - ) -> Self { - let log_env = match app_env { - Some(val) => val, - None => match env::var("APP_ENV") { - Ok(val) => val, - Err(_e) => "development".to_string(), - }, - }; - - let name = name.map(|val| get_file_name(&val)); - - let stdout = stdout.unwrap_or(false); - let stderr = stderr.unwrap_or(false); - - let stdout = if !stdout && !stderr && file_config.is_none() { - let msg = format!( - "{}: {}. {}", - "LogConfig".bold().red(), - "No output specified", - "Defaulting to stdout".green(), - ); - println!("{}", msg); - - true - } else { - stdout - }; - - LogConfig { - stdout, - stderr, - level: level.unwrap_or_else(|| "INFO".to_string()), - app_env: log_env, - name, - time_format: time_format.unwrap_or_else(|| DEFAULT_TIME_PATTERN.to_string()), - json_config, - file_config, - lock_guard: lock_guard.unwrap_or(false), - thread_id: thread_id.unwrap_or(false), - color: color.unwrap_or(false), - } - } - - pub fn log_level(&mut self, level: String) { - self.level = level; - } - - pub fn update_name(&mut self, name: String) { - let filename = get_file_name(&name); - self.name = Some(filename); - } - - pub fn __str__(&self) -> PyResult { - Ok(serde_json::to_string_pretty(&self).unwrap()) - } -} - -/// Get the name of the file -/// -/// # Arguments -/// -/// * `name` - The name of the file -/// -pub fn get_file_name(filename: &str) -> String { - Path::new(&filename) - .file_name() - .and_then(|s| s.to_str()) - .unwrap() - .to_string() -} - -#[allow(clippy::single_char_pattern)] -fn get_log_directory(output: &str) -> String { - let file_splits = output.split("/").to_owned().collect::>().clone(); - let directory = file_splits[..file_splits.len() - 1].join("/"); - - if directory.is_empty() { - "./logs".to_string() - } else { - directory - } -} - -fn get_file_params(file_config: &LogFileConfig) -> (String, String) { - let directory = get_log_directory(&file_config.filename); - let file_name_prefix = get_file_name(&file_config.filename); - - (directory, file_name_prefix) -} - -/// Get the file appender -/// -/// # Arguments -/// -/// * `rotate` - The rotation type -/// * `directory` - The directory to write the file to -/// * `file_name_prefix` - The prefix of the file name -/// -/// # Returns -/// -/// * `RollingFileAppender` - The file appender -fn get_file_appender( - rotate: &str, - directory: &str, - file_name_prefix: &str, -) -> tracing_appender::rolling::RollingFileAppender { - if rotate == "hourly" { - tracing_appender::rolling::hourly(directory, file_name_prefix) - } else if rotate == "daily" { - tracing_appender::rolling::daily(directory, file_name_prefix) - } else if rotate == "minutely" { - tracing_appender::rolling::minutely(directory, file_name_prefix) - } else { - tracing_appender::rolling::never(directory, file_name_prefix) - } -} - -#[allow(clippy::len_zero)] // len tends to be faster than is_empty in tests -fn format_string(message: &str, args: &Vec) -> String { - if args.len() > 0 { - SimpleCurlyFormat - .format(message, args) - .unwrap_or_else(|_| message.into()) - .to_string() - } else { - message.to_string() - } -} - -/// Rust logging class -/// -/// # Arguments -/// -/// * `output` - The output of the logger. Either "stdout" or "stderr" -/// * `level` - The level of the logger. Either "info", "debug", "warn", or "error" -/// * `name` - The name of the file -/// -#[allow(dead_code)] -pub struct RustLogger { - reload_handle: ReloadHandle, - pub guard: Option, -} - -impl RustLogger { - pub fn get_timer(time_format: String) -> UtcTime>> { - let time = Box::new(time_format); - let time_format_result = time::format_description::parse(Box::leak(time).as_str()); - - // handle invalid user time format - // Very rare that this would fail but let's handle it anyway - let time_format = time_format_result.unwrap_or_else(|error| { - println!("{}: {}", "Invalid time format:".bold().red(), error); - println!("Defaulting to pattern: {}", DEFAULT_TIME_PATTERN.green()); - - time::format_description::parse(DEFAULT_TIME_PATTERN).unwrap() - }); - - UtcTime::new(time_format) - } - - pub fn get_level_filter(level: &str) -> LevelFilter { - match level { - "DEBUG" => LevelFilter::DEBUG, - "INFO" => LevelFilter::INFO, - "WARN" => LevelFilter::WARN, - "ERROR" => LevelFilter::ERROR, - "TRACE" => LevelFilter::TRACE, - _ => LevelFilter::INFO, - } - } - - /// Create a new logger - /// - /// # Arguments - /// - /// * `log_config` - The configuration for the logger - /// - /// # Returns - /// RustLogger - pub fn new(log_config: &LogConfig) -> RustLogger { - let layers = RustLogger::build_layers(log_config); - let filter = RustLogger::get_level_filter(&log_config.level); - let (filter, reload_handle) = reload::Layer::new(filter); - - // in case we want to lock the guard (default behavior is not to lock) - if log_config.lock_guard { - let guard = tracing_subscriber::registry() - .with(layers) - .with(filter) - .set_default(); - - Self { - reload_handle, - guard: Some(guard), - } - - // Don't lock guard (set global default subscriber) - } else { - let subscriber_result = tracing_subscriber::registry() - .with(layers) - .with(filter) - .try_init(); - - match subscriber_result { - Ok(val) => val, - Err(_e) => (), - } - - Self { - reload_handle, - guard: None, - } - } - } - - /// Reload the logger level - pub fn reload_level(&mut self, level: &str) -> Result<(), reload::Error> { - let filter = RustLogger::get_level_filter(level); - self.reload_handle.reload(filter) - } - - /// Build the json layer for the logger - /// - /// # Arguments - /// - /// * `log_config` - The configuration for the logger - /// * `writer` - The writer for the logger - /// - /// # Returns - /// * `Box + Send + Sync>` - The layer for the logger - fn construct_json_layer( - log_config: &LogConfig, - writer: W2, - ) -> Box + Send + Sync> - where - S: tracing_core::Subscriber, - W2: for<'writer> MakeWriter<'writer> + 'static + Send + Sync, - for<'a> S: LookupSpan<'a>, - { - let flatten = log_config.json_config.as_ref().unwrap().flatten; - let timer = RustLogger::get_timer(log_config.time_format.clone()); - - tracing_subscriber::fmt::layer() - .with_target(false) - .json() - .flatten_event(flatten) - .with_thread_ids(log_config.thread_id) - .with_timer(timer) - .with_writer(writer) - .with_ansi(log_config.color) - .boxed() - } - - /// Build the json layers for the logger - /// - /// # Arguments - /// - /// * `log_config` - The configuration for the logger - /// - /// # Returns - /// * `Vec + Send + Sync>>` - The layers for the logger - fn construct_json_layers(log_config: &LogConfig) -> Vec + Send + Sync>> - where - S: tracing_core::Subscriber, - for<'a> S: LookupSpan<'a>, - { - let mut layers = Vec::new(); - - if log_config.stdout { - layers.push(RustLogger::construct_json_layer(log_config, io::stdout)); - } - - if log_config.stderr { - layers.push(RustLogger::construct_json_layer(log_config, io::stderr)); - } - - if log_config.file_config.is_some() { - let (directory, file_name_prefix) = - get_file_params(log_config.file_config.as_ref().unwrap()); - let file_appender = get_file_appender( - &log_config.file_config.as_ref().unwrap().rotate, - &directory, - &file_name_prefix, - ); - layers.push(RustLogger::construct_json_layer(log_config, file_appender)); - } - - layers - } - - fn construct_cmd_layer( - log_config: &LogConfig, - writer: W2, - ) -> Box + Send + Sync> - where - S: tracing_core::Subscriber, - W2: for<'writer> MakeWriter<'writer> + 'static + Send + Sync, - for<'a> S: LookupSpan<'a>, - { - let timer = RustLogger::get_timer(log_config.time_format.clone()); - tracing_subscriber::fmt::layer() - .with_target(false) - .with_thread_ids(log_config.thread_id) - .with_timer(timer) - .with_writer(writer) - .with_ansi(log_config.color) - .boxed() - } - - /// Build the layers for the logger - /// - /// # Arguments - /// - /// * `log_config` - The configuration for the logger - /// - /// # Returns - /// - /// * `Vec + Send + Sync>>` - The layers for the logger - fn construct_cmd_layers(log_config: &LogConfig) -> Vec + Send + Sync>> - where - S: tracing_core::Subscriber, - for<'a> S: LookupSpan<'a>, - { - let mut layers = Vec::new(); - // set time format (applies to all layers) - - if log_config.stdout { - let writer = io::stdout; - layers.push(RustLogger::construct_cmd_layer(log_config, writer)); - } - - if log_config.stderr { - let writer = io::stderr; - layers.push(RustLogger::construct_cmd_layer(log_config, writer)); - } - - if log_config.file_config.is_some() { - let (directory, file_name_prefix) = - get_file_params(log_config.file_config.as_ref().unwrap()); - let writer = get_file_appender( - &log_config.file_config.as_ref().unwrap().rotate, - &directory, - &file_name_prefix, - ); - - layers.push(RustLogger::construct_cmd_layer(log_config, writer)); - } - - layers - } - - /// Build the layers for the logger - /// - /// # Arguments - /// - /// * `log_config` - The configuration for the logger - /// - /// # Returns - /// - /// * `Vec + Send + Sync>>` - The layers for the logger - fn build_layers(log_config: &LogConfig) -> Vec + Send + Sync>> - where - S: tracing_core::Subscriber, - for<'a> S: LookupSpan<'a>, - { - if log_config.json_config.is_some() { - RustLogger::construct_json_layers(log_config) - } else { - RustLogger::construct_cmd_layers(log_config) - } - } - - /// Log an info message - /// - /// # Arguments - /// - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `log_config` - The configuration for the logger - /// - pub fn info(&self, message: &str, args: Option>, log_config: &LogConfig) { - // format string first - let msg = match args { - Some(val) => format_string(message, &val), - None => message.to_string(), - }; - - match log_config.name { - Some(ref val) => tracing::info!( - message = msg, - app_env = log_config.app_env, - name = val.as_str() - ), - None => tracing::info!(message = msg, app_env = log_config.app_env), - }; - } - - /// Log a debug message - /// - /// # Arguments - /// - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `log_config` - The configuration for the logger - /// - pub fn debug(&self, message: &str, args: Option>, log_config: &LogConfig) { - let msg = match args { - Some(val) => format_string(message, &val), - None => message.to_string(), - }; - match log_config.name { - Some(ref val) => tracing::debug!( - message = msg, - app_env = log_config.app_env, - name = val.as_str() - ), - None => tracing::debug!(message = msg, app_env = log_config.app_env), - }; - } - - /// Log a warning message - /// - /// # Arguments - /// - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `log_config` - The configuration for the logger - /// - pub fn warning(&self, message: &str, args: Option>, log_config: &LogConfig) { - let msg = match args { - Some(val) => format_string(message, &val), - None => message.to_string(), - }; - match log_config.name { - Some(ref val) => tracing::warn!( - message = msg, - app_env = log_config.app_env, - name = val.as_str() - ), - None => tracing::warn!(message = msg, app_env = log_config.app_env), - }; - } - - /// Log an error message - /// - /// # Arguments - /// - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `log_config` - The configuration for the logger - /// - pub fn error(&self, message: &str, args: Option>, log_config: &LogConfig) { - let msg = match args { - Some(val) => format_string(message, &val), - None => message.to_string(), - }; - match log_config.name { - Some(ref val) => tracing::error!( - message = msg, - app_env = log_config.app_env, - name = val.as_str() - ), - None => tracing::error!(message = msg, app_env = log_config.app_env), - }; - } - - /// Log an trace message - /// - /// # Arguments - /// - /// * `message` - The message to log - /// * `args` - The arguments to log - /// * `log_config` - The configuration for the logger - /// - pub fn trace(&self, message: &str, args: Option>, log_config: &LogConfig) { - let msg = match args { - Some(val) => format_string(message, &val), - None => message.to_string(), - }; - match log_config.name { - Some(ref val) => tracing::trace!( - message = msg, - app_env = log_config.app_env, - name = val.as_str() - ), - None => tracing::trace!(message = msg, app_env = log_config.app_env), - }; - } -} - -#[cfg(test)] -mod tests { - use super::{JsonConfig, LogConfig, LogFileConfig, RustLogger}; - - fn generate_test_file_config( - level: String, - stdout: bool, - stderr: bool, - rotate: &str, - filename: &str, - ) -> LogConfig { - LogConfig { - stdout, - stderr, - level, - app_env: "development".to_string(), - name: None, - time_format: - "[year]-[month]-[day] [hour repr:24]:[minute]:[second]::[subsecond digits:4]" - .to_string(), - json_config: Some(JsonConfig::new(None)), - file_config: Some(LogFileConfig::new( - Some(filename.to_string()), - Some(rotate.to_string()), - )), - lock_guard: true, - thread_id: false, - color: true, - } - } - - fn generate_test_json_config(level: String, stdout: bool, stderr: bool) -> LogConfig { - LogConfig { - stdout, - stderr, - level, - app_env: "development".to_string(), - name: None, - time_format: - "[year]-[month]-[day] [hour repr:24]:[minute]:[second]::[subsecond digits:4]" - .to_string(), - json_config: Some(JsonConfig::new(None)), - file_config: None, - lock_guard: true, - thread_id: true, - color: true, - } - } - - fn generate_test_incorrect_config() -> LogConfig { - LogConfig { - stdout: false, - stderr: false, - level: "INFO".to_string(), - app_env: "development".to_string(), - name: None, - time_format: - "[year]-[month]-[day] [hour repr:24]:[minute]:[second]::[subsecond digits:4]" - .to_string(), - json_config: Some(JsonConfig::new(None)), - file_config: None, - lock_guard: true, - thread_id: true, - color: true, - } - } - - #[test] - fn test_stdout_logger() { - let levels = ["INFO", "DEBUG", "WARN", "ERROR", "TRACE"]; - - levels.iter().for_each(|level| { - let args = Some(vec!["10".to_string(), "10".to_string()]); - let config = generate_test_json_config(level.to_string(), true, false); - let logger = RustLogger::new(&config); - logger.info("test", args.clone(), &config); - logger.debug("test", args.clone(), &config); - logger.warning("test", args.clone(), &config); - logger.error("test", args.clone(), &config); - logger.trace("test", args.clone(), &config); - }); - } - - #[test] - fn test_stderr_logger() { - let levels = ["INFO", "DEBUG", "WARN", "ERROR", "TRACE"]; - - levels.iter().for_each(|level| { - let config = generate_test_json_config(level.to_string(), false, true); - let logger = RustLogger::new(&config); - logger.info("test", None, &config); - logger.debug("test", None, &config); - logger.warning("test", None, &config); - logger.error("test", None, &config); - logger.trace("test", None, &config); - }); - } - - #[test] - fn test_file_logger_minute() { - let config = generate_test_file_config( - "INFO".to_string(), - true, - false, - "minutely", - "minute/log.log", - ); - let logger = RustLogger::new(&config); - logger.info("test", None, &config); - - std::fs::remove_dir_all("minute").unwrap(); - } - - #[test] - fn test_file_logger_hourly() { - let config = - generate_test_file_config("INFO".to_string(), true, false, "hourly", "hourly/log.log"); - let logger = RustLogger::new(&config); - logger.info("test", None, &config); - - std::fs::remove_dir_all("hourly").unwrap(); - } - - #[test] - fn test_file_logger_daily() { - let config = - generate_test_file_config("INFO".to_string(), true, false, "daily", "daily/log.log"); - let logger = RustLogger::new(&config); - logger.info("test", None, &config); - - std::fs::remove_dir_all("daily").unwrap(); - } - - #[test] - fn test_file_logger_never() { - let config = - generate_test_file_config("INFO".to_string(), true, false, "never", "never/log.log"); - let logger = RustLogger::new(&config); - logger.info("test", None, &config); - - std::fs::remove_dir_all("never").unwrap(); - } - - #[test] - fn test_invalid_output() { - let config = generate_test_incorrect_config(); - let logger = RustLogger::new(&config); - logger.info("test", None, &config); - } -} diff --git a/tests/_test_scratch.py b/tests/_test_scratch.py deleted file mode 100644 index d45222f..0000000 --- a/tests/_test_scratch.py +++ /dev/null @@ -1,4 +0,0 @@ -from rusty_logger import Logger - -logger = Logger.get_logger(__file__) -logger.info("Loggy McLogface") diff --git a/tests/conftest.py b/tests/conftest.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/file_logger_test.py b/tests/file_logger_test.py deleted file mode 100644 index e69de29..0000000 diff --git a/tests/mod_one.py b/tests/mod_one.py deleted file mode 100644 index 0ec239b..0000000 --- a/tests/mod_one.py +++ /dev/null @@ -1,21 +0,0 @@ -from rusty_logger import Logger, LogConfig, JsonConfig, LogFileConfig - - -logger = Logger.get_logger( - name=__file__, - config=LogConfig( - json_config=JsonConfig(), - file_config=LogFileConfig( - filename="log/test.log", - ), - lock_guard=True, - ), -) - - -class TestOne: - @staticmethod - def test_logger(): - pointer = logger - assert pointer == logger - logger.info("This is a test log") diff --git a/tests/mod_two.py b/tests/mod_two.py deleted file mode 100644 index a0cdd72..0000000 --- a/tests/mod_two.py +++ /dev/null @@ -1,19 +0,0 @@ -from rusty_logger import Logger, LogConfig, JsonConfig, LogFileConfig - - -logger = Logger.get_logger( - name=__file__, - config=LogConfig( - json_config=JsonConfig(), - file_config=LogFileConfig( - filename="log/test.log", - ), - lock_guard=True, - ), -) - - -class TestTwo: - @staticmethod - def test_logger(): - logger.info("This is a test log") diff --git a/tests/requirements.txt b/tests/requirements.txt deleted file mode 100644 index 484db85..0000000 --- a/tests/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -pytest==7.4.2 -pytest-cov==3.0.0 \ No newline at end of file diff --git a/tests/standard_logger.py b/tests/standard_logger.py deleted file mode 100644 index e0707b0..0000000 --- a/tests/standard_logger.py +++ /dev/null @@ -1,10 +0,0 @@ -from rusty_logger import Logger, __version__ - - -logger = Logger.get_logger(name=__file__) -logger.info("Rusty Logger version: {}", __version__) -logger.info("test info") -logger.debug("test debug") -logger.warning("test warning") -logger.error("test error") -logger.trace("test trace") diff --git a/tests/test_logger.py b/tests/test_logger.py deleted file mode 100644 index aaf8578..0000000 --- a/tests/test_logger.py +++ /dev/null @@ -1,177 +0,0 @@ -import glob -from rusty_logger import LogConfig, JsonConfig, LogLevel, LogFileConfig, __version__, Logger -import shutil - -"""All tests are performed with guard locking -Guard locking is a feature that allows you to lock a logger to a specific context that is dropped on end of context. -All tests are performed with loggers scoped to their function context. -If lock_guard is set to False, a default global logger is used that runs the duration of the application -and is immutable after instantiation. Thus, subsequent tests with different logger configurations will fail. -However, guard_lock = false (default) is useful for applications that do not require multiple loggers. -""" - - -def test_version(): - assert __version__ is not None - - -def test_log_config(): - config = LogConfig() - assert config.stdout is True - assert config.stderr is False - assert config.level == "INFO" - assert config.app_env == "development" - assert config.json_config is None - - -def test_log_level(): - assert LogLevel.DEBUG == "DEBUG" - assert LogLevel.INFO == "INFO" - assert LogLevel.WARN == "WARN" - assert LogLevel.ERROR == "ERROR" - assert LogLevel.TRACE == "TRACE" - - -def test_info_logger_stdout(): - logger = Logger.get_logger( - name=__file__, - config=LogConfig(lock_guard=True), - ) - logger.info("test info") - logger.debug("test debug") - logger.warning("test warning") - logger.error("test error") - logger.trace("test trace") - logger.info("test info", color="red") # testing color parsing - - -def test_debug_logger_file(): - file_config = LogFileConfig(filename="log/test.log") - logger = Logger.get_logger( - name=__file__, - config=LogConfig( - lock_guard=True, - file_config=file_config, - level="DEBUG", - color=True, - ), - ) - - logger.info("test info") - logger.debug("test debug") - logger.warning("test warning") - logger.error("test error") - - assert glob.glob("log/test.log*") - - for name in glob.glob("log/test.log*"): - with open(name, "r") as fp: - for count, line in enumerate(fp): - pass - count = count + 1 - assert count == 4 - shutil.rmtree("log", ignore_errors=False) - - -def test_warn_logger_file(): - file_config = LogFileConfig(filename="log/test.log") - logger = Logger.get_logger( - name=__file__, - config=LogConfig( - level="TRACE", - json_config=JsonConfig(flatten=True), - file_config=file_config, - lock_guard=True, - ), - ) - - logger.info("test info") - logger.debug("test debug") - logger.warning("test warning") - logger.error("test error") - logger.trace("test error") - logger.info("test info", color="red") # this will be skipped - - assert glob.glob("log/test.log*") - - for name in glob.glob("log/test.log*"): - with open(name, "r") as fp: - for count, line in enumerate(fp): - pass - count = count + 1 - assert count == 6 - shutil.rmtree("log", ignore_errors=False) - - -def test_error_logger_file(): - file_config = LogFileConfig(filename="log/test.log") - logger = Logger.get_logger( - name=__name__, - config=LogConfig( - level="ERROR", - json_config=JsonConfig(flatten=True), - file_config=file_config, - lock_guard=True, - thread_id=True, - ), - ) - - logger.info("test info") - logger.debug("test debug") - logger.warning("test warning") - logger.error("test error") - - assert glob.glob("log/test.log*") - - for name in glob.glob("log/test.log*"): - with open(name, "r") as fp: - for count, line in enumerate(fp): - count - pass - count = count + 1 - assert count == 1 - shutil.rmtree("log", ignore_errors=False) - - -def _test_modules(): - from tests.mod_one import TestOne - from tests.mod_two import TestTwo - - TestOne.test_logger() - TestTwo.test_logger() - - for name in glob.glob("log/test.log*"): - with open(name, "r") as fp: - for count, line in enumerate(fp): - pass - count = count + 1 - assert count == 2 - shutil.rmtree("log", ignore_errors=False) - - -def test_invalid_config_format(): - logger = Logger.get_logger( - name=__file__, - config=LogConfig( - stderr=False, - stdout=False, - time_format="[hour]:[minute]", - lock_guard=True, - ), - ) - - # Logger will default to stdout true if not set - assert logger.config.stdout - logger.info("blah") - - -def test_info_logger_stdout_args(): - # turn off guard locking for last test - logger = Logger.get_logger( - name=__file__, - config=LogConfig( - lock_guard=True, - ), - ) - - logger.info("test info {} {} {} ", "test", 10.43, {"test": "test"})