primitive 0.2.46__tar.gz → 0.2.49__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (113) hide show
  1. {primitive-0.2.46 → primitive-0.2.49}/PKG-INFO +1 -2
  2. {primitive-0.2.46 → primitive-0.2.49}/pyproject.toml +0 -1
  3. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/__about__.py +1 -1
  4. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/agent/runner.py +30 -142
  5. {primitive-0.2.46 → primitive-0.2.49}/uv.lock +0 -37
  6. {primitive-0.2.46 → primitive-0.2.49}/.git-hooks/pre-commit +0 -0
  7. {primitive-0.2.46 → primitive-0.2.49}/.gitattributes +0 -0
  8. {primitive-0.2.46 → primitive-0.2.49}/.github/workflows/lint.yml +0 -0
  9. {primitive-0.2.46 → primitive-0.2.49}/.github/workflows/publish.yml +0 -0
  10. {primitive-0.2.46 → primitive-0.2.49}/.github/workflows/pyright.yml +0 -0
  11. {primitive-0.2.46 → primitive-0.2.49}/.gitignore +0 -0
  12. {primitive-0.2.46 → primitive-0.2.49}/.vscode/extensions.json +0 -0
  13. {primitive-0.2.46 → primitive-0.2.49}/.vscode/settings.json +0 -0
  14. {primitive-0.2.46 → primitive-0.2.49}/LICENSE.txt +0 -0
  15. {primitive-0.2.46 → primitive-0.2.49}/Makefile +0 -0
  16. {primitive-0.2.46 → primitive-0.2.49}/README.md +0 -0
  17. {primitive-0.2.46 → primitive-0.2.49}/linux setup.md +0 -0
  18. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/__init__.py +0 -0
  19. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/agent/__init__.py +0 -0
  20. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/agent/actions.py +0 -0
  21. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/agent/commands.py +0 -0
  22. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/agent/uploader.py +0 -0
  23. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/auth/__init__.py +0 -0
  24. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/auth/actions.py +0 -0
  25. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/auth/commands.py +0 -0
  26. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/auth/graphql/__init__.py +0 -0
  27. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/auth/graphql/queries.py +0 -0
  28. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/cli.py +0 -0
  29. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/client.py +0 -0
  30. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/daemons/__init__.py +0 -0
  31. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/daemons/actions.py +0 -0
  32. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/daemons/commands.py +0 -0
  33. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/daemons/launch_agents.py +0 -0
  34. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/daemons/launch_service.py +0 -0
  35. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/daemons/ui.py +0 -0
  36. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/exec/__init__.py +0 -0
  37. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/exec/actions.py +0 -0
  38. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/exec/commands.py +0 -0
  39. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/exec/interactive.py +0 -0
  40. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/files/__init__.py +0 -0
  41. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/files/actions.py +0 -0
  42. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/files/commands.py +0 -0
  43. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/files/graphql/__init__.py +0 -0
  44. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/files/graphql/fragments.py +0 -0
  45. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/files/graphql/mutations.py +0 -0
  46. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/files/graphql/queries.py +0 -0
  47. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/git/__init__.py +0 -0
  48. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/git/actions.py +0 -0
  49. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/git/commands.py +0 -0
  50. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/git/graphql/__init__.py +0 -0
  51. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/git/graphql/queries.py +0 -0
  52. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/graphql/__init__.py +0 -0
  53. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/graphql/relay.py +0 -0
  54. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/graphql/sdk.py +0 -0
  55. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/graphql/utility_fragments.py +0 -0
  56. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/__init__.py +0 -0
  57. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/actions.py +0 -0
  58. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/android.py +0 -0
  59. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/commands.py +0 -0
  60. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/graphql/__init__.py +0 -0
  61. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/graphql/fragments.py +0 -0
  62. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/graphql/mutations.py +0 -0
  63. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/graphql/queries.py +0 -0
  64. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/hardware/ui.py +0 -0
  65. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/jobs/__init__.py +0 -0
  66. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/jobs/actions.py +0 -0
  67. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/jobs/commands.py +0 -0
  68. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/jobs/graphql/__init__.py +0 -0
  69. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/jobs/graphql/fragments.py +0 -0
  70. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/jobs/graphql/mutations.py +0 -0
  71. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/jobs/graphql/queries.py +0 -0
  72. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/monitor/actions.py +0 -0
  73. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/monitor/commands.py +0 -0
  74. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/organizations/__init__.py +0 -0
  75. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/organizations/actions.py +0 -0
  76. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/organizations/commands.py +0 -0
  77. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/organizations/graphql/__init__.py +0 -0
  78. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/organizations/graphql/fragments.py +0 -0
  79. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/organizations/graphql/mutations.py +0 -0
  80. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/organizations/graphql/queries.py +0 -0
  81. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/projects/__init__.py +0 -0
  82. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/projects/actions.py +0 -0
  83. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/projects/commands.py +0 -0
  84. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/projects/graphql/__init__.py +0 -0
  85. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/projects/graphql/fragments.py +0 -0
  86. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/projects/graphql/mutations.py +0 -0
  87. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/projects/graphql/queries.py +0 -0
  88. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/provisioning/__init__.py +0 -0
  89. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/provisioning/actions.py +0 -0
  90. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/provisioning/graphql/__init__.py +0 -0
  91. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/provisioning/graphql/queries.py +0 -0
  92. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/reservations/__init__.py +0 -0
  93. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/reservations/actions.py +0 -0
  94. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/reservations/commands.py +0 -0
  95. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/reservations/graphql/__init__.py +0 -0
  96. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/reservations/graphql/fragments.py +0 -0
  97. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/reservations/graphql/mutations.py +0 -0
  98. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/reservations/graphql/queries.py +0 -0
  99. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/__init__.py +0 -0
  100. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/actions.py +0 -0
  101. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/auth.py +0 -0
  102. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/cache.py +0 -0
  103. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/chunk_size.py +0 -0
  104. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/config.py +0 -0
  105. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/daemons.py +0 -0
  106. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/exceptions.py +0 -0
  107. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/logging.py +0 -0
  108. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/memory_size.py +0 -0
  109. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/printer.py +0 -0
  110. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/psutil.py +0 -0
  111. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/shell.py +0 -0
  112. {primitive-0.2.46 → primitive-0.2.49}/src/primitive/utils/text.py +0 -0
  113. {primitive-0.2.46 → primitive-0.2.49}/tests/__init__.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: primitive
3
- Version: 0.2.46
3
+ Version: 0.2.49
4
4
  Project-URL: Documentation, https://github.com//primitivecorp/primitive-cli#readme
5
5
  Project-URL: Issues, https://github.com//primitivecorp/primitive-cli/issues
6
6
  Project-URL: Source, https://github.com//primitivecorp/primitive-cli
@@ -23,7 +23,6 @@ Requires-Dist: gql[all]
23
23
  Requires-Dist: loguru
24
24
  Requires-Dist: paramiko[invoke]
25
25
  Requires-Dist: psutil>=7.0.0
26
- Requires-Dist: pyyaml
27
26
  Requires-Dist: rich>=13.9.4
28
27
  Requires-Dist: speedtest-cli
29
28
  Description-Content-Type: text/markdown
@@ -30,7 +30,6 @@ dependencies = [
30
30
  "click",
31
31
  "gql[all]",
32
32
  "loguru",
33
- "pyyaml",
34
33
  # "primitive-pal == 0.1.4",
35
34
  "paramiko[invoke]",
36
35
  "speedtest-cli",
@@ -1,4 +1,4 @@
1
1
  # SPDX-FileCopyrightText: 2025-present Dylan Stein <dylan@primitive.tech>
2
2
  #
3
3
  # SPDX-License-Identifier: MIT
4
- __version__ = "0.2.46"
4
+ __version__ = "0.2.49"
@@ -1,35 +1,21 @@
1
1
  import asyncio
2
2
  import os
3
- import re
4
3
  import shutil
5
4
  import typing
6
5
  from enum import Enum, IntEnum
7
6
  from pathlib import Path, PurePath
8
7
  from typing import Dict, List, TypedDict
9
8
 
10
- import yaml
11
9
  from loguru import logger
12
10
 
13
11
  from primitive.utils.cache import get_artifacts_cache, get_logs_cache, get_sources_cache
14
12
  from primitive.utils.logging import fmt, log_context
15
13
  from primitive.utils.psutil import kill_process_and_children
16
- from primitive.utils.shell import env_to_dict
17
-
18
- try:
19
- from yaml import CLoader as Loader
20
- except ImportError:
21
- from yaml import Loader
22
14
 
23
15
  if typing.TYPE_CHECKING:
24
16
  import primitive.client
25
17
 
26
- CHUNK_SIZE = 64 * 1024
27
- ENV_VAR_LOOKUP_START = "_ENV_VAR_LOOKUP_START"
28
- START_DELIMITER_SIZE = len(bytes(ENV_VAR_LOOKUP_START, encoding="utf-8"))
29
- ENV_VAR_LOOKUP_END = "_ENV_VAR_LOOKUP_END"
30
- END_DELIMITER_SIZE = len(bytes(ENV_VAR_LOOKUP_END, encoding="utf-8"))
31
-
32
- assert CHUNK_SIZE > START_DELIMITER_SIZE + END_DELIMITER_SIZE
18
+ BUFFER_SIZE = 4096
33
19
 
34
20
 
35
21
  class Task(TypedDict):
@@ -68,8 +54,7 @@ class Runner:
68
54
  self.job = job_run["job"]
69
55
  self.job_run = job_run
70
56
  self.job_settings = job_run["jobSettings"]
71
- self.config = None
72
- self.source_dir: Path | None = None
57
+ self.config = job_run["jobSettings"]["config"]
73
58
  self.initial_env = {}
74
59
  self.modified_env = {}
75
60
  self.file_logger = None
@@ -109,22 +94,6 @@ class Runner:
109
94
  self.job_settings["rootDirectory"]
110
95
  )
111
96
 
112
- job_filename = self.job_settings["repositoryFilename"]
113
- logger.info(f"Scanning directory for job file {job_filename}")
114
-
115
- job_config_file = Path(self.source_dir / ".primitive" / job_filename)
116
-
117
- if job_config_file.exists():
118
- logger.info(
119
- f"Found job description for {self.job['slug']} at {job_config_file}"
120
- )
121
- self.config = yaml.load(open(job_config_file, "r"), Loader=Loader)
122
- else:
123
- logger.error(
124
- f"No job description with matching filename '{job_filename}' found"
125
- )
126
- raise FileNotFoundError
127
-
128
97
  # Setup initial process environment
129
98
  self.initial_env = os.environ
130
99
  self.initial_env = {
@@ -140,6 +109,11 @@ class Runner:
140
109
  self.job_run["gitCommit"]["repoFullName"]
141
110
  )
142
111
 
112
+ if "VIRTUAL_ENV" in self.initial_env:
113
+ del self.initial_env["VIRTUAL_ENV"]
114
+ if "SHELL" in self.initial_env:
115
+ self.initial_env["SHELL"] = "/bin/bash"
116
+
143
117
  @log_context(label="execute")
144
118
  def execute_job_run(self) -> None:
145
119
  self.modified_env = {**self.initial_env}
@@ -253,13 +227,11 @@ class Runner:
253
227
  # Adding an additional echo and utilizing stdbuf to force line buffering
254
228
  # This ensures that the environment variables and starting delimiter are
255
229
  # always in a new chunk, vastly simplifying our parsing logic
256
- args = [
257
- "/bin/bash",
258
- "-c",
259
- f"{cmd} && echo -n '{ENV_VAR_LOOKUP_START}' && env && echo -n '{ENV_VAR_LOOKUP_END}'",
260
- ]
230
+ args = ["/bin/bash", "-c", cmd]
261
231
 
262
- logger.info(f"Executing command {i + 1}/{len(commands)}: {cmd}")
232
+ logger.info(
233
+ f"Executing command {i + 1}/{len(commands)}: {cmd} at {self.source_dir / task.get('workdir', '')}"
234
+ )
263
235
 
264
236
  process = await asyncio.create_subprocess_exec(
265
237
  *args,
@@ -281,13 +253,9 @@ class Runner:
281
253
  kill_process_and_children(pid=process.pid)
282
254
  return False
283
255
 
284
- stdout_failed, stderr_failed = await asyncio.gather(
285
- self.log_cmd(
286
- process=process, stream=process.stdout, tags=task.get("tags", {})
287
- ),
288
- self.log_cmd(
289
- process=process, stream=process.stderr, tags=task.get("tags", {})
290
- ),
256
+ await asyncio.gather(
257
+ self.log_cmd(stream=process.stdout, level=LogLevel.INFO),
258
+ self.log_cmd(stream=process.stderr, level=LogLevel.ERROR),
291
259
  )
292
260
 
293
261
  returncode = await process.wait()
@@ -301,106 +269,26 @@ class Runner:
301
269
  f"Task {task['label']} failed on '{cmd}' with return code {returncode}"
302
270
  )
303
271
  return True
304
- elif stdout_failed or stderr_failed:
305
- logger.error(f"Task {task['label']} failed on '{cmd}'")
306
- return True
307
272
 
308
273
  logger.success(f"Completed {task['label']} task")
309
274
  return False
310
275
 
311
- async def log_cmd(self, process, stream, tags: Dict = {}) -> bool:
312
- failure_detected = False
313
- parse_environment = False
314
- last_chunk_buffer = b""
315
- environment_buffer = b""
316
- while chunk := await stream.read(CHUNK_SIZE):
317
- if parse_environment:
318
- environment_buffer += chunk
319
- continue
320
-
321
- # First, look for start delimiter in chunk
322
- full_chunk = last_chunk_buffer + chunk
323
- last_chunk_buffer = b""
324
- start_index = full_chunk.find(bytes(ENV_VAR_LOOKUP_START, encoding="utf-8"))
325
-
326
- if start_index != -1:
327
- environment_buffer = full_chunk[start_index + START_DELIMITER_SIZE :]
328
- processed_lines = await self.read_chunk(full_chunk[:start_index])
329
- parse_environment = True
330
- else:
331
- processed_lines = await self.read_chunk(full_chunk)
332
-
333
- while (
334
- len(last_chunk_buffer) < START_DELIMITER_SIZE
335
- and len(processed_lines) > 0
336
- ):
337
- last_chunk_buffer += bytes(
338
- processed_lines.pop() + "\n", encoding="utf-8"
339
- )
340
-
341
- # Handle logging
342
- parse_logs = self.job_settings["parseLogs"]
343
- parse_stderr = self.job_settings["parseStderr"]
344
-
345
- for line in processed_lines:
346
- level = LogLevel.INFO
347
- tag = None
348
- if (parse_logs and "error" in line.lower()) or (
349
- parse_stderr and stream is process.stderr
350
- ):
351
- level = LogLevel.ERROR
352
- elif parse_logs and "warning" in line.lower():
353
- level = LogLevel.WARNING
354
-
355
- # If we already detected a failure, skip checking
356
- if not failure_detected:
357
- failure_detected = (
358
- level == LogLevel.ERROR
359
- and self.job_settings["failureLevel"] >= FailureLevel.ERROR
360
- ) or (
361
- level == LogLevel.WARNING
362
- and self.job_settings["failureLevel"] >= FailureLevel.WARNING
363
- )
364
-
365
- # Tag on the first matching regex in the list
366
- for tag_key, regex in tags.items():
367
- pattern = re.compile(regex)
368
- if pattern.match(line):
369
- tag = tag_key
370
- break
371
-
372
- logger.bind(tag=tag).log(level.value, line)
373
-
374
- start_index = environment_buffer.find(
375
- bytes(ENV_VAR_LOOKUP_END, encoding="utf-8")
376
- )
377
- if parse_environment and start_index == -1:
378
- logger.error("Environment variable buffer did not contain end delimiter")
379
- failure_detected = True
380
- return failure_detected
381
-
382
- environment_buffer = environment_buffer[:start_index]
383
- new_env_vars = env_to_dict(environment_buffer)
384
- if len(new_env_vars.keys()) > 0:
385
- self.modified_env = {**self.modified_env, **new_env_vars}
386
- return failure_detected
387
-
388
- async def read_chunk(self, chunk: bytes) -> List[str]:
389
- """Converts a chunk of bytes into proper lines."""
390
- lines = []
391
- current_line = ""
392
- for char in chunk.decode():
393
- if char in ("\n", "\r"):
394
- lines.append(current_line)
395
- current_line = ""
396
- else:
397
- current_line += char
398
-
399
- # Handle extra characters in the buffer
400
- if len(current_line) > 0:
401
- lines.append(current_line)
402
-
403
- return [line for line in lines if len(line) > 0]
276
+ async def log_cmd(
277
+ self,
278
+ stream: asyncio.StreamReader | None,
279
+ level: LogLevel,
280
+ ):
281
+ buffer = bytearray()
282
+ while stream and not stream.at_eof():
283
+ chunk = await stream.read(BUFFER_SIZE)
284
+ if not chunk:
285
+ break
286
+ buffer += chunk
287
+ while b"\n" in buffer:
288
+ line, _, buffer = buffer.partition(b"\n")
289
+ logger.log(level.value, line.decode(errors="replace"))
290
+ if buffer:
291
+ logger.log(level.value, buffer.decode(errors="replace"))
404
292
 
405
293
  @log_context(label="cleanup")
406
294
  def cleanup(self) -> None:
@@ -810,7 +810,6 @@ dependencies = [
810
810
  { name = "loguru" },
811
811
  { name = "paramiko", extra = ["invoke"] },
812
812
  { name = "psutil" },
813
- { name = "pyyaml" },
814
813
  { name = "rich" },
815
814
  { name = "speedtest-cli" },
816
815
  ]
@@ -830,7 +829,6 @@ requires-dist = [
830
829
  { name = "loguru" },
831
830
  { name = "paramiko", extras = ["invoke"] },
832
831
  { name = "psutil", specifier = ">=7.0.0" },
833
- { name = "pyyaml" },
834
832
  { name = "rich", specifier = ">=13.9.4" },
835
833
  { name = "speedtest-cli" },
836
834
  ]
@@ -1024,41 +1022,6 @@ wheels = [
1024
1022
  { url = "https://files.pythonhosted.org/packages/ec/57/56b9bcc3c9c6a792fcbaf139543cee77261f3651ca9da0c93f5c1221264b/python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427", size = 229892, upload-time = "2024-03-01T18:36:18.57Z" },
1025
1023
  ]
1026
1024
 
1027
- [[package]]
1028
- name = "pyyaml"
1029
- version = "6.0.2"
1030
- source = { registry = "https://pypi.org/simple" }
1031
- sdist = { url = "https://files.pythonhosted.org/packages/54/ed/79a089b6be93607fa5cdaedf301d7dfb23af5f25c398d5ead2525b063e17/pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e", size = 130631, upload-time = "2024-08-06T20:33:50.674Z" }
1032
- wheels = [
1033
- { url = "https://files.pythonhosted.org/packages/f8/aa/7af4e81f7acba21a4c6be026da38fd2b872ca46226673c89a758ebdc4fd2/PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774", size = 184612, upload-time = "2024-08-06T20:32:03.408Z" },
1034
- { url = "https://files.pythonhosted.org/packages/8b/62/b9faa998fd185f65c1371643678e4d58254add437edb764a08c5a98fb986/PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee", size = 172040, upload-time = "2024-08-06T20:32:04.926Z" },
1035
- { url = "https://files.pythonhosted.org/packages/ad/0c/c804f5f922a9a6563bab712d8dcc70251e8af811fce4524d57c2c0fd49a4/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c", size = 736829, upload-time = "2024-08-06T20:32:06.459Z" },
1036
- { url = "https://files.pythonhosted.org/packages/51/16/6af8d6a6b210c8e54f1406a6b9481febf9c64a3109c541567e35a49aa2e7/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317", size = 764167, upload-time = "2024-08-06T20:32:08.338Z" },
1037
- { url = "https://files.pythonhosted.org/packages/75/e4/2c27590dfc9992f73aabbeb9241ae20220bd9452df27483b6e56d3975cc5/PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85", size = 762952, upload-time = "2024-08-06T20:32:14.124Z" },
1038
- { url = "https://files.pythonhosted.org/packages/9b/97/ecc1abf4a823f5ac61941a9c00fe501b02ac3ab0e373c3857f7d4b83e2b6/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4", size = 735301, upload-time = "2024-08-06T20:32:16.17Z" },
1039
- { url = "https://files.pythonhosted.org/packages/45/73/0f49dacd6e82c9430e46f4a027baa4ca205e8b0a9dce1397f44edc23559d/PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e", size = 756638, upload-time = "2024-08-06T20:32:18.555Z" },
1040
- { url = "https://files.pythonhosted.org/packages/22/5f/956f0f9fc65223a58fbc14459bf34b4cc48dec52e00535c79b8db361aabd/PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5", size = 143850, upload-time = "2024-08-06T20:32:19.889Z" },
1041
- { url = "https://files.pythonhosted.org/packages/ed/23/8da0bbe2ab9dcdd11f4f4557ccaf95c10b9811b13ecced089d43ce59c3c8/PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44", size = 161980, upload-time = "2024-08-06T20:32:21.273Z" },
1042
- { url = "https://files.pythonhosted.org/packages/86/0c/c581167fc46d6d6d7ddcfb8c843a4de25bdd27e4466938109ca68492292c/PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab", size = 183873, upload-time = "2024-08-06T20:32:25.131Z" },
1043
- { url = "https://files.pythonhosted.org/packages/a8/0c/38374f5bb272c051e2a69281d71cba6fdb983413e6758b84482905e29a5d/PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725", size = 173302, upload-time = "2024-08-06T20:32:26.511Z" },
1044
- { url = "https://files.pythonhosted.org/packages/c3/93/9916574aa8c00aa06bbac729972eb1071d002b8e158bd0e83a3b9a20a1f7/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5", size = 739154, upload-time = "2024-08-06T20:32:28.363Z" },
1045
- { url = "https://files.pythonhosted.org/packages/95/0f/b8938f1cbd09739c6da569d172531567dbcc9789e0029aa070856f123984/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425", size = 766223, upload-time = "2024-08-06T20:32:30.058Z" },
1046
- { url = "https://files.pythonhosted.org/packages/b9/2b/614b4752f2e127db5cc206abc23a8c19678e92b23c3db30fc86ab731d3bd/PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476", size = 767542, upload-time = "2024-08-06T20:32:31.881Z" },
1047
- { url = "https://files.pythonhosted.org/packages/d4/00/dd137d5bcc7efea1836d6264f049359861cf548469d18da90cd8216cf05f/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48", size = 731164, upload-time = "2024-08-06T20:32:37.083Z" },
1048
- { url = "https://files.pythonhosted.org/packages/c9/1f/4f998c900485e5c0ef43838363ba4a9723ac0ad73a9dc42068b12aaba4e4/PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b", size = 756611, upload-time = "2024-08-06T20:32:38.898Z" },
1049
- { url = "https://files.pythonhosted.org/packages/df/d1/f5a275fdb252768b7a11ec63585bc38d0e87c9e05668a139fea92b80634c/PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4", size = 140591, upload-time = "2024-08-06T20:32:40.241Z" },
1050
- { url = "https://files.pythonhosted.org/packages/0c/e8/4f648c598b17c3d06e8753d7d13d57542b30d56e6c2dedf9c331ae56312e/PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8", size = 156338, upload-time = "2024-08-06T20:32:41.93Z" },
1051
- { url = "https://files.pythonhosted.org/packages/ef/e3/3af305b830494fa85d95f6d95ef7fa73f2ee1cc8ef5b495c7c3269fb835f/PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba", size = 181309, upload-time = "2024-08-06T20:32:43.4Z" },
1052
- { url = "https://files.pythonhosted.org/packages/45/9f/3b1c20a0b7a3200524eb0076cc027a970d320bd3a6592873c85c92a08731/PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1", size = 171679, upload-time = "2024-08-06T20:32:44.801Z" },
1053
- { url = "https://files.pythonhosted.org/packages/7c/9a/337322f27005c33bcb656c655fa78325b730324c78620e8328ae28b64d0c/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133", size = 733428, upload-time = "2024-08-06T20:32:46.432Z" },
1054
- { url = "https://files.pythonhosted.org/packages/a3/69/864fbe19e6c18ea3cc196cbe5d392175b4cf3d5d0ac1403ec3f2d237ebb5/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484", size = 763361, upload-time = "2024-08-06T20:32:51.188Z" },
1055
- { url = "https://files.pythonhosted.org/packages/04/24/b7721e4845c2f162d26f50521b825fb061bc0a5afcf9a386840f23ea19fa/PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5", size = 759523, upload-time = "2024-08-06T20:32:53.019Z" },
1056
- { url = "https://files.pythonhosted.org/packages/2b/b2/e3234f59ba06559c6ff63c4e10baea10e5e7df868092bf9ab40e5b9c56b6/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc", size = 726660, upload-time = "2024-08-06T20:32:54.708Z" },
1057
- { url = "https://files.pythonhosted.org/packages/fe/0f/25911a9f080464c59fab9027482f822b86bf0608957a5fcc6eaac85aa515/PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652", size = 751597, upload-time = "2024-08-06T20:32:56.985Z" },
1058
- { url = "https://files.pythonhosted.org/packages/14/0d/e2c3b43bbce3cf6bd97c840b46088a3031085179e596d4929729d8d68270/PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183", size = 140527, upload-time = "2024-08-06T20:33:03.001Z" },
1059
- { url = "https://files.pythonhosted.org/packages/fa/de/02b54f42487e3d3c6efb3f89428677074ca7bf43aae402517bc7cca949f3/PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563", size = 156446, upload-time = "2024-08-06T20:33:04.33Z" },
1060
- ]
1061
-
1062
1025
  [[package]]
1063
1026
  name = "requests"
1064
1027
  version = "2.32.3"
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes