soutrik commited on
Commit
035df3d
1 Parent(s): a31745a

check and confirm docker compose on gpu

Browse files
Files changed (7) hide show
  1. Dockerfile +29 -13
  2. docker-compose.yaml +29 -0
  3. ec2_runner_setup.md +20 -1
  4. main.py +4 -2
  5. poetry.lock +125 -80
  6. pyproject.toml +1 -1
  7. src/litserve_benchmark.py +32 -37
Dockerfile CHANGED
@@ -1,16 +1,31 @@
1
- # Stage 1: Base image with Poetry and dependencies
2
- FROM pytorch/pytorch:2.4.0-cuda12.4-cudnn9-runtime as base
3
 
4
  LABEL maintainer="Soutrik soutrik1991@gmail.com" \
5
  description="Base Docker image for running a Python app with Poetry and GPU support."
6
 
7
- # Install Poetry and necessary system dependencies
8
- RUN apt-get update && apt-get install -y --no-install-recommends curl && \
9
- curl -sSL https://install.python-poetry.org | python3 - && \
 
 
 
 
 
 
 
 
 
10
  apt-get clean && rm -rf /var/lib/apt/lists/*
11
 
12
- # Add Poetry to the PATH explicitly
13
- ENV PATH="/root/.local/bin:$PATH"
 
 
 
 
 
 
14
 
15
  # Configure Poetry environment
16
  ENV POETRY_NO_INTERACTION=1 \
@@ -23,7 +38,7 @@ WORKDIR /app
23
  # Copy pyproject.toml and poetry.lock to install dependencies
24
  COPY pyproject.toml poetry.lock /app/
25
 
26
- # Install dependencies without installing the package itself
27
  RUN --mount=type=cache,target=/tmp/poetry_cache poetry install --only main --no-root
28
 
29
  # Stage 2: Build stage for the application
@@ -38,13 +53,11 @@ COPY main.py /app/main.py
38
  # Stage 3: Final runtime stage
39
  FROM base as runner
40
 
41
- # Copy application source code and necessary files from builder stage
42
  COPY --from=builder /app/src /app/src
43
  COPY --from=builder /app/configs /app/configs
44
  COPY --from=builder /app/.project-root /app/.project-root
45
  COPY --from=builder /app/main.py /app/main.py
46
-
47
- # Copy virtual environment from the builder stage
48
  COPY --from=builder /app/.venv /app/.venv
49
 
50
  # Copy client files
@@ -53,8 +66,11 @@ COPY run_client.sh /app/run_client.sh
53
  # Set the working directory to /app
54
  WORKDIR /app
55
 
56
- # Set the environment path to use the virtual environment
57
  ENV PATH="/app/.venv/bin:$PATH"
58
 
59
- # Default command
 
 
 
60
  CMD ["python", "-m", "main"]
 
1
+ # Stage 1: Base image with CUDA 12.2, cuDNN 9, and minimal runtime for PyTorch
2
+ FROM nvidia/cuda:12.2.0-runtime-ubuntu20.04 as base
3
 
4
  LABEL maintainer="Soutrik soutrik1991@gmail.com" \
5
  description="Base Docker image for running a Python app with Poetry and GPU support."
6
 
7
+ # Install necessary system dependencies, including Python 3.10
8
+ RUN apt-get update && apt-get install -y --no-install-recommends \
9
+ software-properties-common && \
10
+ add-apt-repository ppa:deadsnakes/ppa && \
11
+ apt-get update && apt-get install -y --no-install-recommends \
12
+ python3.10 \
13
+ python3.10-venv \
14
+ python3.10-dev \
15
+ python3-pip \
16
+ curl \
17
+ git \
18
+ build-essential && \
19
  apt-get clean && rm -rf /var/lib/apt/lists/*
20
 
21
+ # Set Python 3.10 as the default
22
+ RUN update-alternatives --install /usr/bin/python python /usr/bin/python3.10 1 && \
23
+ update-alternatives --install /usr/bin/python3 python3 /usr/bin/python3.10 1 && \
24
+ python --version
25
+
26
+ # Install Poetry
27
+ RUN curl -sSL https://install.python-poetry.org | python3 - && \
28
+ ln -s /root/.local/bin/poetry /usr/local/bin/poetry
29
 
30
  # Configure Poetry environment
31
  ENV POETRY_NO_INTERACTION=1 \
 
38
  # Copy pyproject.toml and poetry.lock to install dependencies
39
  COPY pyproject.toml poetry.lock /app/
40
 
41
+ # Install Python dependencies without building the app itself
42
  RUN --mount=type=cache,target=/tmp/poetry_cache poetry install --only main --no-root
43
 
44
  # Stage 2: Build stage for the application
 
53
  # Stage 3: Final runtime stage
54
  FROM base as runner
55
 
56
+ # Copy application source code and dependencies from the builder stage
57
  COPY --from=builder /app/src /app/src
58
  COPY --from=builder /app/configs /app/configs
59
  COPY --from=builder /app/.project-root /app/.project-root
60
  COPY --from=builder /app/main.py /app/main.py
 
 
61
  COPY --from=builder /app/.venv /app/.venv
62
 
63
  # Copy client files
 
66
  # Set the working directory to /app
67
  WORKDIR /app
68
 
69
+ # Add virtual environment to PATH
70
  ENV PATH="/app/.venv/bin:$PATH"
71
 
72
+ # Install PyTorch with CUDA 12.2 support (adjusted for compatibility)
73
+ RUN pip install torch torchvision torchaudio --index-url https://download.pytorch.org/whl/cu122
74
+
75
+ # Default command to run the application
76
  CMD ["python", "-m", "main"]
docker-compose.yaml CHANGED
@@ -19,6 +19,13 @@ services:
19
  - default
20
  env_file:
21
  - .env
 
 
 
 
 
 
 
22
 
23
  eval:
24
  build:
@@ -38,6 +45,13 @@ services:
38
  - default
39
  env_file:
40
  - .env
 
 
 
 
 
 
 
41
 
42
 
43
  server:
@@ -61,6 +75,13 @@ services:
61
  - .env
62
  ports:
63
  - "8080:8080"
 
 
 
 
 
 
 
64
 
65
  client:
66
  build:
@@ -82,6 +103,14 @@ services:
82
  env_file:
83
  - .env
84
 
 
 
 
 
 
 
 
 
85
 
86
  volumes:
87
  data:
 
19
  - default
20
  env_file:
21
  - .env
22
+ deploy:
23
+ resources:
24
+ reservations:
25
+ devices:
26
+ - driver: nvidia
27
+ count: 1
28
+ capabilities: [gpu]
29
 
30
  eval:
31
  build:
 
45
  - default
46
  env_file:
47
  - .env
48
+ deploy:
49
+ resources:
50
+ reservations:
51
+ devices:
52
+ - driver: nvidia
53
+ count: 1
54
+ capabilities: [gpu]
55
 
56
 
57
  server:
 
75
  - .env
76
  ports:
77
  - "8080:8080"
78
+ deploy:
79
+ resources:
80
+ reservations:
81
+ devices:
82
+ - driver: nvidia
83
+ count: 1
84
+ capabilities: [gpu]
85
 
86
  client:
87
  build:
 
103
  env_file:
104
  - .env
105
 
106
+ deploy:
107
+ resources:
108
+ reservations:
109
+ devices:
110
+ - driver: nvidia
111
+ count: 1
112
+ capabilities: [gpu]
113
+
114
 
115
  volumes:
116
  data:
ec2_runner_setup.md CHANGED
@@ -335,4 +335,23 @@ If successful, it should show details of the T4 GPU.
335
  - **PyTorch**: Installed with CUDA 12.2 support
336
 
337
  This setup ensures your system is ready for deep learning workloads with the T4 GPU.
338
- ```
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
335
  - **PyTorch**: Installed with CUDA 12.2 support
336
 
337
  This setup ensures your system is ready for deep learning workloads with the T4 GPU.
338
+
339
+ Install conda and create a new environment for the project
340
+ Install pytorch and torchvision in the new environment
341
+ Install other dependencies like numpy, pandas, matplotlib, etc.
342
+ Run the project code in the new environment
343
+ >>> import torch
344
+ >>> print(torch.cuda.is_available())
345
+ >>> print(torch.cuda.get_device_name(0))
346
+ >>> print(torch.version.cuda)
347
+ ```
348
+ __CUDA Docker Setup__:
349
+ ```bash
350
+ # If you are using docker and want to run a container with CUDA support
351
+ sudo apt install -y nvidia-container-toolkit
352
+ nvidia-ctk --version
353
+ sudo systemctl restart docker
354
+ sudo systemctl status docker
355
+ docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu20.04 nvidia-smi
356
+ docker run --rm --gpus all nvidia/cuda:12.2.0-base-ubuntu20.04 nvcc --version
357
+ ```
main.py CHANGED
@@ -1,3 +1,5 @@
1
- from loguru import logger
2
 
3
- logger.info("Hello, World!")
 
 
 
1
+ import torch
2
 
3
+ print(torch.cuda.is_available()) # Should return True if our GPU is enabled
4
+ print(torch.cuda.get_device_name(0)) # Should return "Tesla T4" if our GPU is enabled
5
+ print(torch.version.cuda) # Should return "12.4" if our GPU is enabled
poetry.lock CHANGED
@@ -246,92 +246,93 @@ files = [
246
 
247
  [[package]]
248
  name = "aiohttp"
249
- version = "3.11.5"
250
  description = "Async http client/server framework (asyncio)"
251
  optional = false
252
  python-versions = ">=3.9"
253
  files = [
254
- {file = "aiohttp-3.11.5-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:6f9afa6500aed9d3ea6d8bdd1dfed19252bb254dfc8503660c50bee908701c2a"},
255
- {file = "aiohttp-3.11.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:732ab84706bcfd2f2f16ea76c125a2025c1c747fc14db88ec1a7223ba3f2b9de"},
256
- {file = "aiohttp-3.11.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:3e6808209e3e2dc87980116234a59d1cb0857cd0e5273898a8fa2117fe3e3f9b"},
257
- {file = "aiohttp-3.11.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5add1f3dea8dcbaa6408de3f29f8dfaa663db703a62b1986ec65f12a54027854"},
258
- {file = "aiohttp-3.11.5-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f01131f46ed4d5361be6b362035a73ad1cea13819705dce4a969d9ee46fdbe8f"},
259
- {file = "aiohttp-3.11.5-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2bcd19a61db6a0b0f503f62faae0871b79a03dd2253787c60bb2436ff52619dc"},
260
- {file = "aiohttp-3.11.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9fd4e6ad1bb64f4794fbe4a082e5a4ac7680753adc9599ef2fb0bffc2a39027"},
261
- {file = "aiohttp-3.11.5-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bd49e76cbdc0f89539124fd12bf273b81eb3b5c9798e60736d6812747723311b"},
262
- {file = "aiohttp-3.11.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:633ef6e990032341305254f826602b93c38cde5f5154470ce031ec8735fdf909"},
263
- {file = "aiohttp-3.11.5-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:ceaddd89dbe146f3b48181160e3267736566ee3fa933d20512d3955adc0f5fd3"},
264
- {file = "aiohttp-3.11.5-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:f35f169d67b20a8104ea5c2660ae352aacdc95aa0461b227a5482e2c29638b54"},
265
- {file = "aiohttp-3.11.5-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:fdaf5b03c1328ca63a2c9cb24a5479e808ddd62132ccb3187015b727313c1375"},
266
- {file = "aiohttp-3.11.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:2766e6a246e4be9156d27f86fdf49d04a96a696a5cfcbe60aeb29bbfe91305c8"},
267
- {file = "aiohttp-3.11.5-cp310-cp310-win32.whl", hash = "sha256:a57c32e01a3ef97b841012fdcffcf73c372296b4c7bda1d67fd63c128b7adb30"},
268
- {file = "aiohttp-3.11.5-cp310-cp310-win_amd64.whl", hash = "sha256:46bb88bcee78aedfd0b664a92f6192ed776432862f9050772f0333b556e19d7c"},
269
- {file = "aiohttp-3.11.5-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:006546319eec664a32b8574bcf095880530fb431e58a290b0a39060def8734c4"},
270
- {file = "aiohttp-3.11.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:afe368c244920218a9dff7ffcdad023e4959a7be2ce61a6c459812ad09daaf8b"},
271
- {file = "aiohttp-3.11.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:eb3731dbe8b3608b09c1e6c3948a86365d8b22e649c0e24ef9e94d23d8108241"},
272
- {file = "aiohttp-3.11.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ba5aa61e4e557d8beeb6c3937d7591a9c2cd35b26d1d523e782d8222e6bdd56"},
273
- {file = "aiohttp-3.11.5-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a93b33cf3445a1c28e85f1b84b948625fa667ec4a48b59b7dd8e006a6fb841ff"},
274
- {file = "aiohttp-3.11.5-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e6ec3dab142a06e284b48de132e1938dddc866fae5006781985893d4cec7909a"},
275
- {file = "aiohttp-3.11.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b7892ec8b75a025bb0d60f49850fcf3a81888f92ffa0689c20e0625c03a7e329"},
276
- {file = "aiohttp-3.11.5-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ebf4e11938bb0251485fde7c94d7ac2b0c39a738f4b3f3c683746b85de55768a"},
277
- {file = "aiohttp-3.11.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d6d70ba0a3c8ecb18328c9530f360dec68ea7c1c8219b0a0b3aad4d13c190ae2"},
278
- {file = "aiohttp-3.11.5-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:cdddd330512e5c66006367d5d91170e4d16522277de79551c80843c22c97cd16"},
279
- {file = "aiohttp-3.11.5-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0aa667554a0bbe9ce75f071876adcc294d5d487141b6142068c309fee4249e33"},
280
- {file = "aiohttp-3.11.5-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:189a1f63264c69d20f45461a8a9cd0a7fe23ec6fd8ecbe3b14cd017f651329ea"},
281
- {file = "aiohttp-3.11.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:16fb393dff37de88039152d8a45c5e4f31a6785222b606c9b0eaec73f4dac84d"},
282
- {file = "aiohttp-3.11.5-cp311-cp311-win32.whl", hash = "sha256:8c0ca3a4c2ffce0204ed2af90760dcb97d9c7334b66af2e4e11a64bbf2d2873e"},
283
- {file = "aiohttp-3.11.5-cp311-cp311-win_amd64.whl", hash = "sha256:f9c2470432ebb7c8e094fd5c164cb355df752662c7ef59153d38651d0c540b2f"},
284
- {file = "aiohttp-3.11.5-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:3f21c6d1fae17f4466af3796975ab34010db3ac1f0d688272a6ce2f9fa2a4ea5"},
285
- {file = "aiohttp-3.11.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f2041691ac9a4ac5f3ccda419efdbd97f3b25bcc64c5badf57a85a69b8579268"},
286
- {file = "aiohttp-3.11.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7ad77209639aa7f8d1bd87bd0aa961cac791658c9dd1d32225cbabee95b70bd4"},
287
- {file = "aiohttp-3.11.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca5c02fec19113abb7d9df9350471fa1ed25f76ad24be81690c96b3b759da795"},
288
- {file = "aiohttp-3.11.5-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:35c429f0f761619ea659cfe5bed5c26bc62c5e09c2da28b5ee86d006b1a1eb4d"},
289
- {file = "aiohttp-3.11.5-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:68f0f8213e891b81800812ec70c58bac3899f4828e7ad14ba5997c26dd88aa6f"},
290
- {file = "aiohttp-3.11.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:381c1d8334fb010968dfc8eb1140ed349c5ade9ba20feb0aee2a047d9af0b7a5"},
291
- {file = "aiohttp-3.11.5-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0ea7b22c2569007df2c39dbe72b7c7cf4e6f6424b505545c68fde8495a35bcc9"},
292
- {file = "aiohttp-3.11.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:50d8784cdc111ed0709debe595be831ebb1f0c536b0840684d02fd12d100a092"},
293
- {file = "aiohttp-3.11.5-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0a7a8915129e6e9b43b5e2f13e0533314462f34e8f8589fb388b8f35becb997e"},
294
- {file = "aiohttp-3.11.5-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7e0cdfdc6ea4b974c3d546e683bf5a408a8777886c7ec389a780da58a8aa284"},
295
- {file = "aiohttp-3.11.5-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9a23bd19042768281c06858a55ee3d85e572111681e5f5dd68ebd27a6ae1e2af"},
296
- {file = "aiohttp-3.11.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:304316862900286574e38dbd58c9c5c25dfd52bcfea16514a00dd741f992871e"},
297
- {file = "aiohttp-3.11.5-cp312-cp312-win32.whl", hash = "sha256:3e0f4119290d432fa7babfc76cbde4f3e21b826240ba51a6d4fdb82935cf82bd"},
298
- {file = "aiohttp-3.11.5-cp312-cp312-win_amd64.whl", hash = "sha256:1fe98b92f943b00e1831aece85638af6ca6c699f82625f7a6c64a2543b7a9769"},
299
- {file = "aiohttp-3.11.5-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:e8407cc7801e2c8a0f22641f8451d05dcc41da818efa96bde2068729c3c264c5"},
300
- {file = "aiohttp-3.11.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f26e5ea97665847a449452e73ffdb89edd373d2277ba954813776816ac1c0b8a"},
301
- {file = "aiohttp-3.11.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:77d58df6820601e45b8577fb1d14a504c6a10315ee794e03549aed00e3a1a0ae"},
302
- {file = "aiohttp-3.11.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ebceca202221bb6fa30312558a055b6aefff448667e4f48a2cd9c32139b969f8"},
303
- {file = "aiohttp-3.11.5-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a80d9c44c3b60262c9335ba35b086f7e188fd2f6e45ff2ff0b0f6e350452f6c0"},
304
- {file = "aiohttp-3.11.5-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f0a694f03167e00d685582693f93b043ed37e40feb7065cc350930d2917126e9"},
305
- {file = "aiohttp-3.11.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d15f94b5717c4b9f2e14c02a0fad97214330ca1ef9673db033166eced098b2cb"},
306
- {file = "aiohttp-3.11.5-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c79793f89623ea83a0de4a38facf8beef956837be32bc48c3ac76e346254e974"},
307
- {file = "aiohttp-3.11.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac1cdc0b3d552cad60fca276da5713c678a155581a77dd6898ab96fed018188c"},
308
- {file = "aiohttp-3.11.5-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:035f34af40203ae94d2700ba732706f42222b4c428aa6cea43333cc8c0f9e4c7"},
309
- {file = "aiohttp-3.11.5-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:31df961cf559f8cf430b70977a7c95747a0ef24d5bb8f2365751b72964a8ceab"},
310
- {file = "aiohttp-3.11.5-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:afd046ab8ed14434c3c39300a5f3e5d2f993b9c8dfb3b21b6367e780caae208f"},
311
- {file = "aiohttp-3.11.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:44ab58914199ba57f7b95ccb38fcf27d94334eaf0d308aaea09012b878254bc0"},
312
- {file = "aiohttp-3.11.5-cp313-cp313-win32.whl", hash = "sha256:c147edaeee6a70cfc9e3edca45f7533a85bbd169d352a1355ceff97f4b75cf57"},
313
- {file = "aiohttp-3.11.5-cp313-cp313-win_amd64.whl", hash = "sha256:8df9e2f6e31c75519afe5a75af0eab47893884bcf5d8493dfc89c4dfe2bfb695"},
314
- {file = "aiohttp-3.11.5-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:933242d5316337c775a4ae9ce82e75c9e53ee43f39e5f7202114747f3cd95e08"},
315
- {file = "aiohttp-3.11.5-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b48be2532572aba7f0fcc660a59a0ae31fbe1fdf58b91b3e8e6ed2c118a8f662"},
316
- {file = "aiohttp-3.11.5-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:385d6527b2c72dff1a3a3336cb688a493057193a1671d091189116a833c50477"},
317
- {file = "aiohttp-3.11.5-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c683e440f0e1a23e0406aff6138b20de57215f9ad241391761831d12f56408ed"},
318
- {file = "aiohttp-3.11.5-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:efd327e40300a507073e8bbf11897c3e294be13b0fee4f7e11812153da0515b0"},
319
- {file = "aiohttp-3.11.5-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ebae6dd32a35bf888abf27598f3f4f1b9a267eec384a850e25e8fc684ff558c0"},
320
- {file = "aiohttp-3.11.5-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:549236995649fbd8fb53eeafad0673f8953aeaa97ae2d010ee534a43373cc989"},
321
- {file = "aiohttp-3.11.5-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1fa82b697ab1b3ba94e607aab9ef6aaf618cd47e44a24f112b633517a5a0be83"},
322
- {file = "aiohttp-3.11.5-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c89ddb0aeeae8facd72644ec6809bba2dd2936cba81d871177b7af311de661db"},
323
- {file = "aiohttp-3.11.5-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:04e2f8cbeefd0e06c1dcea28f9a87a2c769eab136301795b49ebf31c54282a63"},
324
- {file = "aiohttp-3.11.5-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:62e8b91a03d0e667f77c60672b9e10cd5f5432c1b0c2a6a32a24951e2d79a460"},
325
- {file = "aiohttp-3.11.5-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:e701291a1143b2eb3f4b6343482c9c94310dbe07dc7b3015b2fc84ec3116ea12"},
326
- {file = "aiohttp-3.11.5-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:7c542c9af3e22d31cf4baebe7bb131d2ef9e35acad397800b8a6a2b09487f7d8"},
327
- {file = "aiohttp-3.11.5-cp39-cp39-win32.whl", hash = "sha256:392836687024fd61272c4598f5b144d0581969fd6506145dec6161a5789f54da"},
328
- {file = "aiohttp-3.11.5-cp39-cp39-win_amd64.whl", hash = "sha256:382a0838b433f42dca78c1375c08cb822e514dadf9c5364307fade830ff5e81e"},
329
- {file = "aiohttp-3.11.5.tar.gz", hash = "sha256:7b857fdad5f95d05bbd27c68cdd549889287dea7fe3376265a8a85d554deec1e"},
330
  ]
331
 
332
  [package.dependencies]
333
  aiohappyeyeballs = ">=2.3.0"
334
  aiosignal = ">=1.1.2"
 
335
  attrs = ">=17.3.0"
336
  frozenlist = ">=1.1.1"
337
  multidict = ">=4.5,<7.0"
@@ -544,8 +545,10 @@ files = [
544
  ]
545
 
546
  [package.dependencies]
 
547
  idna = ">=2.8"
548
  sniffio = ">=1.1"
 
549
 
550
  [package.extras]
551
  doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
@@ -646,6 +649,9 @@ files = [
646
  {file = "asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851"},
647
  ]
648
 
 
 
 
649
  [package.extras]
650
  docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"]
651
  gssauth = ["gssapi", "sspilib"]
@@ -883,6 +889,8 @@ mypy-extensions = ">=0.4.3"
883
  packaging = ">=22.0"
884
  pathspec = ">=0.9.0"
885
  platformdirs = ">=2"
 
 
886
 
887
  [package.extras]
888
  colorama = ["colorama (>=0.4.3)"]
@@ -1614,6 +1622,9 @@ files = [
1614
  {file = "coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24"},
1615
  ]
1616
 
 
 
 
1617
  [package.extras]
1618
  toml = ["tomli"]
1619
 
@@ -2133,6 +2144,20 @@ files = [
2133
  {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"},
2134
  ]
2135
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
2136
  [[package]]
2137
  name = "fastapi"
2138
  version = "0.115.5"
@@ -4248,6 +4273,9 @@ files = [
4248
  {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"},
4249
  ]
4250
 
 
 
 
4251
  [[package]]
4252
  name = "mypy-extensions"
4253
  version = "1.0.0"
@@ -4768,7 +4796,7 @@ files = [
4768
  ]
4769
 
4770
  [package.dependencies]
4771
- numpy = {version = ">=1.23.2", markers = "python_version == \"3.11\""}
4772
  python-dateutil = ">=2.8.2"
4773
  pytz = ">=2020.1"
4774
  tzdata = ">=2022.7"
@@ -5791,9 +5819,11 @@ files = [
5791
 
5792
  [package.dependencies]
5793
  colorama = {version = "*", markers = "sys_platform == \"win32\""}
 
5794
  iniconfig = "*"
5795
  packaging = "*"
5796
  pluggy = ">=1.5,<2"
 
5797
 
5798
  [package.extras]
5799
  dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
@@ -6048,6 +6078,9 @@ files = [
6048
  {file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"},
6049
  ]
6050
 
 
 
 
6051
  [package.extras]
6052
  hiredis = ["hiredis (>1.0.0)"]
6053
  ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
@@ -7245,6 +7278,17 @@ dev = ["tokenizers[testing]"]
7245
  docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"]
7246
  testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"]
7247
 
 
 
 
 
 
 
 
 
 
 
 
7248
  [[package]]
7249
  name = "tomlkit"
7250
  version = "0.13.2"
@@ -7620,6 +7664,7 @@ h11 = ">=0.8"
7620
  httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
7621
  python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
7622
  pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
 
7623
  uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
7624
  watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
7625
  websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
@@ -8177,5 +8222,5 @@ type = ["pytest-mypy"]
8177
 
8178
  [metadata]
8179
  lock-version = "2.0"
8180
- python-versions = "3.11.9"
8181
- content-hash = "10964bfc333a340ec3ed898145e7078c04f58357f2b1554b741eb596f6e1e0a6"
 
246
 
247
  [[package]]
248
  name = "aiohttp"
249
+ version = "3.11.6"
250
  description = "Async http client/server framework (asyncio)"
251
  optional = false
252
  python-versions = ">=3.9"
253
  files = [
254
+ {file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7510b3ca2275691875ddf072a5b6cd129278d11fe09301add7d292fc8d3432de"},
255
+ {file = "aiohttp-3.11.6-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:bfab0d2c3380c588fc925168533edb21d3448ad76c3eadc360ff963019161724"},
256
+ {file = "aiohttp-3.11.6-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:cf02dba0f342f3a8228f43fae256aafc21c4bc85bffcf537ce4582e2b1565188"},
257
+ {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:92daedf7221392e7a7984915ca1b0481a94c71457c2f82548414a41d65555e70"},
258
+ {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:2274a7876e03429e3218589a6d3611a194bdce08c3f1e19962e23370b47c0313"},
259
+ {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8a2e1eae2d2f62f3660a1591e16e543b2498358593a73b193006fb89ee37abc6"},
260
+ {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:978ec3fb0a42efcd98aae608f58c6cfcececaf0a50b4e86ee3ea0d0a574ab73b"},
261
+ {file = "aiohttp-3.11.6-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a51f87b27d9219ed4e202ed8d6f1bb96f829e5eeff18db0d52f592af6de6bdbf"},
262
+ {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:04d1a02a669d26e833c8099992c17f557e3b2fdb7960a0c455d7b1cbcb05121d"},
263
+ {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3679d5fcbc7f1ab518ab4993f12f80afb63933f6afb21b9b272793d398303b98"},
264
+ {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:a4b24e03d04893b5c8ec9cd5f2f11dc9c8695c4e2416d2ac2ce6c782e4e5ffa5"},
265
+ {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:d9abdfd35ecff1c95f270b7606819a0e2de9e06fa86b15d9080de26594cf4c23"},
266
+ {file = "aiohttp-3.11.6-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:8b5c3e7928a0ad80887a5eba1c1da1830512ddfe7394d805badda45c03db3109"},
267
+ {file = "aiohttp-3.11.6-cp310-cp310-win32.whl", hash = "sha256:913dd9e9378f3c38aeb5c4fb2b8383d6490bc43f3b427ae79f2870651ae08f22"},
268
+ {file = "aiohttp-3.11.6-cp310-cp310-win_amd64.whl", hash = "sha256:4ac26d482c2000c3a59bf757a77adc972828c9d4177b4bd432a46ba682ca7271"},
269
+ {file = "aiohttp-3.11.6-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:26ac4c960ea8debf557357a172b3ef201f2236a462aefa1bc17683a75483e518"},
270
+ {file = "aiohttp-3.11.6-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8b1f13ebc99fb98c7c13057b748f05224ccc36d17dee18136c695ef23faaf4ff"},
271
+ {file = "aiohttp-3.11.6-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4679f1a47516189fab1774f7e45a6c7cac916224c91f5f94676f18d0b64ab134"},
272
+ {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:74491fdb3d140ff561ea2128cb7af9ba0a360067ee91074af899c9614f88a18f"},
273
+ {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f51e1a90412d387e62aa2d243998c5eddb71373b199d811e6ed862a9f34f9758"},
274
+ {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:72ab89510511c3bb703d0bb5504787b11e0ed8be928ed2a7cf1cda9280628430"},
275
+ {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6681c9e046d99646e8059266688374a063da85b2e4c0ebfa078cda414905d080"},
276
+ {file = "aiohttp-3.11.6-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1a17f8a6d3ab72cbbd137e494d1a23fbd3ea973db39587941f32901bb3c5c350"},
277
+ {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:867affc7612a314b95f74d93aac550ce0909bc6f0b6c658cc856890f4d326542"},
278
+ {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:00d894ebd609d5a423acef885bd61e7f6a972153f99c5b3ea45fc01fe909196c"},
279
+ {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:614c87be9d0d64477d1e4b663bdc5d1534fc0a7ebd23fb08347ab9fd5fe20fd7"},
280
+ {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:533ed46cf772f28f3bffae81c0573d916a64dee590b5dfaa3f3d11491da05b95"},
281
+ {file = "aiohttp-3.11.6-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:589884cfbc09813afb1454816b45677e983442e146183143f988f7f5a040791a"},
282
+ {file = "aiohttp-3.11.6-cp311-cp311-win32.whl", hash = "sha256:1da63633ba921669eec3d7e080459d4ceb663752b3dafb2f31f18edd248d2170"},
283
+ {file = "aiohttp-3.11.6-cp311-cp311-win_amd64.whl", hash = "sha256:d778ddda09622e7d83095cc8051698a0084c155a1474bfee9bac27d8613dbc31"},
284
+ {file = "aiohttp-3.11.6-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:943a952df105a5305257984e7a1f5c2d0fd8564ff33647693c4d07eb2315446d"},
285
+ {file = "aiohttp-3.11.6-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d24ec28b7658970a1f1d98608d67f88376c7e503d9d45ff2ba1949c09f2b358c"},
286
+ {file = "aiohttp-3.11.6-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6720e809a660fdb9bec7c168c582e11cfedce339af0a5ca847a5d5b588dce826"},
287
+ {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4252d30da0ada6e6841b325869c7ef5104b488e8dd57ec439892abbb8d7b3615"},
288
+ {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f65f43ff01b238aa0b5c47962c83830a49577efe31bd37c1400c3d11d8a32835"},
289
+ {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4dc5933f6c9b26404444d36babb650664f984b8e5fa0694540e7b7315d11a4ff"},
290
+ {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5bf546ba0c029dfffc718c4b67748687fd4f341b07b7c8f1719d6a3a46164798"},
291
+ {file = "aiohttp-3.11.6-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c351d05bbeae30c088009c0bb3b17dda04fd854f91cc6196c448349cc98f71c3"},
292
+ {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:10499079b063576fad1597898de3f9c0a2ce617c19cc7cd6b62fdcff6b408bf7"},
293
+ {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:442ee82eda47dd59798d6866ce020fb8d02ea31ac9ac82b3d719ed349e6a9d52"},
294
+ {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:86fce9127bc317119b34786d9e9ae8af4508a103158828a535f56d201da6ab19"},
295
+ {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:973d26a5537ce5d050302eb3cd876457451745b1da0624cbb483217970e12567"},
296
+ {file = "aiohttp-3.11.6-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:532b8f038a4e001137d3600cea5d3439d1881df41bdf44d0f9651264d562fdf0"},
297
+ {file = "aiohttp-3.11.6-cp312-cp312-win32.whl", hash = "sha256:4863c59f748dbe147da82b389931f2a676aebc9d3419813ed5ca32d057c9cb32"},
298
+ {file = "aiohttp-3.11.6-cp312-cp312-win_amd64.whl", hash = "sha256:5d7f481f82c18ac1f7986e31ba6eea9be8b2e2c86f1ef035b6866179b6c5dd68"},
299
+ {file = "aiohttp-3.11.6-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:40f502350496ba4c6820816d3164f8a0297b9aa4e95d910da31beb189866a9df"},
300
+ {file = "aiohttp-3.11.6-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:9072669b0bffb40f1f6977d0b5e8a296edc964f9cefca3a18e68649c214d0ce3"},
301
+ {file = "aiohttp-3.11.6-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:518160ecf4e6ffd61715bc9173da0925fcce44ae6c7ca3d3f098fe42585370fb"},
302
+ {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f69cc1b45115ac44795b63529aa5caa9674be057f11271f65474127b24fc1ce6"},
303
+ {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c6be90a6beced41653bda34afc891617c6d9e8276eef9c183f029f851f0a3c3d"},
304
+ {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:00c22fe2486308770d22ef86242101d7b0f1e1093ce178f2358f860e5149a551"},
305
+ {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2607ebb783e3aeefa017ec8f34b506a727e6b6ab2c4b037d65f0bc7151f4430a"},
306
+ {file = "aiohttp-3.11.6-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:5f761d6819870c2a8537f75f3e2fc610b163150cefa01f9f623945840f601b2c"},
307
+ {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e44d1bc6c88f5234115011842219ba27698a5f2deee245c963b180080572aaa2"},
308
+ {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:7e0cb6a1b1f499cb2aa0bab1c9f2169ad6913c735b7447e058e0c29c9e51c0b5"},
309
+ {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a76b4d4ca34254dca066acff2120811e2a8183997c135fcafa558280f2cc53f3"},
310
+ {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:69051c1e45fb18c0ae4d39a075532ff0b015982e7997f19eb5932eb4a3e05c17"},
311
+ {file = "aiohttp-3.11.6-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:aff2ed18274c0bfe0c1d772781c87d5ca97ae50f439729007cec9644ee9b15fe"},
312
+ {file = "aiohttp-3.11.6-cp313-cp313-win32.whl", hash = "sha256:2fbea25f2d44df809a46414a8baafa5f179d9dda7e60717f07bded56300589b3"},
313
+ {file = "aiohttp-3.11.6-cp313-cp313-win_amd64.whl", hash = "sha256:f77bc29a465c0f9f6573d1abe656d385fa673e34efe615bd4acc50899280ee47"},
314
+ {file = "aiohttp-3.11.6-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:de6123b298d17bca9e53581f50a275b36e10d98e8137eb743ce69ee766dbdfe9"},
315
+ {file = "aiohttp-3.11.6-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:a10200f705f4fff00e148b7f41e5d1d929c7cd4ac523c659171a0ea8284cd6fb"},
316
+ {file = "aiohttp-3.11.6-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:b7776ef6901b54dd557128d96c71e412eec0c39ebc07567e405ac98737995aad"},
317
+ {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e5c2a55583cd91936baf73d223807bb93ace6eb1fe54424782690f2707162ab"},
318
+ {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b032bd6cf7422583bf44f233f4a1489fee53c6d35920123a208adc54e2aba41e"},
319
+ {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:04fe2d99acbc5cf606f75d7347bf3a027c24c27bc052d470fb156f4cfcea5739"},
320
+ {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:84a79c366375c2250934d1238abe5d5ea7754c823a1c7df0c52bf0a2bfded6a9"},
321
+ {file = "aiohttp-3.11.6-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c33cbbe97dc94a34d1295a7bb68f82727bcbff2b284f73ae7e58ecc05903da97"},
322
+ {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:19e4fb9ac727834b003338dcdd27dcfe0de4fb44082b01b34ed0ab67c3469fc9"},
323
+ {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:a97f6b2afbe1d27220c0c14ea978e09fb4868f462ef3d56d810d206bd2e057a2"},
324
+ {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:c3f7afeea03a9bc49be6053dfd30809cd442cc12627d6ca08babd1c1f9e04ccf"},
325
+ {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:0d10967600ce5bb69ddcb3e18d84b278efb5199d8b24c3c71a4959c2f08acfd0"},
326
+ {file = "aiohttp-3.11.6-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:60f2f631b9fe7aa321fa0f0ff3f5d8b9f7f9b72afd4eecef61c33cf1cfea5d58"},
327
+ {file = "aiohttp-3.11.6-cp39-cp39-win32.whl", hash = "sha256:4d2b75333deb5c5f61bac5a48bba3dbc142eebbd3947d98788b6ef9cc48628ae"},
328
+ {file = "aiohttp-3.11.6-cp39-cp39-win_amd64.whl", hash = "sha256:8908c235421972a2e02abcef87d16084aabfe825d14cc9a1debd609b3cfffbea"},
329
+ {file = "aiohttp-3.11.6.tar.gz", hash = "sha256:fd9f55c1b51ae1c20a1afe7216a64a88d38afee063baa23c7fce03757023c999"},
330
  ]
331
 
332
  [package.dependencies]
333
  aiohappyeyeballs = ">=2.3.0"
334
  aiosignal = ">=1.1.2"
335
+ async-timeout = {version = ">=4.0,<6.0", markers = "python_version < \"3.11\""}
336
  attrs = ">=17.3.0"
337
  frozenlist = ">=1.1.1"
338
  multidict = ">=4.5,<7.0"
 
545
  ]
546
 
547
  [package.dependencies]
548
+ exceptiongroup = {version = ">=1.0.2", markers = "python_version < \"3.11\""}
549
  idna = ">=2.8"
550
  sniffio = ">=1.1"
551
+ typing-extensions = {version = ">=4.1", markers = "python_version < \"3.11\""}
552
 
553
  [package.extras]
554
  doc = ["Sphinx (>=7.4,<8.0)", "packaging", "sphinx-autodoc-typehints (>=1.2.0)", "sphinx-rtd-theme"]
 
649
  {file = "asyncpg-0.30.0.tar.gz", hash = "sha256:c551e9928ab6707602f44811817f82ba3c446e018bfe1d3abecc8ba5f3eac851"},
650
  ]
651
 
652
+ [package.dependencies]
653
+ async-timeout = {version = ">=4.0.3", markers = "python_version < \"3.11.0\""}
654
+
655
  [package.extras]
656
  docs = ["Sphinx (>=8.1.3,<8.2.0)", "sphinx-rtd-theme (>=1.2.2)"]
657
  gssauth = ["gssapi", "sspilib"]
 
889
  packaging = ">=22.0"
890
  pathspec = ">=0.9.0"
891
  platformdirs = ">=2"
892
+ tomli = {version = ">=1.1.0", markers = "python_version < \"3.11\""}
893
+ typing-extensions = {version = ">=4.0.1", markers = "python_version < \"3.11\""}
894
 
895
  [package.extras]
896
  colorama = ["colorama (>=0.4.3)"]
 
1622
  {file = "coverage-7.6.7.tar.gz", hash = "sha256:d79d4826e41441c9a118ff045e4bccb9fdbdcb1d02413e7ea6eb5c87b5439d24"},
1623
  ]
1624
 
1625
+ [package.dependencies]
1626
+ tomli = {version = "*", optional = true, markers = "python_full_version <= \"3.11.0a6\" and extra == \"toml\""}
1627
+
1628
  [package.extras]
1629
  toml = ["tomli"]
1630
 
 
2144
  {file = "entrypoints-0.4.tar.gz", hash = "sha256:b706eddaa9218a19ebcd67b56818f05bb27589b1ca9e8d797b74affad4ccacd4"},
2145
  ]
2146
 
2147
+ [[package]]
2148
+ name = "exceptiongroup"
2149
+ version = "1.2.2"
2150
+ description = "Backport of PEP 654 (exception groups)"
2151
+ optional = false
2152
+ python-versions = ">=3.7"
2153
+ files = [
2154
+ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"},
2155
+ {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"},
2156
+ ]
2157
+
2158
+ [package.extras]
2159
+ test = ["pytest (>=6)"]
2160
+
2161
  [[package]]
2162
  name = "fastapi"
2163
  version = "0.115.5"
 
4273
  {file = "multidict-6.1.0.tar.gz", hash = "sha256:22ae2ebf9b0c69d206c003e2f6a914ea33f0a932d4aa16f236afc049d9958f4a"},
4274
  ]
4275
 
4276
+ [package.dependencies]
4277
+ typing-extensions = {version = ">=4.1.0", markers = "python_version < \"3.11\""}
4278
+
4279
  [[package]]
4280
  name = "mypy-extensions"
4281
  version = "1.0.0"
 
4796
  ]
4797
 
4798
  [package.dependencies]
4799
+ numpy = {version = ">=1.22.4", markers = "python_version < \"3.11\""}
4800
  python-dateutil = ">=2.8.2"
4801
  pytz = ">=2020.1"
4802
  tzdata = ">=2022.7"
 
5819
 
5820
  [package.dependencies]
5821
  colorama = {version = "*", markers = "sys_platform == \"win32\""}
5822
+ exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""}
5823
  iniconfig = "*"
5824
  packaging = "*"
5825
  pluggy = ">=1.5,<2"
5826
+ tomli = {version = ">=1", markers = "python_version < \"3.11\""}
5827
 
5828
  [package.extras]
5829
  dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"]
 
6078
  {file = "redis-5.0.8.tar.gz", hash = "sha256:0c5b10d387568dfe0698c6fad6615750c24170e548ca2deac10c649d463e9870"},
6079
  ]
6080
 
6081
+ [package.dependencies]
6082
+ async-timeout = {version = ">=4.0.3", markers = "python_full_version < \"3.11.3\""}
6083
+
6084
  [package.extras]
6085
  hiredis = ["hiredis (>1.0.0)"]
6086
  ocsp = ["cryptography (>=36.0.1)", "pyopenssl (==20.0.1)", "requests (>=2.26.0)"]
 
7278
  docs = ["setuptools-rust", "sphinx", "sphinx-rtd-theme"]
7279
  testing = ["black (==22.3)", "datasets", "numpy", "pytest", "requests", "ruff"]
7280
 
7281
+ [[package]]
7282
+ name = "tomli"
7283
+ version = "2.1.0"
7284
+ description = "A lil' TOML parser"
7285
+ optional = false
7286
+ python-versions = ">=3.8"
7287
+ files = [
7288
+ {file = "tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391"},
7289
+ {file = "tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8"},
7290
+ ]
7291
+
7292
  [[package]]
7293
  name = "tomlkit"
7294
  version = "0.13.2"
 
7664
  httptools = {version = ">=0.5.0", optional = true, markers = "extra == \"standard\""}
7665
  python-dotenv = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
7666
  pyyaml = {version = ">=5.1", optional = true, markers = "extra == \"standard\""}
7667
+ typing-extensions = {version = ">=4.0", markers = "python_version < \"3.11\""}
7668
  uvloop = {version = ">=0.14.0,<0.15.0 || >0.15.0,<0.15.1 || >0.15.1", optional = true, markers = "(sys_platform != \"win32\" and sys_platform != \"cygwin\") and platform_python_implementation != \"PyPy\" and extra == \"standard\""}
7669
  watchfiles = {version = ">=0.13", optional = true, markers = "extra == \"standard\""}
7670
  websockets = {version = ">=10.4", optional = true, markers = "extra == \"standard\""}
 
8222
 
8223
  [metadata]
8224
  lock-version = "2.0"
8225
+ python-versions = "3.10.15"
8226
+ content-hash = "f716178afcbcd2f78554e71f39d279ce266c633a668a8246716f601c76801647"
pyproject.toml CHANGED
@@ -7,7 +7,7 @@ license = "Apache-2.0"
7
  readme = "README.md"
8
 
9
  [tool.poetry.dependencies]
10
- python = "3.11.9"
11
  black = "24.8.0"
12
  coverage = ">=7.6.1"
13
  hydra-colorlog = "1.2.0"
 
7
  readme = "README.md"
8
 
9
  [tool.poetry.dependencies]
10
+ python = "3.10.15"
11
  black = "24.8.0"
12
  coverage = ">=7.6.1"
13
  hydra-colorlog = "1.2.0"
src/litserve_benchmark.py CHANGED
@@ -6,6 +6,11 @@ import requests
6
  import psutil
7
  from urllib.request import urlopen
8
  import matplotlib.pyplot as plt
 
 
 
 
 
9
 
10
  # Try importing `gpustat` for GPU monitoring
11
  try:
@@ -16,7 +21,7 @@ except ImportError:
16
  GPU_AVAILABLE = False
17
 
18
  # Constants
19
- SERVER_URL = "http://localhost:8080" # Base server URL
20
  TEST_IMAGE_URL = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/beignets-task-guide.png"
21
 
22
 
@@ -28,7 +33,7 @@ def fetch_and_prepare_payload():
28
  img_data = urlopen(TEST_IMAGE_URL).read()
29
  return base64.b64encode(img_data).decode("utf-8")
30
  except Exception as e:
31
- print(f"Error fetching the image: {e}")
32
  return None
33
 
34
 
@@ -47,7 +52,7 @@ def send_request(payload, batch=False):
47
  predictions = response.json() if response.status_code == 200 else None
48
  return response_time, response.status_code, predictions
49
  except Exception as e:
50
- print(f"Error sending request: {e}")
51
  return None, None, None
52
 
53
 
@@ -73,7 +78,7 @@ def benchmark_api(num_requests=100, concurrency_level=10, batch=False):
73
  """
74
  payload = fetch_and_prepare_payload()
75
  if not payload:
76
- print("Error preparing payload. Benchmark aborted.")
77
  return
78
 
79
  payloads = [payload] * num_requests if batch else [payload]
@@ -114,11 +119,11 @@ def benchmark_api(num_requests=100, concurrency_level=10, batch=False):
114
  avg_response_time = np.mean(response_times) * 1000 if response_times else 0 # ms
115
  requests_per_second = num_requests / total_benchmark_time
116
 
117
- print("\n--- Sample Predictions ---")
118
  for i, prediction in enumerate(
119
  predictions[:5]
120
  ): # Show predictions for the first 5 requests
121
- print(f"Request {i + 1}: {prediction}")
122
 
123
  return {
124
  "total_requests": num_requests,
@@ -134,66 +139,56 @@ def benchmark_api(num_requests=100, concurrency_level=10, batch=False):
134
 
135
  def run_benchmarks():
136
  """
137
- Run comprehensive benchmarks and create plots.
138
  """
139
  concurrency_levels = [1, 8, 16, 32]
140
  metrics = []
141
 
142
- print("Running API benchmarks...")
143
  for concurrency in concurrency_levels:
144
- print(f"\nTesting concurrency level: {concurrency}")
145
  result = benchmark_api(
146
  num_requests=50, concurrency_level=concurrency, batch=False
147
  )
148
  if result:
149
  metrics.append(result)
150
- print(
151
  f"Concurrency {concurrency}: "
152
  f"{result['requests_per_second']:.2f} reqs/sec, "
153
  f"CPU: {result['avg_cpu_usage']:.1f}%, "
154
  f"GPU: {result['avg_gpu_usage']:.1f}%"
155
  )
156
 
157
- # Generate plots
158
- plt.figure(figsize=(12, 6))
159
-
160
- # Throughput
161
- plt.subplot(1, 2, 1)
162
- plt.plot(
163
- concurrency_levels,
164
- [m["requests_per_second"] for m in metrics],
165
- "r-o",
166
- label="Throughput",
167
- )
168
- plt.xlabel("Concurrency Level")
169
- plt.ylabel("Requests per Second")
170
- plt.title("API Throughput")
171
- plt.grid(True)
172
-
173
- # Resource Usage
174
- plt.subplot(1, 2, 2)
175
  plt.plot(
176
  concurrency_levels,
177
  [m["avg_cpu_usage"] for m in metrics],
178
  "b-o",
179
  label="CPU Usage",
180
  )
 
 
 
 
 
 
 
 
181
  if GPU_AVAILABLE:
 
182
  plt.plot(
183
  concurrency_levels,
184
  [m["avg_gpu_usage"] for m in metrics],
185
  "g-o",
186
  label="GPU Usage",
187
  )
188
- plt.xlabel("Concurrency Level")
189
- plt.ylabel("Resource Usage (%)")
190
- plt.title("Resource Usage")
191
- plt.legend()
192
- plt.grid(True)
193
-
194
- plt.tight_layout()
195
- plt.savefig("benchmark_results.png")
196
- print("Benchmark results saved as 'benchmark_results.png'.")
197
 
198
 
199
  if __name__ == "__main__":
 
6
  import psutil
7
  from urllib.request import urlopen
8
  import matplotlib.pyplot as plt
9
+ from loguru import logger
10
+ import os
11
+ from dotenv import load_dotenv, find_dotenv
12
+
13
+ load_dotenv(find_dotenv())
14
 
15
  # Try importing `gpustat` for GPU monitoring
16
  try:
 
21
  GPU_AVAILABLE = False
22
 
23
  # Constants
24
+ SERVER_URL = os.getenv("SERVER_URL", "http://localhost:8080")
25
  TEST_IMAGE_URL = "https://huggingface.co/datasets/huggingface/documentation-images/resolve/main/beignets-task-guide.png"
26
 
27
 
 
33
  img_data = urlopen(TEST_IMAGE_URL).read()
34
  return base64.b64encode(img_data).decode("utf-8")
35
  except Exception as e:
36
+ logger.info(f"Error fetching the image: {e}")
37
  return None
38
 
39
 
 
52
  predictions = response.json() if response.status_code == 200 else None
53
  return response_time, response.status_code, predictions
54
  except Exception as e:
55
+ logger.info(f"Error sending request: {e}")
56
  return None, None, None
57
 
58
 
 
78
  """
79
  payload = fetch_and_prepare_payload()
80
  if not payload:
81
+ logger.info("Error preparing payload. Benchmark aborted.")
82
  return
83
 
84
  payloads = [payload] * num_requests if batch else [payload]
 
119
  avg_response_time = np.mean(response_times) * 1000 if response_times else 0 # ms
120
  requests_per_second = num_requests / total_benchmark_time
121
 
122
+ logger.info("\n--- Sample Predictions ---")
123
  for i, prediction in enumerate(
124
  predictions[:5]
125
  ): # Show predictions for the first 5 requests
126
+ logger.info(f"Request {i + 1}: {prediction}")
127
 
128
  return {
129
  "total_requests": num_requests,
 
139
 
140
  def run_benchmarks():
141
  """
142
+ Run comprehensive benchmarks and create separate plots for CPU and GPU usage.
143
  """
144
  concurrency_levels = [1, 8, 16, 32]
145
  metrics = []
146
 
147
+ logger.info("Running API benchmarks...")
148
  for concurrency in concurrency_levels:
149
+ logger.info(f"\nTesting concurrency level: {concurrency}")
150
  result = benchmark_api(
151
  num_requests=50, concurrency_level=concurrency, batch=False
152
  )
153
  if result:
154
  metrics.append(result)
155
+ logger.info(
156
  f"Concurrency {concurrency}: "
157
  f"{result['requests_per_second']:.2f} reqs/sec, "
158
  f"CPU: {result['avg_cpu_usage']:.1f}%, "
159
  f"GPU: {result['avg_gpu_usage']:.1f}%"
160
  )
161
 
162
+ # Generate CPU Usage Plot
163
+ plt.figure(figsize=(10, 5))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
164
  plt.plot(
165
  concurrency_levels,
166
  [m["avg_cpu_usage"] for m in metrics],
167
  "b-o",
168
  label="CPU Usage",
169
  )
170
+ plt.xlabel("Concurrency Level")
171
+ plt.ylabel("CPU Usage (%)")
172
+ plt.title("CPU Usage vs. Concurrency Level")
173
+ plt.grid(True)
174
+ plt.savefig("artifacts/cpu_usage.png")
175
+ logger.info("CPU usage plot saved as 'cpu_usage.png'.")
176
+
177
+ # Generate GPU Usage Plot
178
  if GPU_AVAILABLE:
179
+ plt.figure(figsize=(10, 5))
180
  plt.plot(
181
  concurrency_levels,
182
  [m["avg_gpu_usage"] for m in metrics],
183
  "g-o",
184
  label="GPU Usage",
185
  )
186
+ plt.xlabel("Concurrency Level")
187
+ plt.ylabel("GPU Usage (%)")
188
+ plt.title("GPU Usage vs. Concurrency Level")
189
+ plt.grid(True)
190
+ plt.savefig("artifacts/gpu_usage.png")
191
+ logger.info("GPU usage plot saved as 'gpu_usage.png'.")
 
 
 
192
 
193
 
194
  if __name__ == "__main__":