diff --git a/.github/workflows/docker-extras.yml b/.github/workflows/docker-extras.yml index 76a56bea..3a5fee81 100644 --- a/.github/workflows/docker-extras.yml +++ b/.github/workflows/docker-extras.yml @@ -34,7 +34,7 @@ jobs: - name: Build and push platforms uses: docker/build-push-action@v5 with: - context: docker + context: . file: docker/Dockerfile.torchserve platforms: linux/amd64,linux/arm64 push: true @@ -68,7 +68,7 @@ jobs: - name: Build and push platforms uses: docker/build-push-action@v5 with: - context: docker + context: . file: docker/Dockerfile.cuda-torchserve platforms: linux/amd64 push: true diff --git a/.github/workflows/docker-test.yml b/.github/workflows/docker-test.yml index 8e7473eb..7f61bfac 100644 --- a/.github/workflows/docker-test.yml +++ b/.github/workflows/docker-test.yml @@ -7,9 +7,7 @@ jobs: - uses: actions/checkout@v4 - name: docker build run: | - cd docker - docker build -f Dockerfile.torchserve . -t iqtlabs/gamutrf-torchserve:latest - cd .. + docker build -f docker/Dockerfile.torchserve . -t iqtlabs/gamutrf-torchserve:latest ./tests/test_torchserve.sh test-gamutrf-extra-images: runs-on: ubuntu-latest diff --git a/Dockerfile b/Dockerfile index acc23cf7..84c57c45 100644 --- a/Dockerfile +++ b/Dockerfile @@ -31,7 +31,7 @@ RUN apt-get update && apt-get install --no-install-recommends -y -q \ # nosemgrep:github.workflows.config.dockerfile-source-not-pinned FROM ubuntu:22.04 -COPY --from=iqtlabs/gnuradio:3.10.7 /usr/share/uhd/images /usr/share/uhd/images +COPY --from=iqtlabs/gnuradio:3.10.8 /usr/share/uhd/images /usr/share/uhd/images COPY --from=installer /usr/local /usr/local COPY --from=installer /gamutrf /gamutrf COPY --from=installer /root/.local /root/.local @@ -40,37 +40,46 @@ ENV DEBIAN_FRONTEND noninteractive ENV UHD_IMAGES_DIR /usr/share/uhd/images ENV PATH="${PATH}:/root/.local/bin" RUN mkdir -p /data/gamutrf -RUN apt-get update && apt-get install --no-install-recommends -y -q \ - ca-certificates \ - libblas3 \ - libboost-iostreams1.74.0 \ - libboost-program-options1.74.0 \ - libboost-thread1.74.0 \ - libcairo2 \ - libev4 \ - libfftw3-3 \ - libgl1 \ - libglib2.0-0 \ - liblapack3 \ - libopencv-core4.5d \ - libopencv-imgcodecs4.5d \ - libopencv-imgproc4.5d \ - librtlsdr0 \ - libspdlog1 \ - libuhd4.1.0 \ - libunwind8 \ - libvulkan1 \ - libzmq5 \ - mesa-vulkan-drivers \ - python3 \ - python3-pyqt5 \ - python3-pyqt5.sip \ - python3-zmq \ - sox \ - sudo \ - wget \ - uhd-host \ - zstd && \ +# install nvidia's vulkan support if x86. +# hadolint ignore=DL3008 +RUN if [ "$(arch)" = "x86_64" ] ; then \ + apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates dirmngr gpg-agent gpg wget && \ + apt-key adv --fetch-keys "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/$(arch)/3bf863cc.pub" && \ + echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/$(arch)/ /" | tee /etc/apt/sources.list.d/nvidia.list && \ + apt-get update && \ + apt-get install -y --no-install-recommends libnvidia-gl-545 ; \ + fi && \ + apt-get update && apt-get install -y --no-install-recommends \ + ca-certificates \ + libblas3 \ + libboost-iostreams1.74.0 \ + libboost-program-options1.74.0 \ + libboost-thread1.74.0 \ + libcairo2 \ + libev4 \ + libfftw3-3 \ + libgl1 \ + libglib2.0-0 \ + liblapack3 \ + libopencv-core4.5d \ + libopencv-imgcodecs4.5d \ + libopencv-imgproc4.5d \ + librtlsdr0 \ + libspdlog1 \ + libuhd4.1.0 \ + libunwind8 \ + libvulkan1 \ + libzmq5 \ + mesa-vulkan-drivers \ + python3 \ + python3-pyqt5 \ + python3-pyqt5.sip \ + python3-zmq \ + sox \ + uhd-host \ + wget \ + zstd && \ apt-get -y -q clean && rm -rf /var/lib/apt/lists/* WORKDIR /gamutrf RUN echo "$(find /gamutrf/gamutrf -type f -name \*py -print)"|xargs grep -Eh "^(import|from)\s"|grep -Ev "gamutrf"|sort|uniq|python3 diff --git a/README.md b/README.md index 4586a80c..b2a3785f 100644 --- a/README.md +++ b/README.md @@ -175,12 +175,22 @@ Run ```echo 0 > /sys/module/usbcore/parameters/usbfs_memory_mb``` as root before ##### ```[ERROR] [USB] USB open failed: insufficient permissions``` -Ettus SDRs download firmware and switch USB identities when first powered up. Restart the affected container to work around this. +Ettus SDRs download firmware and switch USB identities when first powered up. Restart the affected container to work around this (if run with docker compose, restart will happen automatically). ##### ```[ERROR] [UHD] An unexpected exception was caught in a task loop.The task loop will now exit, things may not work.boost: mutex lock failed in pthread_mutex_lock: Invalid argument``` UHD driver arguments ```num_recv_frames``` or ```recv_frame_size``` may be too high. The defaults are defined as ETTUS_ARGS in [utils.py](gamutrf/utils.py). Try reducing one or both via ```--sdrargs```. For example, ```--sdrargs num_recv_frames=64,recv_frame_size=8200,type=b200```. +#### ```[ERROR] [UHD] EnvironmentError: IOError: usb rx6 transfer status: LIBUSB_TRANSFER_OVERFLOW``` + +Stop containers, and reset the Ettus as follows: + +``` +$ /usr/lib/uhd/utils/b2xx_fx3_utils -D +$ /usr/lib/uhd/utils/b2xx_fx3_utils -U +$ /usr/lib/uhd/utils/b2xx_fx3_utils -S +``` + #### Scanner with Ettus SDR shows implausible low power at approx 100MHz intervals Ettus radios periodically need extra time to produce good data when being retuned rapidly by the scanner. Increasing the value of ```--db_clamp_floor``` will cause the scanner to discard windows after retuning (effectively waiting for the retune command to be executed and produce good data before proceeding). diff --git a/docker/Dockerfile.base b/docker/Dockerfile.base index 3d8370ef..d47a3955 100644 --- a/docker/Dockerfile.base +++ b/docker/Dockerfile.base @@ -32,7 +32,7 @@ WORKDIR /root/uhd_sample_recorder/build RUN CMAKE_BUILD_TYPE=Release cmake ../lib && make -j $(nproc) && cp uhd_sample_recorder /usr/local/bin FROM ubuntu:22.04 as driver-builder -COPY --from=iqtlabs/gnuradio:3.10.7 /usr/local /usr/local +COPY --from=iqtlabs/gnuradio:3.10.8 /usr/local /usr/local ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ @@ -72,7 +72,7 @@ WORKDIR /root/lime-tools/build RUN cmake .. && make install FROM ubuntu:22.04 as gr-iqtlabs-builder -COPY --from=iqtlabs/gnuradio:3.10.7 /usr/local /usr/local +COPY --from=iqtlabs/gnuradio:3.10.8 /usr/local /usr/local ENV DEBIAN_FRONTEND noninteractive RUN apt-get update && apt-get install -y --no-install-recommends \ build-essential \ @@ -87,8 +87,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libvulkan-dev \ python3-numpy WORKDIR /root -RUN git clone https://github.com/iqtlabs/gr-iqtlabs -b 1.0.44 -RUN sed -i /SPIRV-Tools/d gr-iqtlabs/lib/CMakeLists.txt +RUN git clone https://github.com/iqtlabs/gr-iqtlabs -b 1.0.46 COPY --from=iqtlabs/gamutrf-vkfft:latest /root /root/gr-iqtlabs WORKDIR /root/gr-iqtlabs/build COPY --from=sigmf-builder /usr/local /usr/local @@ -112,7 +111,7 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ python3 \ python3-numpy \ && apt-get -y -q clean && rm -rf /var/lib/apt/lists/* -COPY --from=iqtlabs/gnuradio:3.10.7 /usr/local /usr/local +COPY --from=iqtlabs/gnuradio:3.10.8 /usr/local /usr/local COPY --from=driver-builder /usr/local /usr/local COPY --from=gr-iqtlabs-builder /usr/local /usr/local COPY --from=uhd_sample_recorder-builder /usr/local /usr/local diff --git a/docker/Dockerfile.cuda-torchserve b/docker/Dockerfile.cuda-torchserve index 8419ebb2..3cc0166a 100644 --- a/docker/Dockerfile.cuda-torchserve +++ b/docker/Dockerfile.cuda-torchserve @@ -1,19 +1,12 @@ FROM nvidia/cuda:11.8.0-runtime-ubuntu22.04 ENV DEBIAN_FRONTEND=noninteractive WORKDIR /root -RUN apt-get update && \ - apt-get install -y \ - git \ - python3-pip -RUN pip config set global.no-cache-dir false && \ - git clone https://github.com/pytorch/serve -b v0.8.2 && \ - cd serve && \ - python3 ./ts_scripts/install_dependencies.py --cuda cu118 --environment prod && \ - pip3 install . && \ - pip3 install -r examples/object_detector/yolo/yolov8/requirements.txt && \ - cd .. && \ - rm -rf serve +COPY torchserve/install-torchserve.sh /torchserve/install-torchserve.sh +RUN /torchserve/install-torchserve.sh --cuda cu118 RUN /usr/local/bin/torchserve --help +COPY torchserve/config.properties /torchserve/config.properties +COPY torchserve/torchserve-entrypoint.sh /torchserve/torchserve-entrypoint.sh +ENTRYPOINT ["/torchserve/torchserve-entrypoint.sh"] # see Dockerfile.torchserve for example, but use # docker run --gpus all -ti iqtlabs/gamutrf-cuda-torchserve:latest bash diff --git a/docker/Dockerfile.torchserve b/docker/Dockerfile.torchserve index 931a75a2..eb0609a2 100644 --- a/docker/Dockerfile.torchserve +++ b/docker/Dockerfile.torchserve @@ -1,16 +1,9 @@ FROM ubuntu:22.04 ENV DEBIAN_FRONTEND=noninteractive WORKDIR /root -RUN apt-get update && \ - apt-get install -y \ - git \ - python3-pip -RUN pip config set global.no-cache-dir false && \ - git clone https://github.com/pytorch/serve -b v0.8.2 && \ - cd serve && \ - python3 ./ts_scripts/install_dependencies.py --environment prod && \ - pip3 install . && \ - pip3 install -r examples/object_detector/yolo/yolov8/requirements.txt && \ - cd .. && \ - rm -rf serve +COPY torchserve/install-torchserve.sh /torchserve/install-torchserve.sh +RUN /torchserve/install-torchserve.sh RUN /usr/local/bin/torchserve --help +COPY torchserve/config.properties /torchserve/config.properties +COPY torchserve/torchserve-entrypoint.sh /torchserve/torchserve-entrypoint.sh +CMD ["/torchserve/torchserve-entrypoint.sh"] diff --git a/docker/Dockerfile.vkfft b/docker/Dockerfile.vkfft index b071ed12..43a75831 100644 --- a/docker/Dockerfile.vkfft +++ b/docker/Dockerfile.vkfft @@ -8,11 +8,26 @@ RUN apt-get update && apt-get install -y --no-install-recommends \ libvulkan-dev \ python3-dev WORKDIR /root -RUN git clone https://github.com/DTolm/VkFFT -b v1.3.1 -RUN sed -i -E 's/GIT_TAG\s+"origin.main"/GIT_TAG "13.0.0"/g' VkFFT/CMakeLists.txt +RUN git clone https://github.com/DTolm/VkFFT -b v1.3.2 WORKDIR /root/VkFFT/build -RUN CMAKE_BUILD_TYPE=Release cmake .. && make -j "$(nproc)" +RUN CMAKE_BUILD_TYPE=Release cmake -DGLSLANG_GIT_TAG=13.0.0 .. && make -j "$(nproc)" FROM ubuntu:22.04 # TODO: ideally, should be packaged such that cmake can find it. +# hadolint ignore=DL3008 +RUN if [ "$(arch)" = "x86_64" ] ; then \ + apt-get update && \ + apt-get install -y --no-install-recommends ca-certificates dirmngr gpg-agent gpg wget && \ + apt-key adv --fetch-keys "https://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/$(arch)/3bf863cc.pub" && \ + echo "deb http://developer.download.nvidia.com/compute/cuda/repos/ubuntu2204/$(arch)/ /" | tee /etc/apt/sources.list.d/nvidia.list && \ + apt-get update && \ + apt-get install -y --no-install-recommends libnvidia-gl-545 ; \ + fi && \ + apt-get update && apt-get install -y --no-install-recommends \ + libvulkan1 COPY --from=vkfft-builder /root/VkFFT /root/VkFFT +CMD ["/root/VkFFT/build/VkFFT_TestSuite", "-devices"] + +# Test that GPU can be accessed by VkFFT: +# $ docker run --gpus all --device /dev/dri/renderD128:/dev/dri/renderD128 -ti iqtlabs/gamutrf-vkfft +# Device id: 0 name: NVIDIA GeForce RTX 4070 Ti API:1.3.260 diff --git a/docs/README-airt.md b/docs/README-airt.md index f0a79f5d..696e9826 100644 --- a/docs/README-airt.md +++ b/docs/README-airt.md @@ -85,7 +85,7 @@ install gr-iqtlabs $ git clone https://github.com/google/flatbuffers -b v23.5.26 $ git clone https://github.com/nlohmann/json -b v3.11.2 $ git clone https://github.com/deepsig/libsigmf -b v1.0.2 -$ git clone https://github.com/iqtlabs/gr-iqtlabs -b 1.0.44 +$ git clone https://github.com/iqtlabs/gr-iqtlabs -b 1.0.46 $ mkdir -p flatbuffers/build && cd flatbuffers/build && cmake -DCMAKE_INSTALL_PREFIX=~/.conda/envs/$CONDA_DEFAULT_ENV .. && make -j $(nproc) && make install && cd ../.. $ mkdir -p json/build && cd json/build && cmake -DCMAKE_INSTALL_PREFIX=~/.conda/envs/$CONDA_DEFAULT_ENV .. && make -j $(nproc) && make install && cd ../.. $ mkdir -p libsigmf/build && cd libsigmf/build && cmake -DUSE_SYSTEM_JSON=ON -DUSE_SYSTEM_FLATBUFFERS=ON -DCMAKE_INSTALL_PREFIX=~/.conda/envs/$CONDA_DEFAULT_ENV -DCMAKE_CXX_FLAGS="-I $HOME/.conda/envs/$CONDA_DEFAULT_ENV/include" .. && make -j $(nproc) && make install && cd ../.. @@ -132,24 +132,22 @@ On a non-AIRT machine that the AIRT can reach over the network, that has an nvid See https://docs.nvidia.com/datacenter/cloud-native/container-toolkit/latest/install-guide.html -# start torchserve +# create model archive -From gamutRF's source directory: +From gamutRF's source directory, and having obtained mini2_snr.pt: ``` -$ mkdir /tmp/torchserve -$ cp torchserve/config.properities /tmp/torchserve -$ docker run --gpus all -p 8081:8081 -p 8080:8080 -v /tmp/torchserve:/torchserve -d iqtlabs/gamutrf-cuda-torchserve torchserve --start --model-store /torchserve --ts-config /torchserve/config.properties --ncs --foreground +$ pip3 install torch-model-archiver +$ mkdir /tmp/model_store +$ torch-model-archiver --force --model-name mini2_snr --version 1.0 --serialized-file /PATH/TO/mini2_snr.pt --handler torchserve/custom_handler.py --export-path /tmp/model_store ``` -# create and register model +# start torchserve -From gamutRF's source directory, and having obtained mini2_snr.pt: +From gamutRF's source directory (mini2_snr is the default model name in torchserve-cuda.yml): ``` -$ pip3 install torch-model-archiver -$ torch-model-archiver --force --model-name mini2_snr --version 1.0 --serialized-file /PATH/TO/mini2_snr.pt --handler torchserve/custom_handler.py --export-path /tmp/torchserve -$ curl -X POST "localhost:8081/models?model_name=mini2_snr&url=mini2_snr.mar&initial_workers=4&batch_size=2" +$ VOL_PREFIX=/tmp/model_store docker compose -f orchestrator.yml -f torchserve-cuda.yml up -d torchserve ``` Now, when starting the scanner, on the AIRT: diff --git a/gamutrf/grscan.py b/gamutrf/grscan.py index 050c7941..c223b9e2 100644 --- a/gamutrf/grscan.py +++ b/gamutrf/grscan.py @@ -131,6 +131,9 @@ def __init__( logging.info( f"retuning across {freq_range/1e6}MHz in {self.sweep_sec}s, requires retuning at {target_retune_hz}Hz in {tune_step_hz/1e6}MHz steps ({tune_step_fft} FFTs)" ) + if not tune_step_fft: + logging.info("tune_step_fft cannot be 0 - defaulting to nfft") + tune_step_fft = nfft tune_dwell_ms = tune_step_fft / fft_rate * 1e3 logging.info( f"requested retuning across {freq_range/1e6}MHz every {tune_step_fft} FFTs, dwell time {tune_dwell_ms}ms" @@ -151,7 +154,6 @@ def __init__( pretune, ) self.fft_blocks = fft_blocks + self.get_db_blocks(nfft, samp_rate, scaling) - self.fft_to_inference_block = self.fft_blocks[-1] retune_fft = self.iqtlabs.retune_fft( "rx_freq", @@ -179,7 +181,7 @@ def __init__( logging.info("serving FFT on %s", zmq_addr) self.fft_blocks.append((zeromq.pub_sink(1, 1, zmq_addr, 100, False, 65536, ""))) - self.inference_blocks = [] + self.inference_blocks = [blocks.null_sink(gr.sizeof_float * nfft)] if inference_output_dir: x = 640 y = 640 @@ -190,26 +192,24 @@ def __init__( image_dir = Path(inference_output_dir, "images") Path(inference_output_dir).mkdir(parents=True, exist_ok=True) image_dir.mkdir(parents=True, exist_ok=True) - self.image_inference_block = self.iqtlabs.image_inference( - tag="rx_freq", - vlen=nfft, - x=x, - y=y, - image_dir=str(image_dir), - convert_alpha=255, - norm_alpha=0, - norm_beta=1, - norm_type=32, # cv::NORM_MINMAX = 32 - colormap=16, # cv::COLORMAP_VIRIDIS = 16, cv::COLORMAP_TURBO = 20, - interpolation=1, # cv::INTER_LINEAR = 1, - flip=0, - min_peak_points=inference_min_db, - model_server=inference_model_server, - model_name=inference_model_name, - ) self.inference_blocks = [ - blocks.stream_to_vector(gr.sizeof_float * nfft, 1), - self.image_inference_block, + self.iqtlabs.image_inference( + tag="rx_freq", + vlen=nfft, + x=x, + y=y, + image_dir=str(image_dir), + convert_alpha=255, + norm_alpha=0, + norm_beta=1, + norm_type=32, # cv::NORM_MINMAX = 32 + colormap=16, # cv::COLORMAP_VIRIDIS = 16, cv::COLORMAP_TURBO = 20, + interpolation=1, # cv::INTER_LINEAR = 1, + flip=0, + min_peak_points=inference_min_db, + model_server=inference_model_server, + model_name=inference_model_name, + ), yolo_bbox( str(Path(inference_output_dir, "predictions")), inference_min_confidence, @@ -223,17 +223,18 @@ def __init__( else: self.msg_connect((retune_fft, "tune"), (self.sources[0], cmd_port)) self.connect_blocks(self.sources[0], self.sources[1:]) - self.connect_blocks(self.fft_to_inference_block, self.inference_blocks) + self.connect((retune_fft, 1), (self.inference_blocks[0], 0)) + self.connect_blocks(self.inference_blocks[0], self.inference_blocks[1:]) for pipeline_blocks in ( self.fft_blocks, self.samples_blocks, ): self.connect_blocks(self.sources[-1], pipeline_blocks) - def connect_blocks(self, source, other_blocks): + def connect_blocks(self, source, other_blocks, last_block_port=0): last_block = source for block in other_blocks: - self.connect((last_block, 0), (block, 0)) + self.connect((last_block, last_block_port), (block, 0)) last_block = block def get_db_blocks(self, nfft, samp_rate, scaling): diff --git a/gamutrf/scan.py b/gamutrf/scan.py index 351484f3..04462ae8 100644 --- a/gamutrf/scan.py +++ b/gamutrf/scan.py @@ -75,21 +75,21 @@ def argument_parser(): dest="sweep_sec", type=float, default=30, - help="Set sweep_sec [default=%(default)r]", + help="Set sweep_sec [default=%(default)r] - ignored if --tune-dwell-ms > 0 or --tune-step-fft > 0", ) parser.add_argument( "--tune-dwell-ms", dest="tune_dwell_ms", type=float, default=0, - help="Set tune dwell time in ms (0 is use sweep_sec) [default=%(default)r]", + help="Set tune dwell time in ms [default=%(default)r] - ignored if --tune-step-fft > 0", ) parser.add_argument( "--tune-step-fft", dest="tune_step_fft", type=int, default=0, - help="tune FFT step (0 is use sweep_sec) [default=%(default)r]", + help="tune FFT step [default=%(default)r] - if 0, use --tune-dwell-ms (if > 0) or --sweep-sec (if > 0)", ) parser.add_argument( "--skip-tune-step", diff --git a/orchestrator.yml b/orchestrator.yml index 04eb4d0d..79131d9f 100644 --- a/orchestrator.yml +++ b/orchestrator.yml @@ -40,6 +40,16 @@ services: devices: - /dev/bus/usb:/dev/bus/usb - /dev/dri/renderD128:/dev/dri/renderD128 + # Uncomment when using Nvidia GPU (container toolkit etc must be installed) + # deploy: + # resources: + # reservations: + # devices: + # - driver: nvidia + # count: 1 + # capabilities: [gpu] + volumes: + - '${VOL_PREFIX}:/logs' command: - gamutrf-scan - --logaddr=0.0.0.0 @@ -49,8 +59,14 @@ services: - '--freq-end=${FREQ_END}' - --samp-rate=8.192e6 - --nfft=256 - - --sweep-sec=8 + - --tune-dwell-ms=100 + - --tune-step-fft=0 - --db_clamp_floor=-150 + - --fft_batch_size=256 + # - --inference_min_db=-50 + # - --inference_model_name=mini2_snr + # - --inference_model_server=torchserve:8080 + # - --inference_output_dir=/logs/inference healthcheck: test: [CMD, "/gamutrf/bin/scanhc.sh", "9000"] interval: 10s @@ -59,7 +75,7 @@ services: sigfinder: restart: always image: iqtlabs/gamutrf:latest - shm_size: 128m + shm_size: 128m privileged: true networks: - gamutrf @@ -94,6 +110,7 @@ services: - --save_path=/logs - --port=9003 - --detection_type=narrowband + - --n_detect=1 - --width=12 - --height=6 - --min_freq=0 diff --git a/poetry.lock b/poetry.lock index f5b0d037..df908dad 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,9 +1,10 @@ -# This file is automatically @generated by Poetry 1.6.1 and should not be changed by hand. +# This file is automatically @generated by Poetry 1.4.2 and should not be changed by hand. [[package]] name = "anyio" version = "4.0.0" description = "High level compatibility layer for multiple asynchronous event loop implementations" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -23,13 +24,14 @@ trio = ["trio (>=0.22)"] [[package]] name = "astroid" -version = "3.0.0" +version = "3.0.1" description = "An abstract syntax tree for Python with inference support." +category = "dev" optional = false python-versions = ">=3.8.0" files = [ - {file = "astroid-3.0.0-py3-none-any.whl", hash = "sha256:f2510e7fdcd6cfda4ec50014726d4857abf79acfc010084ce8c26091913f1b25"}, - {file = "astroid-3.0.0.tar.gz", hash = "sha256:1defdbca052635dd29657ea674edfc45e4b5be9cd53630c5b084fcfed94344a8"}, + {file = "astroid-3.0.1-py3-none-any.whl", hash = "sha256:7d5895c9825e18079c5aeac0572bc2e4c83205c95d416e0b4fee8bc361d2d9ca"}, + {file = "astroid-3.0.1.tar.gz", hash = "sha256:86b0bb7d7da0be1a7c4aedb7974e391b32d4ed89e33de6ed6902b4b15c97577e"}, ] [package.dependencies] @@ -39,6 +41,7 @@ typing-extensions = {version = ">=4.0.0", markers = "python_version < \"3.11\""} name = "attr" version = "0.3.2" description = "Simple decorator to set attributes of target function or class in a DRY way." +category = "dev" optional = false python-versions = "*" files = [ @@ -50,6 +53,7 @@ files = [ name = "attrs" version = "23.1.0" description = "Classes Without Boilerplate" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -68,6 +72,7 @@ tests-no-zope = ["cloudpickle", "hypothesis", "mypy (>=1.1.1)", "pympler", "pyte name = "bjoern" version = "3.2.2" description = "A screamingly fast Python 2 + 3 WSGI server written in C." +category = "main" optional = false python-versions = "*" files = [ @@ -76,29 +81,30 @@ files = [ [[package]] name = "black" -version = "23.10.0" +version = "23.10.1" description = "The uncompromising code formatter." +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "black-23.10.0-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:f8dc7d50d94063cdfd13c82368afd8588bac4ce360e4224ac399e769d6704e98"}, - {file = "black-23.10.0-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:f20ff03f3fdd2fd4460b4f631663813e57dc277e37fb216463f3b907aa5a9bdd"}, - {file = "black-23.10.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3d9129ce05b0829730323bdcb00f928a448a124af5acf90aa94d9aba6969604"}, - {file = "black-23.10.0-cp310-cp310-win_amd64.whl", hash = "sha256:960c21555be135c4b37b7018d63d6248bdae8514e5c55b71e994ad37407f45b8"}, - {file = "black-23.10.0-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:30b78ac9b54cf87bcb9910ee3d499d2bc893afd52495066c49d9ee6b21eee06e"}, - {file = "black-23.10.0-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:0e232f24a337fed7a82c1185ae46c56c4a6167fb0fe37411b43e876892c76699"}, - {file = "black-23.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31946ec6f9c54ed7ba431c38bc81d758970dd734b96b8e8c2b17a367d7908171"}, - {file = "black-23.10.0-cp311-cp311-win_amd64.whl", hash = "sha256:c870bee76ad5f7a5ea7bd01dc646028d05568d33b0b09b7ecfc8ec0da3f3f39c"}, - {file = "black-23.10.0-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:6901631b937acbee93c75537e74f69463adaf34379a04eef32425b88aca88a23"}, - {file = "black-23.10.0-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:481167c60cd3e6b1cb8ef2aac0f76165843a374346aeeaa9d86765fe0dd0318b"}, - {file = "black-23.10.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f74892b4b836e5162aa0452393112a574dac85e13902c57dfbaaf388e4eda37c"}, - {file = "black-23.10.0-cp38-cp38-win_amd64.whl", hash = "sha256:47c4510f70ec2e8f9135ba490811c071419c115e46f143e4dce2ac45afdcf4c9"}, - {file = "black-23.10.0-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:76baba9281e5e5b230c9b7f83a96daf67a95e919c2dfc240d9e6295eab7b9204"}, - {file = "black-23.10.0-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:a3c2ddb35f71976a4cfeca558848c2f2f89abc86b06e8dd89b5a65c1e6c0f22a"}, - {file = "black-23.10.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db451a3363b1e765c172c3fd86213a4ce63fb8524c938ebd82919bf2a6e28c6a"}, - {file = "black-23.10.0-cp39-cp39-win_amd64.whl", hash = "sha256:7fb5fc36bb65160df21498d5a3dd330af8b6401be3f25af60c6ebfe23753f747"}, - {file = "black-23.10.0-py3-none-any.whl", hash = "sha256:e223b731a0e025f8ef427dd79d8cd69c167da807f5710add30cdf131f13dd62e"}, - {file = "black-23.10.0.tar.gz", hash = "sha256:31b9f87b277a68d0e99d2905edae08807c007973eaa609da5f0c62def6b7c0bd"}, + {file = "black-23.10.1-cp310-cp310-macosx_10_16_arm64.whl", hash = "sha256:ec3f8e6234c4e46ff9e16d9ae96f4ef69fa328bb4ad08198c8cee45bb1f08c69"}, + {file = "black-23.10.1-cp310-cp310-macosx_10_16_x86_64.whl", hash = "sha256:1b917a2aa020ca600483a7b340c165970b26e9029067f019e3755b56e8dd5916"}, + {file = "black-23.10.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c74de4c77b849e6359c6f01987e94873c707098322b91490d24296f66d067dc"}, + {file = "black-23.10.1-cp310-cp310-win_amd64.whl", hash = "sha256:7b4d10b0f016616a0d93d24a448100adf1699712fb7a4efd0e2c32bbb219b173"}, + {file = "black-23.10.1-cp311-cp311-macosx_10_16_arm64.whl", hash = "sha256:b15b75fc53a2fbcac8a87d3e20f69874d161beef13954747e053bca7a1ce53a0"}, + {file = "black-23.10.1-cp311-cp311-macosx_10_16_x86_64.whl", hash = "sha256:e293e4c2f4a992b980032bbd62df07c1bcff82d6964d6c9496f2cd726e246ace"}, + {file = "black-23.10.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7d56124b7a61d092cb52cce34182a5280e160e6aff3137172a68c2c2c4b76bcb"}, + {file = "black-23.10.1-cp311-cp311-win_amd64.whl", hash = "sha256:3f157a8945a7b2d424da3335f7ace89c14a3b0625e6593d21139c2d8214d55ce"}, + {file = "black-23.10.1-cp38-cp38-macosx_10_16_arm64.whl", hash = "sha256:cfcce6f0a384d0da692119f2d72d79ed07c7159879d0bb1bb32d2e443382bf3a"}, + {file = "black-23.10.1-cp38-cp38-macosx_10_16_x86_64.whl", hash = "sha256:33d40f5b06be80c1bbce17b173cda17994fbad096ce60eb22054da021bf933d1"}, + {file = "black-23.10.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:840015166dbdfbc47992871325799fd2dc0dcf9395e401ada6d88fe11498abad"}, + {file = "black-23.10.1-cp38-cp38-win_amd64.whl", hash = "sha256:037e9b4664cafda5f025a1728c50a9e9aedb99a759c89f760bd83730e76ba884"}, + {file = "black-23.10.1-cp39-cp39-macosx_10_16_arm64.whl", hash = "sha256:7cb5936e686e782fddb1c73f8aa6f459e1ad38a6a7b0e54b403f1f05a1507ee9"}, + {file = "black-23.10.1-cp39-cp39-macosx_10_16_x86_64.whl", hash = "sha256:7670242e90dc129c539e9ca17665e39a146a761e681805c54fbd86015c7c84f7"}, + {file = "black-23.10.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed45ac9a613fb52dad3b61c8dea2ec9510bf3108d4db88422bacc7d1ba1243d"}, + {file = "black-23.10.1-cp39-cp39-win_amd64.whl", hash = "sha256:6d23d7822140e3fef190734216cefb262521789367fbdc0b3f22af6744058982"}, + {file = "black-23.10.1-py3-none-any.whl", hash = "sha256:d431e6739f727bb2e0495df64a6c7a5310758e87505f5f8cde9ff6c0f2d7e4fe"}, + {file = "black-23.10.1.tar.gz", hash = "sha256:1f8ce316753428ff68749c65a5f7844631aa18c8679dfd3ca9dc1a289979c258"}, ] [package.dependencies] @@ -120,6 +126,7 @@ uvloop = ["uvloop (>=0.15.2)"] name = "blinker" version = "1.6.2" description = "Fast, simple object-to-object and broadcast signaling" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -131,6 +138,7 @@ files = [ name = "caerus" version = "0.1.9" description = "Python package caerus" +category = "main" optional = false python-versions = ">=3" files = [ @@ -149,6 +157,7 @@ wget = "*" name = "cairocffi" version = "1.6.1" description = "cffi-based cairo bindings for Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -168,6 +177,7 @@ xcb = ["xcffib (>=1.4.0)"] name = "certifi" version = "2023.7.22" description = "Python package for providing Mozilla's CA Bundle." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -179,6 +189,7 @@ files = [ name = "cffi" version = "1.16.0" description = "Foreign Function Interface for Python calling C code." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -243,6 +254,7 @@ pycparser = "*" name = "charset-normalizer" version = "3.3.0" description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +category = "main" optional = false python-versions = ">=3.7.0" files = [ @@ -342,6 +354,7 @@ files = [ name = "click" version = "8.1.7" description = "Composable command line interface toolkit" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -356,6 +369,7 @@ colorama = {version = "*", markers = "platform_system == \"Windows\""} name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" files = [ @@ -367,6 +381,7 @@ files = [ name = "contourpy" version = "1.1.1" description = "Python library for calculating contours of 2D quadrilateral grids" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -441,6 +456,7 @@ test-no-images = ["pytest", "pytest-cov", "wurlitzer"] name = "coverage" version = "7.3.2" description = "Code coverage measurement for Python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -508,6 +524,7 @@ toml = ["tomli"] name = "cycler" version = "0.12.0" description = "Composable style cycles" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -523,6 +540,7 @@ tests = ["pytest", "pytest-cov", "pytest-xdist"] name = "dill" version = "0.3.7" description = "serialize all of Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -537,6 +555,7 @@ graph = ["objgraph (>=1.7.2)"] name = "docker" version = "6.1.3" description = "A Python library for the Docker Engine API." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -558,6 +577,7 @@ ssh = ["paramiko (>=2.4.3)"] name = "exceptiongroup" version = "1.1.3" description = "Backport of PEP 654 (exception groups)" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -572,6 +592,7 @@ test = ["pytest (>=6)"] name = "falcon" version = "3.1.1" description = "The ultra-reliable, fast ASGI+WSGI framework for building data plane APIs at scale." +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -613,6 +634,7 @@ files = [ name = "falcon-cors" version = "1.1.7" description = "Falcon CORS middlware" +category = "main" optional = false python-versions = "*" files = [ @@ -626,6 +648,7 @@ falcon = "*" name = "fancycompleter" version = "0.9.1" description = "colorful TAB completion for Python prompt" +category = "dev" optional = false python-versions = "*" files = [ @@ -639,13 +662,14 @@ pyrepl = ">=0.8.2" [[package]] name = "findpeaks" -version = "2.5.4" +version = "2.5.5" description = "findpeaks is for the detection of peaks and valleys in a 1D vector and 2D array (image)." +category = "main" optional = false python-versions = ">=3" files = [ - {file = "findpeaks-2.5.4-py3-none-any.whl", hash = "sha256:617ad8100d82eb695cd5563746ef52a494db36dcb0cda449fcf5202959576d63"}, - {file = "findpeaks-2.5.4.tar.gz", hash = "sha256:9441e5531ba5ba0fdd941aded154fedd6f08234f388486a8e8bf43a01f1cd917"}, + {file = "findpeaks-2.5.5-py3-none-any.whl", hash = "sha256:489a706789a256b9cc95e2c8c12d1fce53bcb87e34c0c24cdc3f08fba3bffe1a"}, + {file = "findpeaks-2.5.5.tar.gz", hash = "sha256:1310afd69cb08391b71ff3b9712487104231134fa7cc3eb0660d59b1f59e6c4c"}, ] [package.dependencies] @@ -664,6 +688,7 @@ xarray = "*" name = "flask" version = "3.0.0" description = "A simple framework for building complex web applications." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -687,6 +712,7 @@ dotenv = ["python-dotenv"] name = "fonttools" version = "4.43.1" description = "Tools to manipulate font files" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -752,6 +778,7 @@ woff = ["brotli (>=1.0.1)", "brotlicffi (>=0.8.0)", "zopfli (>=0.1.4)"] name = "gpsd-py3" version = "0.3.0" description = "Python 3 library for working with gpsd" +category = "main" optional = false python-versions = "*" files = [ @@ -762,6 +789,7 @@ files = [ name = "h11" version = "0.14.0" description = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -773,6 +801,7 @@ files = [ name = "httpcore" version = "0.18.0" description = "A minimal low-level HTTP client." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -784,16 +813,17 @@ files = [ anyio = ">=3.0,<5.0" certifi = "*" h11 = ">=0.13,<0.15" -sniffio = "==1.*" +sniffio = ">=1.0.0,<2.0.0" [package.extras] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "httpx" version = "0.25.0" description = "The next generation HTTP client." +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -809,14 +839,15 @@ sniffio = "*" [package.extras] brotli = ["brotli", "brotlicffi"] -cli = ["click (==8.*)", "pygments (==2.*)", "rich (>=10,<14)"] +cli = ["click (>=8.0.0,<9.0.0)", "pygments (>=2.0.0,<3.0.0)", "rich (>=10,<14)"] http2 = ["h2 (>=3,<5)"] -socks = ["socksio (==1.*)"] +socks = ["socksio (>=1.0.0,<2.0.0)"] [[package]] name = "idna" version = "3.4" description = "Internationalized Domain Names in Applications (IDNA)" +category = "main" optional = false python-versions = ">=3.5" files = [ @@ -828,6 +859,7 @@ files = [ name = "importlab" version = "0.8.1" description = "A library to calculate python dependency graphs." +category = "dev" optional = false python-versions = ">=3.6.0" files = [ @@ -842,6 +874,7 @@ networkx = ">=2" name = "importlib-metadata" version = "6.8.0" description = "Read metadata from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -861,6 +894,7 @@ testing = ["flufl.flake8", "importlib-resources (>=1.3)", "packaging", "pyfakefs name = "importlib-resources" version = "6.1.0" description = "Read resources from Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -879,6 +913,7 @@ testing = ["pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", name = "iniconfig" version = "2.0.0" description = "brain-dead simple config-ini parsing" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -890,6 +925,7 @@ files = [ name = "isort" version = "5.12.0" description = "A Python utility / library to sort Python imports." +category = "dev" optional = false python-versions = ">=3.8.0" files = [ @@ -907,6 +943,7 @@ requirements-deprecated-finder = ["pip-api", "pipreqs"] name = "itsdangerous" version = "2.1.2" description = "Safely pass data to untrusted environments and back." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -918,6 +955,7 @@ files = [ name = "jinja2" version = "3.1.2" description = "A very fast and expressive template engine." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -935,6 +973,7 @@ i18n = ["Babel (>=2.7)"] name = "joblib" version = "1.3.2" description = "Lightweight pipelining with Python functions" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -946,6 +985,7 @@ files = [ name = "jsonschema" version = "4.19.1" description = "An implementation of JSON Schema validation for Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -967,6 +1007,7 @@ format-nongpl = ["fqdn", "idna", "isoduration", "jsonpointer (>1.13)", "rfc3339- name = "jsonschema-specifications" version = "2023.7.1" description = "The JSON Schema meta-schemas and vocabularies, exposed as a Registry" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -981,6 +1022,7 @@ referencing = ">=0.28.0" name = "kiwisolver" version = "1.4.5" description = "A fast implementation of the Cassowary constraint solver" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1094,6 +1136,7 @@ files = [ name = "libcst" version = "1.1.0" description = "A concrete syntax tree with AST-like properties for Python 3.5, 3.6, 3.7, 3.8, 3.9, and 3.10 programs." +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1142,6 +1185,7 @@ dev = ["Sphinx (>=5.1.1)", "black (==23.9.1)", "build (>=0.10.0)", "coverage (>= name = "markupsafe" version = "2.1.3" description = "Safely add untrusted strings to HTML/XML markup." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1211,6 +1255,7 @@ files = [ name = "matplotlib" version = "3.8.0" description = "Python plotting package" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -1261,6 +1306,7 @@ setuptools_scm = ">=7" name = "mccabe" version = "0.7.0" description = "McCabe checker, plugin for flake8" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1272,6 +1318,7 @@ files = [ name = "mypy-extensions" version = "1.0.0" description = "Type system extensions for programs checked with the mypy type checker." +category = "dev" optional = false python-versions = ">=3.5" files = [ @@ -1283,6 +1330,7 @@ files = [ name = "networkx" version = "3.1" description = "Python package for creating and manipulating graphs and networks" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1301,6 +1349,7 @@ test = ["codecov (>=2.1)", "pytest (>=7.2)", "pytest-cov (>=4.0)"] name = "ninja" version = "1.11.1" description = "Ninja is a small build system with a focus on speed" +category = "dev" optional = false python-versions = "*" files = [ @@ -1330,6 +1379,7 @@ test = ["codecov (>=2.0.5)", "coverage (>=4.2)", "flake8 (>=3.0.4)", "pytest (>= name = "numpy" version = "1.26.1" description = "Fundamental package for array computing in Python" +category = "main" optional = false python-versions = "<3.13,>=3.9" files = [ @@ -1371,6 +1421,7 @@ files = [ name = "opencv-python" version = "4.8.1.78" description = "Wrapper package for OpenCV python bindings." +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -1385,10 +1436,12 @@ files = [ [package.dependencies] numpy = [ - {version = ">=1.21.0", markers = "python_version == \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, - {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\" and python_version < \"3.11\""}, - {version = ">=1.21.2", markers = "platform_system != \"Darwin\" and python_version >= \"3.10\" and python_version < \"3.11\""}, - {version = ">=1.19.3", markers = "platform_system == \"Linux\" and platform_machine == \"aarch64\" and python_version >= \"3.8\" and python_version < \"3.10\" or python_version > \"3.9\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_system != \"Darwin\" and python_version < \"3.10\" or python_version >= \"3.9\" and platform_machine != \"arm64\" and python_version < \"3.10\""}, + {version = ">=1.21.0", markers = "python_version <= \"3.9\" and platform_system == \"Darwin\" and platform_machine == \"arm64\""}, + {version = ">=1.21.2", markers = "python_version >= \"3.10\""}, + {version = ">=1.21.4", markers = "python_version >= \"3.10\" and platform_system == \"Darwin\""}, + {version = ">=1.19.3", markers = "python_version >= \"3.6\" and platform_system == \"Linux\" and platform_machine == \"aarch64\" or python_version >= \"3.9\""}, + {version = ">=1.17.0", markers = "python_version >= \"3.7\""}, + {version = ">=1.17.3", markers = "python_version >= \"3.8\""}, {version = ">=1.23.5", markers = "python_version >= \"3.11\""}, ] @@ -1396,6 +1449,7 @@ numpy = [ name = "packaging" version = "23.2" description = "Core utilities for Python packages" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -1407,6 +1461,7 @@ files = [ name = "paho-mqtt" version = "1.6.1" description = "MQTT version 5.0/3.1.1 client class" +category = "main" optional = false python-versions = "*" files = [ @@ -1418,43 +1473,44 @@ proxy = ["PySocks"] [[package]] name = "pandas" -version = "2.1.1" +version = "2.1.2" description = "Powerful data structures for data analysis, time series, and statistics" +category = "main" optional = false python-versions = ">=3.9" files = [ - {file = "pandas-2.1.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:58d997dbee0d4b64f3cb881a24f918b5f25dd64ddf31f467bb9b67ae4c63a1e4"}, - {file = "pandas-2.1.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:02304e11582c5d090e5a52aec726f31fe3f42895d6bfc1f28738f9b64b6f0614"}, - {file = "pandas-2.1.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ffa8f0966de2c22de408d0e322db2faed6f6e74265aa0856f3824813cf124363"}, - {file = "pandas-2.1.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c1f84c144dee086fe4f04a472b5cd51e680f061adf75c1ae4fc3a9275560f8f4"}, - {file = "pandas-2.1.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:75ce97667d06d69396d72be074f0556698c7f662029322027c226fd7a26965cb"}, - {file = "pandas-2.1.1-cp310-cp310-win_amd64.whl", hash = "sha256:4c3f32fd7c4dccd035f71734df39231ac1a6ff95e8bdab8d891167197b7018d2"}, - {file = "pandas-2.1.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:9e2959720b70e106bb1d8b6eadd8ecd7c8e99ccdbe03ee03260877184bb2877d"}, - {file = "pandas-2.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:25e8474a8eb258e391e30c288eecec565bfed3e026f312b0cbd709a63906b6f8"}, - {file = "pandas-2.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b8bd1685556f3374520466998929bade3076aeae77c3e67ada5ed2b90b4de7f0"}, - {file = "pandas-2.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dc3657869c7902810f32bd072f0740487f9e030c1a3ab03e0af093db35a9d14e"}, - {file = "pandas-2.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:05674536bd477af36aa2effd4ec8f71b92234ce0cc174de34fd21e2ee99adbc2"}, - {file = "pandas-2.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:b407381258a667df49d58a1b637be33e514b07f9285feb27769cedb3ab3d0b3a"}, - {file = "pandas-2.1.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c747793c4e9dcece7bb20156179529898abf505fe32cb40c4052107a3c620b49"}, - {file = "pandas-2.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:3bcad1e6fb34b727b016775bea407311f7721db87e5b409e6542f4546a4951ea"}, - {file = "pandas-2.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f5ec7740f9ccb90aec64edd71434711f58ee0ea7f5ed4ac48be11cfa9abf7317"}, - {file = "pandas-2.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:29deb61de5a8a93bdd033df328441a79fcf8dd3c12d5ed0b41a395eef9cd76f0"}, - {file = "pandas-2.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4f99bebf19b7e03cf80a4e770a3e65eee9dd4e2679039f542d7c1ace7b7b1daa"}, - {file = "pandas-2.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:84e7e910096416adec68075dc87b986ff202920fb8704e6d9c8c9897fe7332d6"}, - {file = "pandas-2.1.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:366da7b0e540d1b908886d4feb3d951f2f1e572e655c1160f5fde28ad4abb750"}, - {file = "pandas-2.1.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:9e50e72b667415a816ac27dfcfe686dc5a0b02202e06196b943d54c4f9c7693e"}, - {file = "pandas-2.1.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cc1ab6a25da197f03ebe6d8fa17273126120874386b4ac11c1d687df288542dd"}, - {file = "pandas-2.1.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0dbfea0dd3901ad4ce2306575c54348d98499c95be01b8d885a2737fe4d7a98"}, - {file = "pandas-2.1.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:0489b0e6aa3d907e909aef92975edae89b1ee1654db5eafb9be633b0124abe97"}, - {file = "pandas-2.1.1-cp39-cp39-win_amd64.whl", hash = "sha256:4cdb0fab0400c2cb46dafcf1a0fe084c8bb2480a1fa8d81e19d15e12e6d4ded2"}, - {file = "pandas-2.1.1.tar.gz", hash = "sha256:fecb198dc389429be557cde50a2d46da8434a17fe37d7d41ff102e3987fd947b"}, + {file = "pandas-2.1.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:24057459f19db9ebb02984c6fdd164a970b31a95f38e4a49cf7615b36a1b532c"}, + {file = "pandas-2.1.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:a6cf8fcc8a63d333970b950a7331a30544cf59b1a97baf0a7409e09eafc1ac38"}, + {file = "pandas-2.1.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ae6ffbd9d614c20d028c7117ee911fc4e266b4dca2065d5c5909e401f8ff683"}, + {file = "pandas-2.1.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eff794eeb7883c5aefb1ed572e7ff533ae779f6c6277849eab9e77986e352688"}, + {file = "pandas-2.1.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:02954e285e8e2f4006b6f22be6f0df1f1c3c97adbb7ed211c6b483426f20d5c8"}, + {file = "pandas-2.1.2-cp310-cp310-win_amd64.whl", hash = "sha256:5b40c9f494e1f27588c369b9e4a6ca19cd924b3a0e1ef9ef1a8e30a07a438f43"}, + {file = "pandas-2.1.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:08d287b68fd28906a94564f15118a7ca8c242e50ae7f8bd91130c362b2108a81"}, + {file = "pandas-2.1.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bbd98dcdcd32f408947afdb3f7434fade6edd408c3077bbce7bd840d654d92c6"}, + {file = "pandas-2.1.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e90c95abb3285d06f6e4feedafc134306a8eced93cb78e08cf50e224d5ce22e2"}, + {file = "pandas-2.1.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:52867d69a54e71666cd184b04e839cff7dfc8ed0cd6b936995117fdae8790b69"}, + {file = "pandas-2.1.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:8d0382645ede2fde352da2a885aac28ec37d38587864c0689b4b2361d17b1d4c"}, + {file = "pandas-2.1.2-cp311-cp311-win_amd64.whl", hash = "sha256:65177d1c519b55e5b7f094c660ed357bb7d86e799686bb71653b8a4803d8ff0d"}, + {file = "pandas-2.1.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:5aa6b86802e8cf7716bf4b4b5a3c99b12d34e9c6a9d06dad254447a620437931"}, + {file = "pandas-2.1.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:d594e2ce51b8e0b4074e6644758865dc2bb13fd654450c1eae51201260a539f1"}, + {file = "pandas-2.1.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3223f997b6d2ebf9c010260cf3d889848a93f5d22bb4d14cd32638b3d8bba7ad"}, + {file = "pandas-2.1.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc4944dc004ca6cc701dfa19afb8bdb26ad36b9bed5bcec617d2a11e9cae6902"}, + {file = "pandas-2.1.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:3f76280ce8ec216dde336e55b2b82e883401cf466da0fe3be317c03fb8ee7c7d"}, + {file = "pandas-2.1.2-cp312-cp312-win_amd64.whl", hash = "sha256:7ad20d24acf3a0042512b7e8d8fdc2e827126ed519d6bd1ed8e6c14ec8a2c813"}, + {file = "pandas-2.1.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:021f09c15e1381e202d95d4a21ece8e7f2bf1388b6d7e9cae09dfe27bd2043d1"}, + {file = "pandas-2.1.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:e7f12b2de0060b0b858cfec0016e7d980ae5bae455a1746bfcc70929100ee633"}, + {file = "pandas-2.1.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:83c166b9bb27c1715bed94495d9598a7f02950b4749dba9349c1dd2cbf10729d"}, + {file = "pandas-2.1.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:25c9976c17311388fcd953cb3d0697999b2205333f4e11e669d90ff8d830d429"}, + {file = "pandas-2.1.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:851b5afbb0d62f6129ae891b533aa508cc357d5892c240c91933d945fff15731"}, + {file = "pandas-2.1.2-cp39-cp39-win_amd64.whl", hash = "sha256:e78507adcc730533619de07bfdd1c62b2918a68cd4419ea386e28abf7f6a1e5c"}, + {file = "pandas-2.1.2.tar.gz", hash = "sha256:52897edc2774d2779fbeb6880d2cfb305daa0b1a29c16b91f531a18918a6e0f3"}, ] [package.dependencies] numpy = [ - {version = ">=1.22.4", markers = "python_version < \"3.11\""}, - {version = ">=1.26.0", markers = "python_version >= \"3.12\""}, - {version = ">=1.23.2", markers = "python_version == \"3.11\""}, + {version = ">=1.22.4,<2", markers = "python_version < \"3.11\""}, + {version = ">=1.23.2,<2", markers = "python_version == \"3.11\""}, + {version = ">=1.26.0,<2", markers = "python_version >= \"3.12\""}, ] python-dateutil = ">=2.8.2" pytz = ">=2020.1" @@ -1488,6 +1544,7 @@ xml = ["lxml (>=4.8.0)"] name = "pathspec" version = "0.11.2" description = "Utility library for gitignore style pattern matching of file paths." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1499,6 +1556,7 @@ files = [ name = "pdbpp" version = "0.10.3" description = "pdb++, a drop-in replacement for pdb" +category = "dev" optional = false python-versions = "*" files = [ @@ -1519,6 +1577,7 @@ testing = ["funcsigs", "pytest"] name = "peakdetect" version = "1.1" description = "Analytic peak finder" +category = "main" optional = false python-versions = "*" files = [ @@ -1534,6 +1593,7 @@ scipy = "*" name = "pillow" version = "10.0.1" description = "Python Imaging Library (Fork)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -1601,6 +1661,7 @@ tests = ["check-manifest", "coverage", "defusedxml", "markdown2", "olefile", "pa name = "platformdirs" version = "3.11.0" description = "A small Python package for determining appropriate platform-specific dirs, e.g. a \"user data dir\"." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1616,6 +1677,7 @@ test = ["appdirs (==1.4.4)", "covdefaults (>=2.3)", "pytest (>=7.4)", "pytest-co name = "pluggy" version = "1.3.0" description = "plugin and hook calling mechanisms for python" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1629,13 +1691,14 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "prometheus-client" -version = "0.17.1" +version = "0.18.0" description = "Python client for the Prometheus monitoring system." +category = "main" optional = false -python-versions = ">=3.6" +python-versions = ">=3.8" files = [ - {file = "prometheus_client-0.17.1-py3-none-any.whl", hash = "sha256:e537f37160f6807b8202a6fc4764cdd19bac5480ddd3e0d463c3002b34462101"}, - {file = "prometheus_client-0.17.1.tar.gz", hash = "sha256:21e674f39831ae3f8acde238afd9a27a37d0d2fb5a28ea094f0ce25d2cbf2091"}, + {file = "prometheus_client-0.18.0-py3-none-any.whl", hash = "sha256:8de3ae2755f890826f4b6479e5571d4f74ac17a81345fe69a6778fdb92579184"}, + {file = "prometheus_client-0.18.0.tar.gz", hash = "sha256:35f7a8c22139e2bb7ca5a698e92d38145bc8dc74c1c0bf56f25cca886a764e17"}, ] [package.extras] @@ -1643,32 +1706,34 @@ twisted = ["twisted"] [[package]] name = "pycairo" -version = "1.25.0" +version = "1.25.1" description = "Python interface for cairo" +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "pycairo-1.25.0-cp310-cp310-win32.whl", hash = "sha256:a8b08f198a45b5e505c1475ed9c3b1a39993b9ebff0e18dd9f194927de6411b7"}, - {file = "pycairo-1.25.0-cp310-cp310-win_amd64.whl", hash = "sha256:f5d29720075d0d3cc1eef8abb3a3069951b466f04583976adfd770e71bc5be3a"}, - {file = "pycairo-1.25.0-cp310-cp310-win_arm64.whl", hash = "sha256:7f1390e5e81719bfcf30ad667c09188caa1d3bd190f9af40efcd13e25b7cf25b"}, - {file = "pycairo-1.25.0-cp311-cp311-win32.whl", hash = "sha256:2e4da8be0a696c2e8a1709f5a2bd849e802147769439ea4268f926695f4b5a55"}, - {file = "pycairo-1.25.0-cp311-cp311-win_amd64.whl", hash = "sha256:c40ce034a07266460bc3318a179aa43b2824d36754906831a90c99fb4f246370"}, - {file = "pycairo-1.25.0-cp311-cp311-win_arm64.whl", hash = "sha256:6654201d10c5f13975caec648796b1e0e2b0f8af1e4302a086dc3183bb8346ee"}, - {file = "pycairo-1.25.0-cp312-cp312-win32.whl", hash = "sha256:caa76409cae523f7c5254ee75935d8d520efa96eaf22c64f26c8e24ca74f8281"}, - {file = "pycairo-1.25.0-cp312-cp312-win_amd64.whl", hash = "sha256:ec0e05fe7a0d2fc1ef0d6babc19b8b2d731af3ab1638fcdcaad2d42204a487f2"}, - {file = "pycairo-1.25.0-cp312-cp312-win_arm64.whl", hash = "sha256:8690cc2cba6bd223cc9703a9a7b392fe1bec78003662c6dbc9869d81ee343bdf"}, - {file = "pycairo-1.25.0-cp38-cp38-win32.whl", hash = "sha256:439c62c3c744aabb70ab6b97f04e0d58e587cc35c2e9f52d1bb2f47f852ea2de"}, - {file = "pycairo-1.25.0-cp38-cp38-win_amd64.whl", hash = "sha256:9f0ee34c6ca1e7ef970d51fb68e5a6a02a374d2e679ceddf891dfc53408b11c7"}, - {file = "pycairo-1.25.0-cp39-cp39-win32.whl", hash = "sha256:659b0b701767bbfe16ad3cb291717039555bf4d0b857f64acc7e40e1b39660bc"}, - {file = "pycairo-1.25.0-cp39-cp39-win_amd64.whl", hash = "sha256:1eb0fe7738e770057017f185a76aaad9aa280da1bdf0571fb85b7e116eeb3001"}, - {file = "pycairo-1.25.0-cp39-cp39-win_arm64.whl", hash = "sha256:c986f7ee44dee9c6b119604f8f33480d9f5410e550a8bbda5d333742a867a53c"}, - {file = "pycairo-1.25.0.tar.gz", hash = "sha256:37842b9bfa6339c45a5025f752e1d78d5840b1a0f82303bdd5610846ad8b5c4f"}, + {file = "pycairo-1.25.1-cp310-cp310-win32.whl", hash = "sha256:cacb5c2abbfdfc79c728ab261ff791511e4957b606c660f9b380975b678b728f"}, + {file = "pycairo-1.25.1-cp310-cp310-win_amd64.whl", hash = "sha256:109ebbeb5bbc510b726fc31251071264dec241e5084d0668f846d7e17e5af8e0"}, + {file = "pycairo-1.25.1-cp310-cp310-win_arm64.whl", hash = "sha256:b19269a8bf9ab5e3c617f2699bed00977fd02ff304339a233654456c0236f7c6"}, + {file = "pycairo-1.25.1-cp311-cp311-win32.whl", hash = "sha256:b10e58a3ce41e487aae15050b630742e880d4135cee7a69cee2c0ea2a0b4bd0a"}, + {file = "pycairo-1.25.1-cp311-cp311-win_amd64.whl", hash = "sha256:fcf5511b05a652a0ef87f626bf26bfc1b796a67f0d1bd40781c62986fb41c356"}, + {file = "pycairo-1.25.1-cp311-cp311-win_arm64.whl", hash = "sha256:4133ba3ef6d875aa1b16643dc0801846f463b8e78750f5308c41902dfeac5b9a"}, + {file = "pycairo-1.25.1-cp312-cp312-win32.whl", hash = "sha256:56fee2837a07ecd914f4fbf78ff59445f78becd658fe36125101925dd489eb94"}, + {file = "pycairo-1.25.1-cp312-cp312-win_amd64.whl", hash = "sha256:fb31eec2c41ec74e23dc0fc9feb4007b4c37f78ec76220ed92530b342e09821a"}, + {file = "pycairo-1.25.1-cp312-cp312-win_arm64.whl", hash = "sha256:27011d822952d7817130fc17f490de94328590bc8d45bdbca9ec4a47039fca22"}, + {file = "pycairo-1.25.1-cp38-cp38-win32.whl", hash = "sha256:9a7c5ed92fe87f60e9796777d5255f2df2deeb8ab1e3c296e67a1d8c9790808c"}, + {file = "pycairo-1.25.1-cp38-cp38-win_amd64.whl", hash = "sha256:48603ad31616140ad6fa097f13086d0ce8f29ead35ad6a215962f3b0496a5a70"}, + {file = "pycairo-1.25.1-cp39-cp39-win32.whl", hash = "sha256:97666c084e9eb1c08c7fd6d306d153767acdf03c0d80349ec55863cecd4138e0"}, + {file = "pycairo-1.25.1-cp39-cp39-win_amd64.whl", hash = "sha256:ac5437d140eccd97af12a618cc1ace0d9a85f1269f29e963751949f132828b21"}, + {file = "pycairo-1.25.1-cp39-cp39-win_arm64.whl", hash = "sha256:bda5d10adbf1f5eba6b524b5a70ccf7f659680b77e691ff94b312f25a6fcc91f"}, + {file = "pycairo-1.25.1.tar.gz", hash = "sha256:7e2be4fbc3b4536f16db7a11982cbf713e75069a4d73d44fe5a49b68423f5c0c"}, ] [[package]] name = "pycnite" version = "2023.10.11" description = "Python bytecode utilities" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -1680,6 +1745,7 @@ files = [ name = "pycparser" version = "2.21" description = "C parser in Python" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1691,6 +1757,7 @@ files = [ name = "pydot" version = "1.4.2" description = "Python interface to Graphviz's Dot" +category = "dev" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" files = [ @@ -1705,6 +1772,7 @@ pyparsing = ">=2.1.4" name = "pygments" version = "2.16.1" description = "Pygments is a syntax highlighting package written in Python." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1717,22 +1785,23 @@ plugins = ["importlib-metadata"] [[package]] name = "pylint" -version = "3.0.1" +version = "3.0.2" description = "python code static checker" +category = "dev" optional = false python-versions = ">=3.8.0" files = [ - {file = "pylint-3.0.1-py3-none-any.whl", hash = "sha256:9c90b89e2af7809a1697f6f5f93f1d0e518ac566e2ac4d2af881a69c13ad01ea"}, - {file = "pylint-3.0.1.tar.gz", hash = "sha256:81c6125637be216b4652ae50cc42b9f8208dfb725cdc7e04c48f6902f4dbdf40"}, + {file = "pylint-3.0.2-py3-none-any.whl", hash = "sha256:60ed5f3a9ff8b61839ff0348b3624ceeb9e6c2a92c514d81c9cc273da3b6bcda"}, + {file = "pylint-3.0.2.tar.gz", hash = "sha256:0d4c286ef6d2f66c8bfb527a7f8a629009e42c99707dec821a03e1b51a4c1496"}, ] [package.dependencies] -astroid = ">=3.0.0,<=3.1.0-dev0" +astroid = ">=3.0.1,<=3.1.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\""}, {version = ">=0.3.7", markers = "python_version >= \"3.12\""}, - {version = ">=0.3.6", markers = "python_version >= \"3.11\" and python_version < \"3.12\""}, ] isort = ">=4.2.5,<6" mccabe = ">=0.6,<0.8" @@ -1749,6 +1818,7 @@ testutils = ["gitpython (>3)"] name = "pyparsing" version = "3.1.1" description = "pyparsing module - Classes and methods to define and execute parsing grammars" +category = "main" optional = false python-versions = ">=3.6.8" files = [ @@ -1763,6 +1833,7 @@ diagrams = ["jinja2", "railroad-diagrams"] name = "pyreadline" version = "2.1" description = "A python implmementation of GNU readline." +category = "dev" optional = false python-versions = "*" files = [ @@ -1773,6 +1844,7 @@ files = [ name = "pyrepl" version = "0.9.0" description = "A library for building flexible command line interfaces" +category = "dev" optional = false python-versions = "*" files = [ @@ -1781,13 +1853,14 @@ files = [ [[package]] name = "pytest" -version = "7.4.2" +version = "7.4.3" description = "pytest: simple powerful testing with Python" +category = "dev" optional = false python-versions = ">=3.7" files = [ - {file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"}, - {file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"}, + {file = "pytest-7.4.3-py3-none-any.whl", hash = "sha256:0d009c083ea859a71b76adf7c1d502e4bc170b80a8ef002da5806527b9591fac"}, + {file = "pytest-7.4.3.tar.gz", hash = "sha256:d989d136982de4e3b29dabcc838ad581c64e8ed52c11fbe86ddebd9da0818cd5"}, ] [package.dependencies] @@ -1805,6 +1878,7 @@ testing = ["argcomplete", "attrs (>=19.2.0)", "hypothesis (>=3.56)", "mock", "no name = "pytest-cov" version = "4.1.0" description = "Pytest plugin for measuring coverage." +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -1823,6 +1897,7 @@ testing = ["fields", "hunter", "process-tests", "pytest-xdist", "six", "virtuale name = "python-dateutil" version = "2.8.2" description = "Extensions to the standard Python datetime module" +category = "main" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" files = [ @@ -1835,12 +1910,25 @@ six = ">=1.5" [[package]] name = "pytype" -version = "2023.10.17" +version = "2023.10.24" description = "Python type inferencer" +category = "dev" optional = false python-versions = ">=3.8" files = [ - {file = "pytype-2023.10.17.tar.gz", hash = "sha256:e94151428769bccd2410b7407edd84fb383c1bbe26f4925906d214a4c3853ca7"}, + {file = "pytype-2023.10.24-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:5ac150ea9f665ce19ea425014baf9d240df8edbcd7555097cce840a9e06efec1"}, + {file = "pytype-2023.10.24-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8f81e31954558cd50a6ae030833024a65776e44ae2873f45a635e637eb911805"}, + {file = "pytype-2023.10.24-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4184269756f3d2ae3d4c9fd443b955902fe8660ab1b111599eb1511376664157"}, + {file = "pytype-2023.10.24-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:a23349f3eef83d6c890ea31947f2558c3433b876eff836644340579de0f9b857"}, + {file = "pytype-2023.10.24-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9d47b5581566a8c7e8253346ffbf5cdda363e58e2b20cb7f4c78b7efda8d24a"}, + {file = "pytype-2023.10.24-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ddaab1f8f5ff34b29ff98831a227b045153dd84ab57dd0bdab26efe8ee297041"}, + {file = "pytype-2023.10.24-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:5f17b3a96de448aacf6b12c83f9ea609497521be8074a02808b65fca163baadd"}, + {file = "pytype-2023.10.24-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9fbdc8fa5e0a5c4e874a53841ff22c2dd76b3db2095768f2f491fd414b6997aa"}, + {file = "pytype-2023.10.24-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2b043619fc65130b1db112735053732d88f327771a8d633258384a6772b98db3"}, + {file = "pytype-2023.10.24-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:fa5f777157eac18358f486d5bd027dad7acdbf412156f6151c994c2131f3c9de"}, + {file = "pytype-2023.10.24-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7730ec5ee53d83648ce7655030626d04a7c3ec9c2aca78467305a6a20e03ba83"}, + {file = "pytype-2023.10.24-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:480031b57775bfb69592254bf10b8912a4c543a9cada9dba0a2dd0a2123babc9"}, + {file = "pytype-2023.10.24.tar.gz", hash = "sha256:18e52ae23e4d7d8aa62a975fd93c5b553e96804a9890095511da81e88a33d366"}, ] [package.dependencies] @@ -1860,6 +1948,7 @@ typing-extensions = ">=4.3.0" name = "pytz" version = "2023.3.post1" description = "World timezone definitions, modern and historical" +category = "main" optional = false python-versions = "*" files = [ @@ -1871,6 +1960,7 @@ files = [ name = "pywin32" version = "306" description = "Python for Window Extensions" +category = "dev" optional = false python-versions = "*" files = [ @@ -1894,6 +1984,7 @@ files = [ name = "pyyaml" version = "6.0.1" description = "YAML parser and emitter for Python" +category = "dev" optional = false python-versions = ">=3.6" files = [ @@ -1953,6 +2044,7 @@ files = [ name = "pyzmq" version = "25.1.1" description = "Python bindings for 0MQ" +category = "main" optional = false python-versions = ">=3.6" files = [ @@ -2058,6 +2150,7 @@ cffi = {version = "*", markers = "implementation_name == \"pypy\""} name = "referencing" version = "0.30.2" description = "JSON Referencing + Python" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2073,6 +2166,7 @@ rpds-py = ">=0.7.0" name = "requests" version = "2.31.0" description = "Python HTTP for Humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2094,6 +2188,7 @@ use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] name = "rpds-py" version = "0.10.4" description = "Python bindings to Rust's persistent data structures (rpds)" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2202,6 +2297,7 @@ files = [ name = "rpi-gpio" version = "0.7.1" description = "A module to control Raspberry Pi GPIO channels" +category = "main" optional = false python-versions = "*" files = [ @@ -2217,6 +2313,7 @@ files = [ name = "schedule" version = "1.2.1" description = "Job scheduling for humans." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2228,6 +2325,7 @@ files = [ name = "scipy" version = "1.11.3" description = "Fundamental algorithms for scientific computing in Python" +category = "main" optional = false python-versions = "<3.13,>=3.9" files = [ @@ -2270,6 +2368,7 @@ test = ["asv", "gmpy2", "mpmath", "pooch", "pytest", "pytest-cov", "pytest-timeo name = "setuptools" version = "68.2.2" description = "Easily download, build, install, upgrade, and uninstall Python packages" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2286,6 +2385,7 @@ testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jar name = "setuptools-scm" version = "8.0.4" description = "the blessed package to manage your versions by scm tags" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2308,6 +2408,7 @@ test = ["build", "pytest", "rich", "wheel"] name = "sigmf" version = "1.1.3" description = "Python module for interacting with SigMF recordings." +category = "main" optional = false python-versions = "*" files = [ @@ -2326,6 +2427,7 @@ gui = ["pysimplegui (==4.0.0)"] name = "six" version = "1.16.0" description = "Python 2 and 3 compatibility utilities" +category = "main" optional = false python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2337,6 +2439,7 @@ files = [ name = "sniffio" version = "1.3.0" description = "Sniff out which async library your code is running under" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2348,6 +2451,7 @@ files = [ name = "sysrsync" version = "1.1.1" description = "Simple and safe python wrapper for calling system rsync" +category = "main" optional = false python-versions = ">=3.6,<4.0" files = [ @@ -2362,6 +2466,7 @@ toml = ">=0.10.0,<0.11.0" name = "tabulate" version = "0.9.0" description = "Pretty-print tabular data" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2376,6 +2481,7 @@ widechars = ["wcwidth"] name = "toml" version = "0.10.2" description = "Python Library for Tom's Obvious, Minimal Language" +category = "main" optional = false python-versions = ">=2.6, !=3.0.*, !=3.1.*, !=3.2.*" files = [ @@ -2387,6 +2493,7 @@ files = [ name = "tomli" version = "2.0.1" description = "A lil' TOML parser" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2398,6 +2505,7 @@ files = [ name = "tomlkit" version = "0.12.1" description = "Style preserving TOML library" +category = "dev" optional = false python-versions = ">=3.7" files = [ @@ -2409,6 +2517,7 @@ files = [ name = "tqdm" version = "4.66.1" description = "Fast, Extensible Progress Meter" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2429,6 +2538,7 @@ telegram = ["requests"] name = "typing-extensions" version = "4.8.0" description = "Backported and Experimental Type Hints for Python 3.8+" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2440,6 +2550,7 @@ files = [ name = "typing-inspect" version = "0.9.0" description = "Runtime inspection utilities for typing module." +category = "dev" optional = false python-versions = "*" files = [ @@ -2455,6 +2566,7 @@ typing-extensions = ">=3.7.4" name = "tzdata" version = "2023.3" description = "Provider of IANA time zone data" +category = "main" optional = false python-versions = ">=2" files = [ @@ -2466,6 +2578,7 @@ files = [ name = "urllib3" version = "2.0.7" description = "HTTP library with thread-safe connection pooling, file post, and more." +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2483,6 +2596,7 @@ zstd = ["zstandard (>=0.18.0)"] name = "websocket-client" version = "1.6.3" description = "WebSocket client for Python with low level API options" +category = "dev" optional = false python-versions = ">=3.8" files = [ @@ -2497,13 +2611,14 @@ test = ["websockets"] [[package]] name = "werkzeug" -version = "3.0.0" +version = "3.0.1" description = "The comprehensive WSGI web application library." +category = "main" optional = false python-versions = ">=3.8" files = [ - {file = "werkzeug-3.0.0-py3-none-any.whl", hash = "sha256:cbb2600f7eabe51dbc0502f58be0b3e1b96b893b05695ea2b35b43d4de2d9962"}, - {file = "werkzeug-3.0.0.tar.gz", hash = "sha256:3ffff4dcc32db52ef3cc94dff3000a3c2846890f3a5a51800a27b909c5e770f0"}, + {file = "werkzeug-3.0.1-py3-none-any.whl", hash = "sha256:90a285dc0e42ad56b34e696398b8122ee4c681833fb35b8334a095d82c56da10"}, + {file = "werkzeug-3.0.1.tar.gz", hash = "sha256:507e811ecea72b18a404947aded4b3390e1db8f826b494d76550ef45bb3b1dcc"}, ] [package.dependencies] @@ -2516,6 +2631,7 @@ watchdog = ["watchdog (>=2.3)"] name = "wget" version = "3.2" description = "pure python download utility" +category = "main" optional = false python-versions = "*" files = [ @@ -2526,6 +2642,7 @@ files = [ name = "wmctrl" version = "0.5" description = "A tool to programmatically control windows inside X" +category = "dev" optional = false python-versions = ">=2.7" files = [ @@ -2543,6 +2660,7 @@ test = ["pytest"] name = "xarray" version = "2023.9.0" description = "N-D labeled arrays and datasets in Python" +category = "main" optional = false python-versions = ">=3.9" files = [ @@ -2566,6 +2684,7 @@ viz = ["matplotlib", "nc-time-axis", "seaborn"] name = "zipp" version = "3.17.0" description = "Backport of pathlib-compatible object wrapper for zip files" +category = "main" optional = false python-versions = ">=3.8" files = [ @@ -2581,6 +2700,7 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p name = "zstandard" version = "0.21.0" description = "Zstandard bindings for Python" +category = "main" optional = false python-versions = ">=3.7" files = [ @@ -2638,4 +2758,4 @@ cffi = ["cffi (>=1.11)"] [metadata] lock-version = "2.0" python-versions = ">=3.9,<3.13" -content-hash = "c8d8158767facf4c4f86b7d7a2f69b20fc452f2bdbcd8b61c663a1f20d54c8fa" +content-hash = "bc3b8c2235ecc7e29e11be1ea79aad8a5e0406794b4e0bb87c808988aa841f6a" diff --git a/pyproject.toml b/pyproject.toml index 940d30fd..82a8141a 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -14,15 +14,15 @@ python = ">=3.9,<3.13" bjoern = "3.2.2" falcon = "3.1.1" falcon-cors = "1.1.7" -findpeaks = "2.5.4" +findpeaks = "2.5.5" gpsd-py3 = "0.3.0" httpx = "0.25.0" Jinja2 = "3.1.2" matplotlib = "3.8.0" numpy = "1.26.1" paho-mqtt = "1.6.1" -pandas = "2.1.1" -prometheus_client = "0.17.1" +pandas = "2.1.2" +prometheus_client = "0.18.0" requests = "2.31.0" "RPi.GPIO" = {version = "0.7.1", markers = "platform_machine != 'aarch64'"} schedule = "1.2.1" @@ -39,12 +39,12 @@ pyzmq = "^25.1.0" [tool.poetry.dev-dependencies] attr = "0.3.2" attrs = "23.1.0" -black = "23.10.0" +black = "23.10.1" docker = "6.1.3" -pylint = "3.0.1" -pytest = "7.4.2" +pylint = "3.0.2" +pytest = "7.4.3" pytest-cov = "4.1.0" -pytype = "2023.10.17" +pytype = "2023.10.24" pdbpp = "^0.10.3" [tool.poetry.scripts] diff --git a/specgram.yml b/specgram.yml index 1468d5d2..2915757c 100644 --- a/specgram.yml +++ b/specgram.yml @@ -1,5 +1,5 @@ -# On Pi4/Ubuntu, also requires systemd.unified_cgroup_hierarchy=0 added to /boot/firmware/cmdline.txt, -# to fall back to cgroup v1. +# On Pi4/Ubuntu, also requires systemd.unified_cgroup_hierarchy=0 added to +# /boot/firmware/cmdline.txt, to fall back to cgroup v1. version: "3.3" networks: gamutrf: diff --git a/tests/test_torchserve.sh b/tests/test_torchserve.sh index 4aff7fc3..f702de8a 100755 --- a/tests/test_torchserve.sh +++ b/tests/test_torchserve.sh @@ -2,7 +2,7 @@ set -e TMPDIR=/tmp -sudo apt-get update && sudo apt-get install -y curl jq wget +sudo apt-get update && sudo apt-get install -y jq wget sudo pip3 install torch-model-archiver cp torchserve/custom_handler.py $TMPDIR/ cd $TMPDIR @@ -11,9 +11,7 @@ wget https://github.com/ultralytics/assets/releases/download/v0.0.0/yolov8n.pt torch-model-archiver --force --model-name yolov8n --version 1.0 --serialized-file yolov8n.pt --handler custom_handler.py rm -rf model_store && mkdir model_store mv yolov8n.mar model_store/ -docker run -v $(pwd)/model_store:/model_store --net host -d iqtlabs/gamutrf-torchserve timeout 60s torchserve --start --model-store /model_store --ncs --foreground -sleep 5 -curl -X POST "localhost:8081/models?model_name=yolov8n&url=yolov8n.mar&initial_workers=4&batch_size=2" +docker run -v $(pwd)/model_store:/model_store --net host --entrypoint timeout -d iqtlabs/gamutrf-torchserve 60s /torchserve/torchserve-entrypoint.sh --models yolov8n=yolov8n.mar # TODO: use gamutRF test spectogram image wget https://github.com/pytorch/serve/raw/master/examples/object_detector/yolo/yolov8/persons.jpg -curl http://127.0.0.1:8080/predictions/yolov8n -T persons.jpg | jq +wget -q --retry-connrefused --retry-on-host-error --body-file=persons.jpg --method=PUT -O- --header='Content-Type: image/jpg' http://127.0.0.1:8080/predictions/yolov8n | jq diff --git a/torchserve-cuda.yml b/torchserve-cuda.yml new file mode 100644 index 00000000..8d6e6043 --- /dev/null +++ b/torchserve-cuda.yml @@ -0,0 +1,22 @@ +version: "3.3" +networks: + gamutrf: +services: + torchserve: + restart: always + image: iqtlabs/gamutrf-cuda-torchserve:latest + networks: + - gamutrf + ports: + - '8080:8080' + volumes: + - '${VOL_PREFIX}:/model_store' + deploy: + resources: + reservations: + devices: + - driver: nvidia + count: 1 + capabilities: [gpu] + command: + - --models mini2_snr=mini2_snr.mar diff --git a/torchserve.yml b/torchserve.yml new file mode 100644 index 00000000..9092acb5 --- /dev/null +++ b/torchserve.yml @@ -0,0 +1,15 @@ +version: "3.3" +networks: + gamutrf: +services: + torchserve: + restart: always + image: iqtlabs/gamutrf-torchserve:latest + networks: + - gamutrf + ports: + - '8080:8080' + volumes: + - '${VOL_PREFIX}:/model_store' + command: + - --models mini2_snr=mini2_snr.mar diff --git a/torchserve/config.properties b/torchserve/config.properties index c0dd1d46..8390f10c 100644 --- a/torchserve/config.properties +++ b/torchserve/config.properties @@ -1,3 +1,5 @@ inference_address=http://0.0.0.0:8080 management_address=http://0.0.0.0:8081 metrics_address=http://0.0.0.0:8082 +# batch_size=16 +# max_batch_delay=1000 diff --git a/torchserve/custom_handler.py b/torchserve/custom_handler.py index c2d35f85..ab40dbd7 100644 --- a/torchserve/custom_handler.py +++ b/torchserve/custom_handler.py @@ -31,10 +31,12 @@ class Yolov8Handler(ObjectDetector): def initialize(self, context): if torch.cuda.is_available(): self.device = torch.device("cuda") + print("Yolov8Handler: using cuda") elif XLA_AVAILABLE: self.device = xm.xla_device() else: self.device = torch.device("cpu") + print("Yolov8Handler: using cpu") properties = context.system_properties self.manifest = context.manifest diff --git a/torchserve/install-torchserve.sh b/torchserve/install-torchserve.sh new file mode 100755 index 00000000..99e8d3d9 --- /dev/null +++ b/torchserve/install-torchserve.sh @@ -0,0 +1,16 @@ +#!/bin/bash + +set -e +apt-get update && \ + apt-get install -y \ + git \ + python3-pip +pip config set global.no-cache-dir false && \ + git clone https://github.com/pytorch/serve -b v0.9.0 && \ + cd serve && \ + python3 ./ts_scripts/install_dependencies.py --environment prod $* && \ + pip3 install . && \ + pip3 install -r examples/object_detector/yolo/yolov8/requirements.txt && \ + cd .. && \ + rm -rf serve + diff --git a/torchserve/torchserve-entrypoint.sh b/torchserve/torchserve-entrypoint.sh new file mode 100755 index 00000000..f14b3adb --- /dev/null +++ b/torchserve/torchserve-entrypoint.sh @@ -0,0 +1,2 @@ +#!/bin/sh +exec /usr/local/bin/torchserve --start --model-store /model_store --ts-config /torchserve/config.properties --ncs --foreground $* diff --git a/worker.yml b/worker.yml index 124e3335..d858b959 100644 --- a/worker.yml +++ b/worker.yml @@ -1,5 +1,5 @@ -# On Pi4/Ubuntu, also requires systemd.unified_cgroup_hierarchy=0 added to /boot/firmware/cmdline.txt, -# to fall back to cgroup v1. +# On Pi4/Ubuntu, also requires systemd.unified_cgroup_hierarchy=0 added to +# /boot/firmware/cmdline.txt, to fall back to cgroup v1. version: "3.3" networks: gamutrf: