classifyre-cli 0.4.78__tar.gz → 0.4.79__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 (269) hide show
  1. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/.turbo/turbo-build.log +1 -1
  2. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/PKG-INFO +1 -1
  3. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/package.json +1 -1
  4. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/pyproject.toml +1 -1
  5. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/object_storage/base.py +19 -0
  6. classifyre_cli-0.4.79/tests/test_object_storage_download_efficiency.py +217 -0
  7. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/uv.lock +46 -46
  8. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/.gitignore +0 -0
  9. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/.python-version +0 -0
  10. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/README.md +0 -0
  11. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/main.py +0 -0
  12. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/scripts/generate_models.py +0 -0
  13. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/__init__.py +0 -0
  14. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/config.py +0 -0
  15. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/__init__.py +0 -0
  16. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/base.py +0 -0
  17. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/broken_links/__init__.py +0 -0
  18. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/broken_links/detector.py +0 -0
  19. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/config.py +0 -0
  20. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/content/__init__.py +0 -0
  21. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/__init__.py +0 -0
  22. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/detector.py +0 -0
  23. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/extractor.py +0 -0
  24. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/__init__.py +0 -0
  25. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_base.py +0 -0
  26. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_factory.py +0 -0
  27. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_gliner2.py +0 -0
  28. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_image_classification.py +0 -0
  29. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_llm.py +0 -0
  30. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_object_detection.py +0 -0
  31. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_regex.py +0 -0
  32. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/runners/_text_classification.py +0 -0
  33. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/custom/trainer.py +0 -0
  34. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/dependencies.py +0 -0
  35. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/engine_version.py +0 -0
  36. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/pii/__init__.py +0 -0
  37. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/pii/detector.py +0 -0
  38. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/secrets/__init__.py +0 -0
  39. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/secrets/detector.py +0 -0
  40. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/threat/__init__.py +0 -0
  41. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/threat/code_security_detector.py +0 -0
  42. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/detectors/threat/yara_detector.py +0 -0
  43. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/file_evaluation/__init__.py +0 -0
  44. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/file_evaluation/runner.py +0 -0
  45. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/main.py +0 -0
  46. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/models/generated_detectors.py +0 -0
  47. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/models/generated_input.py +0 -0
  48. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/models/generated_single_asset_scan_results.py +0 -0
  49. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/outputs/__init__.py +0 -0
  50. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/outputs/base.py +0 -0
  51. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/outputs/console.py +0 -0
  52. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/outputs/factory.py +0 -0
  53. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/outputs/file.py +0 -0
  54. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/outputs/rest.py +0 -0
  55. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/pipeline/__init__.py +0 -0
  56. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/pipeline/content_provider.py +0 -0
  57. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/pipeline/detector_pipeline.py +0 -0
  58. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/pipeline/parsed_content_provider.py +0 -0
  59. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/pipeline/scan_cache.py +0 -0
  60. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/pipeline/text_artifact.py +0 -0
  61. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/pipeline/worker_pool.py +0 -0
  62. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/__init__.py +0 -0
  63. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/asset_metadata.py +0 -0
  64. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/atlassian_common.py +0 -0
  65. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/azure_blob_storage/__init__.py +0 -0
  66. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/azure_blob_storage/source.py +0 -0
  67. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/base.py +0 -0
  68. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/confluence/__init__.py +0 -0
  69. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/confluence/source.py +0 -0
  70. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/databricks/__init__.py +0 -0
  71. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/databricks/source.py +0 -0
  72. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/delta_lake/__init__.py +0 -0
  73. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/delta_lake/source.py +0 -0
  74. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/dependencies.py +0 -0
  75. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/dropbox/__init__.py +0 -0
  76. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/dropbox/auth.py +0 -0
  77. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/dropbox/source.py +0 -0
  78. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/elasticsearch/__init__.py +0 -0
  79. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/elasticsearch/source.py +0 -0
  80. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/email/__init__.py +0 -0
  81. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/email/source.py +0 -0
  82. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/google_cloud_storage/__init__.py +0 -0
  83. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/google_cloud_storage/source.py +0 -0
  84. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/google_workspace/__init__.py +0 -0
  85. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/google_workspace/source.py +0 -0
  86. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/hive/__init__.py +0 -0
  87. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/hive/source.py +0 -0
  88. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/hugging_face/__init__.py +0 -0
  89. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/hugging_face/source.py +0 -0
  90. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/iceberg/__init__.py +0 -0
  91. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/iceberg/source.py +0 -0
  92. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/jira/__init__.py +0 -0
  93. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/jira/source.py +0 -0
  94. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/kafka/__init__.py +0 -0
  95. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/kafka/rest.py +0 -0
  96. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/kafka/source.py +0 -0
  97. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/lakehouse_base.py +0 -0
  98. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/local_folder/__init__.py +0 -0
  99. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/local_folder/source.py +0 -0
  100. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/meilisearch/__init__.py +0 -0
  101. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/meilisearch/source.py +0 -0
  102. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/microsoft_365/__init__.py +0 -0
  103. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/microsoft_365/source.py +0 -0
  104. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/mongodb/__init__.py +0 -0
  105. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/mongodb/source.py +0 -0
  106. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/mssql/__init__.py +0 -0
  107. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/mssql/source.py +0 -0
  108. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/mysql/__init__.py +0 -0
  109. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/mysql/source.py +0 -0
  110. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/neo4j/__init__.py +0 -0
  111. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/neo4j/source.py +0 -0
  112. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/notion/__init__.py +0 -0
  113. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/notion/client.py +0 -0
  114. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/notion/source.py +0 -0
  115. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/opensearch/__init__.py +0 -0
  116. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/opensearch/source.py +0 -0
  117. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/oracle/__init__.py +0 -0
  118. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/oracle/source.py +0 -0
  119. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/postgresql/__init__.py +0 -0
  120. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/postgresql/source.py +0 -0
  121. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/powerbi/__init__.py +0 -0
  122. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/powerbi/source.py +0 -0
  123. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/recipe_normalizer.py +0 -0
  124. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/s3_client.py +0 -0
  125. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/s3_compatible_storage/README.md +0 -0
  126. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/s3_compatible_storage/__init__.py +0 -0
  127. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/s3_compatible_storage/source.py +0 -0
  128. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/sandbox/__init__.py +0 -0
  129. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/sandbox/source.py +0 -0
  130. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/search_engine_base.py +0 -0
  131. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/servicedesk/__init__.py +0 -0
  132. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/servicedesk/source.py +0 -0
  133. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/slack/__init__.py +0 -0
  134. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/slack/source.py +0 -0
  135. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/snowflake/__init__.py +0 -0
  136. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/snowflake/source.py +0 -0
  137. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/sqlite/__init__.py +0 -0
  138. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/sqlite/source.py +0 -0
  139. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/tableau/__init__.py +0 -0
  140. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/tableau/source.py +0 -0
  141. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/tabular_base.py +0 -0
  142. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/tabular_utils.py +0 -0
  143. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/wordpress/__init__.py +0 -0
  144. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/wordpress/source.py +0 -0
  145. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/youtube/__init__.py +0 -0
  146. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/sources/youtube/source.py +0 -0
  147. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/telemetry.py +0 -0
  148. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/__init__.py +0 -0
  149. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/archive_extraction.py +0 -0
  150. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/content_extraction.py +0 -0
  151. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/dependency_groups.py +0 -0
  152. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/embedded_images.py +0 -0
  153. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/file_metadata.py +0 -0
  154. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/file_parser.py +0 -0
  155. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/file_to_images.py +0 -0
  156. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/hashing.py +0 -0
  157. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/legacy_office.py +0 -0
  158. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/resources.py +0 -0
  159. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/transcription.py +0 -0
  160. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/uv_sync.py +0 -0
  161. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/validation.py +0 -0
  162. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/src/utils/video_processing.py +0 -0
  163. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/__init__.py +0 -0
  164. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/_lakehouse_fakes.py +0 -0
  165. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/conftest.py +0 -0
  166. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/__init__.py +0 -0
  167. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/broken_links/test_broken_links_detector.py +0 -0
  168. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/conftest.py +0 -0
  169. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/content/__init__.py +0 -0
  170. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/__init__.py +0 -0
  171. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/conftest.py +0 -0
  172. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/test_gliner2_classification.py +0 -0
  173. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/test_invoice_extraction.py +0 -0
  174. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/test_llm_runner.py +0 -0
  175. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/test_pipeline_integration.py +0 -0
  176. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/test_regex_runner.py +0 -0
  177. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/test_runner_hardening.py +0 -0
  178. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/custom/test_transformer_runners.py +0 -0
  179. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/__init__.py +0 -0
  180. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/conftest.py +0 -0
  181. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/sample_invoice.pdf +0 -0
  182. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/test_pii_chunking.py +0 -0
  183. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/test_pii_detector.py +0 -0
  184. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/test_pii_detector_extended.py +0 -0
  185. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/test_pii_regional_entities.py +0 -0
  186. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/pii/test_pii_severity.py +0 -0
  187. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/secrets/__init__.py +0 -0
  188. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/secrets/test_secrets_detector.py +0 -0
  189. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/secrets/test_secrets_detector_extended.py +0 -0
  190. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_base_detector.py +0 -0
  191. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_custom_detector_examples_runtime.py +0 -0
  192. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_detector_catalog_commercial.py +0 -0
  193. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_detector_pipeline_types.py +0 -0
  194. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_detector_schema_examples.py +0 -0
  195. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_detector_types.py +0 -0
  196. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_phase2_detectors.py +0 -0
  197. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/test_registry.py +0 -0
  198. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/threat/__init__.py +0 -0
  199. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/threat/test_code_security_detector.py +0 -0
  200. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/detectors/threat/test_yara_detector.py +0 -0
  201. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/integration/test_wordpress_broken_links_detector.py +0 -0
  202. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/integration/test_wordpress_links_assets.py +0 -0
  203. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/pipeline/test_detector_outcomes.py +0 -0
  204. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/pipeline/test_detector_pipeline.py +0 -0
  205. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/pipeline/test_worker_pool.py +0 -0
  206. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_assets_metadata_catalog.py +0 -0
  207. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_azure_blob_storage_source.py +0 -0
  208. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_base_source_attachment.py +0 -0
  209. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_base_source_sampling.py +0 -0
  210. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_config.py +0 -0
  211. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_confluence_source.py +0 -0
  212. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_custom_extractor.py +0 -0
  213. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_databricks_source.py +0 -0
  214. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_delta_lake_source.py +0 -0
  215. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_dependency_groups.py +0 -0
  216. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_dropbox_auth_command.py +0 -0
  217. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_dropbox_source.py +0 -0
  218. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_elasticsearch_source.py +0 -0
  219. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_email_source.py +0 -0
  220. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_file_evaluation_runner.py +0 -0
  221. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_google_cloud_storage_source.py +0 -0
  222. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_google_workspace_source.py +0 -0
  223. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_hashing.py +0 -0
  224. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_hive_source.py +0 -0
  225. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_hugging_face_source.py +0 -0
  226. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_iceberg_source.py +0 -0
  227. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_jira_source.py +0 -0
  228. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_kafka_source.py +0 -0
  229. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_local_folder_source.py +0 -0
  230. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_main.py +0 -0
  231. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_meilisearch_source.py +0 -0
  232. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_microsoft_365_source.py +0 -0
  233. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_mongodb_source.py +0 -0
  234. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_mssql_source.py +0 -0
  235. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_mysql_source.py +0 -0
  236. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_neo4j_source.py +0 -0
  237. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_notion_source.py +0 -0
  238. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_opensearch_source.py +0 -0
  239. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_oracle_source.py +0 -0
  240. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_outputs.py +0 -0
  241. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_postgresql_source.py +0 -0
  242. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_powerbi_source.py +0 -0
  243. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_recipe_normalizer.py +0 -0
  244. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_s3_compatible_storage_source.py +0 -0
  245. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_sampling_automatic.py +0 -0
  246. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_sandbox_source.py +0 -0
  247. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_scan_cache.py +0 -0
  248. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_servicedesk_source.py +0 -0
  249. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_slack_source.py +0 -0
  250. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_snowflake_source.py +0 -0
  251. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_source_dependency_groups.py +0 -0
  252. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_source_strategy_conformance.py +0 -0
  253. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_sqlite_source.py +0 -0
  254. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_tableau_source.py +0 -0
  255. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_tabular_automatic_sampling.py +0 -0
  256. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_tabular_utils.py +0 -0
  257. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_uv_sync.py +0 -0
  258. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_wordpress_source.py +0 -0
  259. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_youtube_source.py +0 -0
  260. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/test_youtube_source_integration.py +0 -0
  261. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_archive_extraction.py +0 -0
  262. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_content_extraction.py +0 -0
  263. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_embedded_images.py +0 -0
  264. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_file_metadata.py +0 -0
  265. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_file_parser.py +0 -0
  266. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_file_to_images.py +0 -0
  267. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_legacy_office.py +0 -0
  268. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_transcription.py +0 -0
  269. {classifyre_cli-0.4.78 → classifyre_cli-0.4.79}/tests/utils/test_video_processing.py +0 -0
@@ -1,3 +1,3 @@
1
1
  $ uv sync
2
- Resolved 303 packages in 11ms
2
+ Resolved 303 packages in 13ms
3
3
  Checked 51 packages in 1ms
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: classifyre-cli
3
- Version: 0.4.78
3
+ Version: 0.4.79
4
4
  Summary: Classifyre CLI — scan and classify unstructured data sources
5
5
  License: MIT
6
6
  Keywords: data,ingestion,metadata,pii,secrets,unstructured
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@classifyre/cli",
3
- "version": "0.4.78",
3
+ "version": "0.4.79",
4
4
  "private": true,
5
5
  "scripts": {
6
6
  "build": "uv sync",
@@ -1,6 +1,6 @@
1
1
  [project]
2
2
  name = "classifyre-cli"
3
- version = "0.4.78"
3
+ version = "0.4.79"
4
4
  description = "Classifyre CLI — scan and classify unstructured data sources"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -824,6 +824,25 @@ class ObjectStorageSourceBase(BaseSource, ABC):
824
824
  raw_bytes = member_path.read_bytes()
825
825
  mime = self._mime_cache.get(asset_id, "")
826
826
 
827
+ if raw_bytes is None:
828
+ # Normal phase-2 path: discovery ran with discovery_only=True, so no
829
+ # bytes were ever cached. Fetch them once here.
830
+ #
831
+ # Falling through to fetch_content() instead would download the
832
+ # object via _build_snapshot() and then discard it (the snapshot
833
+ # carries no text for object storage), leaving the caller's
834
+ # fetch_content_bytes() fallback to download the very same object a
835
+ # second time — 2x egress on every object-storage scan.
836
+ #
837
+ # These bytes stay a local of this generator, so they are released
838
+ # when it finishes whether or not the asset is evicted (the caller
839
+ # skips eviction on error). Caching them here instead would leak one
840
+ # object per failed asset, which a memory-capped scan pod cannot
841
+ # afford.
842
+ fetched = await self.fetch_content_bytes(asset_id)
843
+ if fetched is not None:
844
+ raw_bytes, mime = fetched
845
+
827
846
  logger.info(
828
847
  "fetch_content_pages(%s): raw_bytes=%s mime=%s processed=%s",
829
848
  asset_id,
@@ -0,0 +1,217 @@
1
+ """Object-storage sources must read each object's bytes exactly once per scan.
2
+
3
+ These are family-wide guards, parametrized over every concrete
4
+ ``ObjectStorageSourceBase`` connector, because the behaviour under test lives in
5
+ the shared base: a regression in one place silently doubles egress and memory for
6
+ S3, Azure, GCS, Dropbox, Google Workspace, Microsoft 365 and Hugging Face at once.
7
+
8
+ The scan shape mirrors ``main.py``: phase 1 discovers with
9
+ ``set_discovery_only(True)`` (metadata only), then phase 2 processes each asset
10
+ through ``ParsedContentProvider`` under a concurrency semaphore.
11
+ """
12
+
13
+ from __future__ import annotations
14
+
15
+ import asyncio
16
+ from datetime import UTC, datetime
17
+
18
+ import pytest
19
+
20
+ from src.pipeline.parsed_content_provider import ParsedContentProvider
21
+ from src.sources.dropbox.source import DropboxObjectRef, DropboxSource
22
+ from src.sources.hugging_face.source import HuggingFaceObjectRef, HuggingFaceSource
23
+ from src.sources.object_storage.base import ObjectRef
24
+ from src.sources.s3_compatible_storage.source import S3CompatibleStorageSource
25
+
26
+ CSV_BYTES = b"name,email\nAda,ada@example.com\nGrace,grace@example.com\n"
27
+ MODIFIED = datetime(2026, 6, 1, tzinfo=UTC)
28
+
29
+
30
+ def _hugging_face(file_count: int):
31
+ source = HuggingFaceSource(
32
+ {
33
+ "type": "HUGGING_FACE",
34
+ "required": {"repo_id": "acme/corpus", "repo_type": "dataset"},
35
+ "masked": {"token": "hf_test-token"},
36
+ "optional": {},
37
+ "sampling": {"strategy": "ALL"},
38
+ }
39
+ )
40
+ source._cached_revision = "a" * 40
41
+ refs = [
42
+ HuggingFaceObjectRef(
43
+ key=f"data/f{index:03d}.csv",
44
+ size=len(CSV_BYTES),
45
+ last_modified=MODIFIED,
46
+ etag=f"sha-{index}",
47
+ blob_id=f"oid-{index}",
48
+ )
49
+ for index in range(file_count)
50
+ ]
51
+ return source, refs
52
+
53
+
54
+ def _dropbox(file_count: int):
55
+ source = DropboxSource(
56
+ {
57
+ "type": "DROPBOX",
58
+ "required": {"auth_method": "access_token"},
59
+ "masked": {"access_token": "sl.token"},
60
+ "optional": {},
61
+ "sampling": {"strategy": "ALL"},
62
+ }
63
+ )
64
+ refs = [
65
+ DropboxObjectRef(
66
+ key=f"/data/f{index:03d}.csv",
67
+ size=len(CSV_BYTES),
68
+ last_modified=MODIFIED,
69
+ etag=f"hash-{index}",
70
+ file_id=f"id:{index}",
71
+ )
72
+ for index in range(file_count)
73
+ ]
74
+ return source, refs
75
+
76
+
77
+ def _s3(file_count: int):
78
+ source = S3CompatibleStorageSource(
79
+ {
80
+ "type": "S3_COMPATIBLE_STORAGE",
81
+ "required": {"bucket": "corpus"},
82
+ "masked": {"aws_access_key_id": "key", "aws_secret_access_key": "secret"},
83
+ "optional": {},
84
+ "sampling": {"strategy": "ALL"},
85
+ }
86
+ )
87
+ refs = [
88
+ ObjectRef(
89
+ key=f"data/f{index:03d}.csv",
90
+ size=len(CSV_BYTES),
91
+ last_modified=MODIFIED,
92
+ etag=f"etag-{index}",
93
+ )
94
+ for index in range(file_count)
95
+ ]
96
+ return source, refs
97
+
98
+
99
+ SOURCE_FACTORIES = {
100
+ "hugging_face": _hugging_face,
101
+ "dropbox": _dropbox,
102
+ "s3_compatible_storage": _s3,
103
+ }
104
+
105
+
106
+ def _instrument(source, refs, monkeypatch, *, fail_on: set[str] | None = None):
107
+ """Wire the source to in-memory objects and count byte reads."""
108
+ downloads: list[str] = []
109
+
110
+ def _download(ref):
111
+ downloads.append(ref.key)
112
+ if fail_on and ref.key in fail_on:
113
+ raise RuntimeError("object unavailable")
114
+ return CSV_BYTES, "text/csv"
115
+
116
+ monkeypatch.setattr(source, "_list_objects", lambda: iter(refs))
117
+ monkeypatch.setattr(source, "_download_object", _download)
118
+ monkeypatch.setattr(source, "_ensure_file_processing_dependencies", lambda: None)
119
+ return downloads
120
+
121
+
122
+ async def _run_scan(source, stub_assets, *, max_concurrent: int, evict: bool = True):
123
+ """Phase 2 as main.py runs it: bounded concurrency, evict after each asset."""
124
+ provider = ParsedContentProvider(source)
125
+ semaphore = asyncio.Semaphore(max_concurrent)
126
+ pages_by_asset: dict[str, list[str]] = {}
127
+
128
+ async def _process(asset):
129
+ async with semaphore:
130
+ try:
131
+ pages_by_asset[asset.hash] = [
132
+ page async for page in provider.fetch_text_pages(asset.hash)
133
+ ]
134
+ finally:
135
+ if evict:
136
+ source.evict_asset_cache(asset.hash)
137
+
138
+ await asyncio.gather(*(_process(asset) for asset in stub_assets), return_exceptions=True)
139
+ return pages_by_asset
140
+
141
+
142
+ async def _discover(source):
143
+ source.set_discovery_only(True)
144
+ stubs = [asset async for batch in source.extract_raw() for asset in batch]
145
+ source.set_discovery_only(False)
146
+ return stubs
147
+
148
+
149
+ @pytest.mark.parametrize("source_name", sorted(SOURCE_FACTORIES))
150
+ @pytest.mark.asyncio
151
+ async def test_discovery_phase_downloads_nothing(source_name, monkeypatch):
152
+ """Phase 1 builds the asset inventory from listing metadata alone.
153
+
154
+ Downloading here would mean a 10,000-object bucket fetches 10,000 objects
155
+ before a single detector runs.
156
+ """
157
+ source, refs = SOURCE_FACTORIES[source_name](25)
158
+ downloads = _instrument(source, refs, monkeypatch)
159
+
160
+ stubs = await _discover(source)
161
+
162
+ assert len(stubs) == 25
163
+ assert downloads == []
164
+
165
+
166
+ @pytest.mark.parametrize("source_name", sorted(SOURCE_FACTORIES))
167
+ @pytest.mark.asyncio
168
+ async def test_each_object_is_downloaded_exactly_once(source_name, monkeypatch):
169
+ """Regression: fetch_content_pages() used to fall through to fetch_content(),
170
+ which downloaded the object and discarded it, so the provider's
171
+ fetch_content_bytes() fallback fetched the same object a second time."""
172
+ source, refs = SOURCE_FACTORIES[source_name](20)
173
+ downloads = _instrument(source, refs, monkeypatch)
174
+
175
+ stubs = await _discover(source)
176
+ pages_by_asset = await _run_scan(source, stubs, max_concurrent=5)
177
+
178
+ assert len(downloads) == 20, f"expected 1 download per object, got {len(downloads)} for 20"
179
+ assert sorted(downloads) == sorted(ref.key for ref in refs)
180
+ # The single download must still produce detector-ready text.
181
+ assert all(
182
+ any("ada@example.com" in page for page in pages) for pages in pages_by_asset.values()
183
+ )
184
+
185
+
186
+ @pytest.mark.parametrize("source_name", sorted(SOURCE_FACTORIES))
187
+ @pytest.mark.asyncio
188
+ async def test_processed_objects_do_not_accumulate_in_memory(source_name, monkeypatch):
189
+ """Object bytes must not stay resident after an asset is processed.
190
+
191
+ A scan pod runs under a hard memory limit, so retaining even one capped
192
+ object per processed asset is enough to OOM a large bucket.
193
+ """
194
+ source, refs = SOURCE_FACTORIES[source_name](30)
195
+ _instrument(source, refs, monkeypatch)
196
+
197
+ stubs = await _discover(source)
198
+ await _run_scan(source, stubs, max_concurrent=5)
199
+
200
+ assert source._bytes_cache == {}
201
+ assert source._content_cache == {}
202
+
203
+
204
+ @pytest.mark.parametrize("source_name", sorted(SOURCE_FACTORIES))
205
+ @pytest.mark.asyncio
206
+ async def test_failed_objects_leak_no_bytes(source_name, monkeypatch):
207
+ """main.py skips evict_asset_cache() when an asset raises, so the byte-fetch
208
+ path must not be what keeps those bytes alive."""
209
+ source, refs = SOURCE_FACTORIES[source_name](10)
210
+ failing = {refs[index].key for index in (1, 4, 7)}
211
+ _instrument(source, refs, monkeypatch, fail_on=failing)
212
+
213
+ stubs = await _discover(source)
214
+ # evict=False models the error path, where main.py never evicts.
215
+ await _run_scan(source, stubs, max_concurrent=5, evict=False)
216
+
217
+ assert source._bytes_cache == {}
@@ -539,30 +539,30 @@ wheels = [
539
539
 
540
540
  [[package]]
541
541
  name = "boto3"
542
- version = "1.43.59"
542
+ version = "1.43.61"
543
543
  source = { registry = "https://pypi.org/simple" }
544
544
  dependencies = [
545
545
  { name = "botocore" },
546
546
  { name = "jmespath" },
547
547
  { name = "s3transfer" },
548
548
  ]
549
- sdist = { url = "https://files.pythonhosted.org/packages/dc/c8/ef9de1d7413da3adcdb6363258ba6b5cc703593409d8c1957825b20a69d3/boto3-1.43.59.tar.gz", hash = "sha256:4e9b14f89adc1a533c89312e86d8e00455a6f15d398796d92f9191b06e56b401", size = 112653, upload-time = "2026-07-29T19:33:25.703Z" }
549
+ sdist = { url = "https://files.pythonhosted.org/packages/fc/70/64c16a00866976fac63f0b672bba5303060bc29814c20200f2012f650574/boto3-1.43.61.tar.gz", hash = "sha256:a818a2ed37ff555c8c710f9c308a5407ef325c43f4162d7f5ce961e20440ca18", size = 112671, upload-time = "2026-07-31T04:17:12.624Z" }
550
550
  wheels = [
551
- { url = "https://files.pythonhosted.org/packages/2b/10/c5999e72b020012f2e0ccccf2a15632329edd34cb95b02b1ccfb1712ec08/boto3-1.43.59-py3-none-any.whl", hash = "sha256:58b9635deebf075c1c3d76df78df08eb2979c2a74283194676783a0bff3b4557", size = 140024, upload-time = "2026-07-29T19:33:23.751Z" },
551
+ { url = "https://files.pythonhosted.org/packages/64/b6/414bc692bd4d8e1f22336024026de31d7f2bfd2ba67b794c77e2181fa76a/boto3-1.43.61-py3-none-any.whl", hash = "sha256:67f1544ef97caddd6d0ebd613010981e3990ac843bc010cc202a88b489b182a0", size = 140023, upload-time = "2026-07-31T04:17:10.542Z" },
552
552
  ]
553
553
 
554
554
  [[package]]
555
555
  name = "botocore"
556
- version = "1.43.59"
556
+ version = "1.43.61"
557
557
  source = { registry = "https://pypi.org/simple" }
558
558
  dependencies = [
559
559
  { name = "jmespath" },
560
560
  { name = "python-dateutil" },
561
561
  { name = "urllib3" },
562
562
  ]
563
- sdist = { url = "https://files.pythonhosted.org/packages/e5/37/3712a70796583570a5a2e426163e13762ba5ec615a73e966ad18e5933954/botocore-1.43.59.tar.gz", hash = "sha256:8016da69ecc1d705249a8ef13548d3c95eec87ac1cd26133a8bdfa73ca175be0", size = 15788291, upload-time = "2026-07-29T19:33:14.871Z" }
563
+ sdist = { url = "https://files.pythonhosted.org/packages/37/9d/be2fdd9f9723734d019d9f3f9f1e8dfe5fb55ab26909c963652cfbdf1761/botocore-1.43.61.tar.gz", hash = "sha256:23a9e8578b08bfb83953d32a08b304bb2cb7a7e2607a44b212c1a39862c2024e", size = 15798287, upload-time = "2026-07-31T04:17:01.494Z" }
564
564
  wheels = [
565
- { url = "https://files.pythonhosted.org/packages/f6/cd/62d749f824b25c152144665f7c5eb8b5ca8be967a87e0c63577b7d4501ae/botocore-1.43.59-py3-none-any.whl", hash = "sha256:21393c35d23b19d7ba95cc4156b59f4013f80696d667997e1abd9d4e29651708", size = 15471171, upload-time = "2026-07-29T19:33:10.864Z" },
565
+ { url = "https://files.pythonhosted.org/packages/0c/90/a95b9c70a26d95ac6875e356986a82639f3c11b39b750502bd10be4926a2/botocore-1.43.61-py3-none-any.whl", hash = "sha256:167c8626661561958a8b5d2066e478113c5789a79e6fbc711b249f2c3d5bca5f", size = 15485538, upload-time = "2026-07-31T04:16:57.579Z" },
566
566
  ]
567
567
 
568
568
  [[package]]
@@ -830,7 +830,7 @@ wheels = [
830
830
 
831
831
  [[package]]
832
832
  name = "classifyre-cli"
833
- version = "0.4.78"
833
+ version = "0.4.79"
834
834
  source = { editable = "." }
835
835
  dependencies = [
836
836
  { name = "beautifulsoup4" },
@@ -1359,7 +1359,7 @@ youtube = [
1359
1359
 
1360
1360
  [[package]]
1361
1361
  name = "classifyre-schemas"
1362
- version = "0.4.78"
1362
+ version = "0.4.79"
1363
1363
  source = { editable = "../../packages/schemas" }
1364
1364
  dependencies = [
1365
1365
  { name = "fastjsonschema" },
@@ -2510,7 +2510,7 @@ http2 = [
2510
2510
 
2511
2511
  [[package]]
2512
2512
  name = "huggingface-hub"
2513
- version = "1.25.1"
2513
+ version = "1.26.0"
2514
2514
  source = { registry = "https://pypi.org/simple" }
2515
2515
  dependencies = [
2516
2516
  { name = "click" },
@@ -2523,9 +2523,9 @@ dependencies = [
2523
2523
  { name = "tqdm" },
2524
2524
  { name = "typing-extensions" },
2525
2525
  ]
2526
- sdist = { url = "https://files.pythonhosted.org/packages/4b/50/db3771a6e4fad4bd28fb055d4363b51cb0ae98c1aa504b79d41fdcab5483/huggingface_hub-1.25.1.tar.gz", hash = "sha256:21129595ca7a753be479b319913e22cc8808361ac118bd76cc413db831b28a99", size = 928426, upload-time = "2026-07-27T09:24:10.117Z" }
2526
+ sdist = { url = "https://files.pythonhosted.org/packages/82/db/3582597f8be0d34bd6881365a26d390854f12893eabdd62dd36de9df5a47/huggingface_hub-1.26.0.tar.gz", hash = "sha256:c8cd4e2df1ba9402f77fce9b509ec1d52debb502551789473f34016acc14e361", size = 936665, upload-time = "2026-07-30T14:12:04.156Z" }
2527
2527
  wheels = [
2528
- { url = "https://files.pythonhosted.org/packages/f7/3f/21e816831c6d16f88a6c784974413fa0421ce8a5d04380c2666ed5b503e5/huggingface_hub-1.25.1-py3-none-any.whl", hash = "sha256:004d4e70350517e24c68a7dbb7dc5e40b2b6aefef8f94bf7a85f6f9835102ea5", size = 774909, upload-time = "2026-07-27T09:24:08.079Z" },
2528
+ { url = "https://files.pythonhosted.org/packages/97/bb/63a644c75b545f3ff394b822e9bd1c4a9586489c618b77a4d8a44a33a23b/huggingface_hub-1.26.0-py3-none-any.whl", hash = "sha256:e8cca670caa5d8dfa7e45bf45e86b466698198cd8150c021bcdb4a86b9252364", size = 780357, upload-time = "2026-07-30T14:12:01.998Z" },
2529
2529
  ]
2530
2530
 
2531
2531
  [[package]]
@@ -2874,7 +2874,7 @@ wheels = [
2874
2874
 
2875
2875
  [[package]]
2876
2876
  name = "litellm"
2877
- version = "1.94.0"
2877
+ version = "1.94.1"
2878
2878
  source = { registry = "https://pypi.org/simple" }
2879
2879
  dependencies = [
2880
2880
  { name = "aiohttp" },
@@ -2890,17 +2890,17 @@ dependencies = [
2890
2890
  { name = "tiktoken" },
2891
2891
  { name = "tokenizers" },
2892
2892
  ]
2893
- sdist = { url = "https://files.pythonhosted.org/packages/4c/74/074301e709bcaad5d81cb057886d16465a2dbf9a1537d6e5af5cffc5b944/litellm-1.94.0.tar.gz", hash = "sha256:12dc4f39a0d82f91cf30a6bce439b457bdff52e694ce87094878e6d521b6e4f5", size = 16266278, upload-time = "2026-07-28T20:21:51.146Z" }
2893
+ sdist = { url = "https://files.pythonhosted.org/packages/a1/d6/6995fbc8cc4a22c9a1346981dd62348cf563e9285e17587703ad235f1fc0/litellm-1.94.1.tar.gz", hash = "sha256:e9effe4c1e9206740b4bb4c98142ea1f71bae57e49df007cd25ef24b0ce4563f", size = 16264730, upload-time = "2026-07-30T23:14:22.682Z" }
2894
2894
  wheels = [
2895
- { url = "https://files.pythonhosted.org/packages/25/60/d3961c7366cb1ae503113cb2ea759c3719483b8ce57f0314e040ccbd1296/litellm-1.94.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:078b66ab2727dbd5fae013f146a08fe1614421fbd3234a5fb6028e3c263ffa27", size = 20681671, upload-time = "2026-07-28T20:21:28.003Z" },
2896
- { url = "https://files.pythonhosted.org/packages/8a/7b/18c36457f82e9ce10dbdc560f79da84afc11c20697e289b939db211e86d1/litellm-1.94.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:205d6ef259391d5b5076e82b2a8a30c63050611e584f7c2d516ff89cf408c6bb", size = 20664567, upload-time = "2026-07-28T20:21:31.064Z" },
2897
- { url = "https://files.pythonhosted.org/packages/dd/30/f68bc8675eeae77c7ede7fa5d6528d865c3a6e3be054f1c0be963ceb704c/litellm-1.94.0-cp312-cp312-win_amd64.whl", hash = "sha256:bf648a12004d183d79461b980402c6c36ba39ca0029c7cd3775d5b6ac20e8947", size = 20268587, upload-time = "2026-07-28T20:21:33.536Z" },
2898
- { url = "https://files.pythonhosted.org/packages/4c/e8/57da5e96ca050df18939205e4ee002b980d8d60fae1a94d63db89abd67a9/litellm-1.94.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:c7ea7b8a0ae43dab9c099da352bfaf43f7ec64a1c5c2b52b66b2ac75837a8e86", size = 20682372, upload-time = "2026-07-28T20:21:36.044Z" },
2899
- { url = "https://files.pythonhosted.org/packages/22/da/0282d815b7a329e0b35e008381c0f9ff8494b2174bd2ad600ba54b05a65c/litellm-1.94.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:a3fc60884d06607664b9eae39347f3e125744cbca92814a2f33a4d27204eda82", size = 20665506, upload-time = "2026-07-28T20:21:38.754Z" },
2900
- { url = "https://files.pythonhosted.org/packages/3f/2e/b0506b0308b36b41fda0a195e07a2202541cd9c71750d75653e6149bfc34/litellm-1.94.0-cp313-cp313-win_amd64.whl", hash = "sha256:dd05c0dee67325f5a580e2adc43fbe21c0ab8b2f2641991b33d096f10fe8c665", size = 20268579, upload-time = "2026-07-28T20:21:41.401Z" },
2901
- { url = "https://files.pythonhosted.org/packages/f7/72/95b02787b339df2b3a1d7abb95d670250845205cc523f47f1c54cd1dff7d/litellm-1.94.0-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:cb820276c4ddd0fdc1232bc9ce55165e5baade4854218e36206568e5cf4af24c", size = 20680792, upload-time = "2026-07-28T20:21:43.756Z" },
2902
- { url = "https://files.pythonhosted.org/packages/4e/fa/9988351539f7b96a76cbe27bdf8cc3aa5bf30b94c34cddae54114c434b54/litellm-1.94.0-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:3858e8c1a08b7400dcf105030cb84753fee2acfe7d10b01f1a450dd4576eea22", size = 20671329, upload-time = "2026-07-28T20:21:46.356Z" },
2903
- { url = "https://files.pythonhosted.org/packages/48/8e/71147c4f78ef8b0e46b585e7c3baa1bb635e79ff188a60feec2e0eaea6ba/litellm-1.94.0-cp314-cp314-win_amd64.whl", hash = "sha256:430127afdb317b98e2f3e4fab1c857fd72117292b5edd7d655e1aae51f213ef6", size = 20270705, upload-time = "2026-07-28T20:21:48.675Z" },
2895
+ { url = "https://files.pythonhosted.org/packages/31/42/77f98b30e99327971a9c27d1f1f2a92a9578b068d4833f42fda8ae9278fa/litellm-1.94.1-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:af37356cf5b325a2887c40ff772b39e1e0865b988297c544b29123ffb13fd1b9", size = 20681910, upload-time = "2026-07-30T23:13:51.535Z" },
2896
+ { url = "https://files.pythonhosted.org/packages/03/3c/f75a840c3a1b6466e138f5833e1623fcbf32a63bae8a56efc31a4265f8b6/litellm-1.94.1-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:66bc95498af3ab687ce7570704cb274bcf1d78049afa87a9f5f64db45b72847d", size = 20664250, upload-time = "2026-07-30T23:13:55.007Z" },
2897
+ { url = "https://files.pythonhosted.org/packages/89/cd/ab61853dc3699a96997dd731bd005f2c511235f695cb32c11209d55201c6/litellm-1.94.1-cp312-cp312-win_amd64.whl", hash = "sha256:44e55a55270dee8bb85e063940c368d32040e6db66765c55db4b884fc002d4ef", size = 20268551, upload-time = "2026-07-30T23:13:58.222Z" },
2898
+ { url = "https://files.pythonhosted.org/packages/33/c0/c00d40bc9a62c397601e23dd7be1905f52f5981413e78fef1184116a1036/litellm-1.94.1-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:cfef0468bda9c1ba8f554bebc2966f08436f1ead98017e7ed2d7663ece77f1c2", size = 20682610, upload-time = "2026-07-30T23:14:01.361Z" },
2899
+ { url = "https://files.pythonhosted.org/packages/4e/51/6923345e9584e6855cbc182af99efcd4de5d5aea75330dfcb53eaa2e3131/litellm-1.94.1-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1b0bc4a2373e54f2bd4c13f8ef9fda3839bfb2e1173fb4bcea3150b07d4c59bc", size = 20665189, upload-time = "2026-07-30T23:14:04.562Z" },
2900
+ { url = "https://files.pythonhosted.org/packages/28/b6/bc53595152faad2275fcbd4106a9d9bfe6133b704b2be3b4fdae31090598/litellm-1.94.1-cp313-cp313-win_amd64.whl", hash = "sha256:d14e5812b5f36af2ab45461ee0c925251bc07daf65c33b8f2ce3fd3ec1235eae", size = 20266790, upload-time = "2026-07-30T23:14:08.139Z" },
2901
+ { url = "https://files.pythonhosted.org/packages/61/3c/e141bf70dd1d93b234ef52e7ae18b1e77c7fe4b83dc262984dbd000fd8b9/litellm-1.94.1-cp314-cp314-manylinux_2_28_aarch64.whl", hash = "sha256:c5c9247d9fea8fe7cda851f7b15db560ee547a8325a0af86048967edf3ccfa15", size = 20681030, upload-time = "2026-07-30T23:14:12.575Z" },
2902
+ { url = "https://files.pythonhosted.org/packages/25/85/36265d4a7ad51636b0e18aded355ef5a2b1e4a38368f0e1068393ed13ddb/litellm-1.94.1-cp314-cp314-manylinux_2_28_x86_64.whl", hash = "sha256:a6f5274876f20dd5c9e53ba3da502e94f5b3c681c5027a0398231d0caae4aacd", size = 20671012, upload-time = "2026-07-30T23:14:16.235Z" },
2903
+ { url = "https://files.pythonhosted.org/packages/c1/9d/533802021f7654deced4ed05d2b73e6206170d6a0ae5000993aa4955e246/litellm-1.94.1-cp314-cp314-win_amd64.whl", hash = "sha256:ffa9a6cd9b6205d60b02ffc0b7f077a03693d835b06d2a34bfeaabb4f073c08a", size = 20269681, upload-time = "2026-07-30T23:14:19.5Z" },
2904
2904
  ]
2905
2905
 
2906
2906
  [[package]]
@@ -3789,7 +3789,7 @@ wheels = [
3789
3789
 
3790
3790
  [[package]]
3791
3791
  name = "openai"
3792
- version = "2.50.0"
3792
+ version = "2.51.0"
3793
3793
  source = { registry = "https://pypi.org/simple" }
3794
3794
  dependencies = [
3795
3795
  { name = "anyio" },
@@ -3801,9 +3801,9 @@ dependencies = [
3801
3801
  { name = "tqdm" },
3802
3802
  { name = "typing-extensions" },
3803
3803
  ]
3804
- sdist = { url = "https://files.pythonhosted.org/packages/d8/f5/e7735f2af272ee179a287911a698b3cbdb59d7a4ac4874571363adf1e4de/openai-2.50.0.tar.gz", hash = "sha256:5128f7caf4a6b01aefd6e7e93efe170a2c3427b8de286b9af5cdff3aa47e02c8", size = 1081965, upload-time = "2026-07-28T22:16:31.674Z" }
3804
+ sdist = { url = "https://files.pythonhosted.org/packages/75/d8/06fda9685e47d9a8fc177ef57f8af75207938fad49a45ce23bfa7b6a2a5c/openai-2.51.0.tar.gz", hash = "sha256:4d61287c42eba54086d09346e709cbf7f8cec51822efce9cc399450b9385fba5", size = 1083410, upload-time = "2026-07-30T17:43:26.507Z" }
3805
3805
  wheels = [
3806
- { url = "https://files.pythonhosted.org/packages/00/ca/db315b3bb748c26c644a3f85b7d509e774354d6518d47080b1446005ee41/openai-2.50.0-py3-none-any.whl", hash = "sha256:90bdddcc5a2fa529b350fac9c5780d87e5c361dcc6090ab57b0d470b0d7af7fa", size = 1650721, upload-time = "2026-07-28T22:16:29.48Z" },
3806
+ { url = "https://files.pythonhosted.org/packages/57/6f/c49e21245ad4865e886f6885e95e998bc024335b392c202bd571639e9d50/openai-2.51.0-py3-none-any.whl", hash = "sha256:91db13ce59a670fddc820a6983989650095e43e3acac09288bceb69356a8904e", size = 1652344, upload-time = "2026-07-30T17:43:24.225Z" },
3807
3807
  ]
3808
3808
 
3809
3809
  [[package]]
@@ -5597,27 +5597,27 @@ wheels = [
5597
5597
 
5598
5598
  [[package]]
5599
5599
  name = "ruff"
5600
- version = "0.16.0"
5601
- source = { registry = "https://pypi.org/simple" }
5602
- sdist = { url = "https://files.pythonhosted.org/packages/4d/94/1e5e4967626faf12fa56999cd6222dff6992ceb086ad7945756baf70c7a7/ruff-0.16.0.tar.gz", hash = "sha256:e460aafd5495ec89efaa6ced2e4a9a581116451e1c88b9d37ef497e0f8e93982", size = 4790557, upload-time = "2026-07-23T19:11:30.981Z" }
5603
- wheels = [
5604
- { url = "https://files.pythonhosted.org/packages/4b/81/1c8818fee7ce1a04cd7d1b3172e0a8f8e4f1dc4feb7fc390e16daa8af323/ruff-0.16.0-py3-none-linux_armv6l.whl", hash = "sha256:e5115729eb08c585e5121978ba5d5b60caeae394ce21b9fb5e6cd33a1c6c9b1e", size = 10754633, upload-time = "2026-07-23T19:10:46.415Z" },
5605
- { url = "https://files.pythonhosted.org/packages/23/df/beaf59c09d68db84304d555f188b276a77132a5d5b0b67a5c762aa143628/ruff-0.16.0-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:3c954b1d580bfa035b41654f7858cc7e71d5fc3ac5b723dd62bd9133830ed522", size = 10969164, upload-time = "2026-07-23T19:10:50.271Z" },
5606
- { url = "https://files.pythonhosted.org/packages/42/ce/741cd197496a1abbf51352710fd15ed995d2a2be87189c1da26a450d6e83/ruff-0.16.0-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e01c21d10eb1b29f47b7454e1f4056db9a3f0260c646aa88457c610291db9f81", size = 10488846, upload-time = "2026-07-23T19:10:52.639Z" },
5607
- { url = "https://files.pythonhosted.org/packages/52/2a/a2db8e88cade358f5cdcb05674a917751074109315d014eb6352d9a893f7/ruff-0.16.0-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6e364e5ed22ed8dc05082fd78e35308618260907ac2d3c1d637b2e682415b6c9", size = 10889729, upload-time = "2026-07-23T19:10:54.89Z" },
5608
- { url = "https://files.pythonhosted.org/packages/42/65/62a771694ebd63029dc953e27dbad40e1588bd4860ff9fe881018fddaa49/ruff-0.16.0-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d327b8fc113a1d4421a04f3839d3752057c8dd1ee320223a6f3f52d04ada462a", size = 10568275, upload-time = "2026-07-23T19:10:56.993Z" },
5609
- { url = "https://files.pythonhosted.org/packages/3f/e2/ced249fe8af5f086c5c58cc21cc3356d50f32f7401c5df87050c999620a7/ruff-0.16.0-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:a9b50c55e263103586b3dcf5f73d479eb8cb5fdb6098fec59a62891dab653717", size = 11385112, upload-time = "2026-07-23T19:10:59.615Z" },
5610
- { url = "https://files.pythonhosted.org/packages/87/0b/05154977a8fd69eeb6c103271f55403bfd8711f5c0f8ed07489d95a504e7/ruff-0.16.0-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0ff4a79ce3ec0172f3241943835de1c4cb4e2dcd07f0f8c2d02603dbbbee4b17", size = 12207008, upload-time = "2026-07-23T19:11:02.154Z" },
5611
- { url = "https://files.pythonhosted.org/packages/fb/29/98225831a3a1eab0e02f4acc6ca6559a98611dcc68b6965ff4b7234627c1/ruff-0.16.0-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e95c448fca1fb2a18372a9440926c5a6ee789639bb975c72e7ae6d0b04218ab4", size = 11650842, upload-time = "2026-07-23T19:11:04.557Z" },
5612
- { url = "https://files.pythonhosted.org/packages/91/66/6bd3cf90500653d55dc0ffc8507aa8300bd49d0214b2e8cb4d3fef2943ba/ruff-0.16.0-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f11a8d11010301d0a398a2fdef67691feca7294da6aef55e2150e8fa2cd520b", size = 11400718, upload-time = "2026-07-23T19:11:09.233Z" },
5613
- { url = "https://files.pythonhosted.org/packages/8e/a2/a54eb4eae05d66364050a5d3b8a9c5ef88196531b3cbe7109d873f87f819/ruff-0.16.0-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:48044c678e9cb8698246c99b14aaccfa6601dea7379eb48a6f8f73f7a6d86cd0", size = 11426177, upload-time = "2026-07-23T19:11:11.994Z" },
5614
- { url = "https://files.pythonhosted.org/packages/1a/be/16e3eea4b2a478a496919f5e36f17c4559e54620bd3bbac5d6affa068006/ruff-0.16.0-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:7aa0959bad8eb8bef50340154fc9b58678dae31fa4293afa38b44b6e552c0213", size = 10856126, upload-time = "2026-07-23T19:11:14.221Z" },
5615
- { url = "https://files.pythonhosted.org/packages/a2/84/252eb8b868a16eec7257c14f504f77537e734b2d69c762e639e588e304a3/ruff-0.16.0-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:28ea2b7df8ebf7f9da6b7d47b230ab48f387c0a29be3b474c4d0740e197bb9af", size = 10571208, upload-time = "2026-07-23T19:11:16.378Z" },
5616
- { url = "https://files.pythonhosted.org/packages/21/09/817a482f542f7570cbb4554b26e896610c7114f539b1d9e2d2145bf6bef6/ruff-0.16.0-py3-none-musllinux_1_2_i686.whl", hash = "sha256:33a3dfac8c35f81498dea9181bccc2f4c4bc8f1521a1dd9406e77643e0f0fb09", size = 11063329, upload-time = "2026-07-23T19:11:19.173Z" },
5617
- { url = "https://files.pythonhosted.org/packages/2e/23/9403c180ca1cb9b1f7335f5c3e5305c09d49ea5b345196682a36028bde4a/ruff-0.16.0-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:a5237a0bda500d30d81b8e07a6973a5cbc772864cbf746ae2f4e8a2e01c9f4ed", size = 11489751, upload-time = "2026-07-23T19:11:21.74Z" },
5618
- { url = "https://files.pythonhosted.org/packages/b2/1d/1b2ef7bcde851c78d7f17f1cca13fd6dc695fc4b3d6197941e72cae5b132/ruff-0.16.0-py3-none-win32.whl", hash = "sha256:7fab76fa065c873f41ff744347c6e77bcc3dfec4bcc754dc26b63d23c0f7f5fb", size = 10785885, upload-time = "2026-07-23T19:11:23.947Z" },
5619
- { url = "https://files.pythonhosted.org/packages/b2/a3/d5e4ef7a56be3f928ffb90b94c25ba7d3cb9c7fe0736aeaaedf361770712/ruff-0.16.0-py3-none-win_amd64.whl", hash = "sha256:429c117f022bf481fabd9d551e7a3952b24c65e6ef44337ea09d90bebef14472", size = 11923141, upload-time = "2026-07-23T19:11:26.409Z" },
5620
- { url = "https://files.pythonhosted.org/packages/cb/9a/8415f2657cbe200f41a4531ccededf135505a92d4a012229121f885b26f9/ruff-0.16.0-py3-none-win_arm64.whl", hash = "sha256:14296fedcd2705c77ab8235439278bbb38f285cf7da5528b00b3e330c3d4872d", size = 11273407, upload-time = "2026-07-23T19:11:28.705Z" },
5600
+ version = "0.16.1"
5601
+ source = { registry = "https://pypi.org/simple" }
5602
+ sdist = { url = "https://files.pythonhosted.org/packages/70/25/7113f6d5498888c5fb7db34081cba7d5971c4cb1bfb26819966eee68f003/ruff-0.16.1.tar.gz", hash = "sha256:fedad7c801dabd3fb9741d76aca39246e6ddd9ca446a015875207bf19f1e6bc7", size = 4877500, upload-time = "2026-07-30T19:37:01.379Z" }
5603
+ wheels = [
5604
+ { url = "https://files.pythonhosted.org/packages/1b/bd/694da69368e0973de65df2ddc73ab18d43c469d5963d9b150911de6bc513/ruff-0.16.1-py3-none-linux_armv6l.whl", hash = "sha256:58edb313b88f0c5460a26adf5f39a37a3be789494a15e3e411e35fa78b89f9a0", size = 10839126, upload-time = "2026-07-30T19:36:13.697Z" },
5605
+ { url = "https://files.pythonhosted.org/packages/3f/f0/b626e5d5bd0dd9576263658ef12885e2288afd1029a48e26ffed65ec1ac1/ruff-0.16.1-py3-none-macosx_10_12_x86_64.whl", hash = "sha256:fde5a99e2f97479af66edd6622c6d5a2a7592c77cf4153d9e4428f5eeb55b60c", size = 11070253, upload-time = "2026-07-30T19:36:17.14Z" },
5606
+ { url = "https://files.pythonhosted.org/packages/83/63/f40acfb6b35b88623e71684942b552c3edd96035f5d98f313815f7b277de/ruff-0.16.1-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e0d4c20532fca4f7fa609369161d968dd28f65d83dabbd61d8e9c7edbf7001f6", size = 10561425, upload-time = "2026-07-30T19:36:20.04Z" },
5607
+ { url = "https://files.pythonhosted.org/packages/aa/dd/14ec0e9c2b4d315547dd38765004b4863e354e1b52cb308272215d9f6f6d/ruff-0.16.1-py3-none-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30affbcedf59ad5703d9c91f82266e02b47739f797e1a7b6e158e5526a6dae38", size = 10948879, upload-time = "2026-07-30T19:36:22.476Z" },
5608
+ { url = "https://files.pythonhosted.org/packages/33/e9/9d870cbae575030fdef595f04b4b97573c525b5497cce4f4498cf2f85446/ruff-0.16.1-py3-none-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:24e9c631573cbca9d20f1283f8f479b2afa4a8503504822bd71a293889f16743", size = 10643691, upload-time = "2026-07-30T19:36:24.914Z" },
5609
+ { url = "https://files.pythonhosted.org/packages/c4/09/12743d544e2173f53ecd27217c65f90d2bc0f8424a66a60339e56bbc0457/ruff-0.16.1-py3-none-manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b41bdd48fb420987a9b5212e4957c26ad4abce401fa9ea9d4d85843727945f4f", size = 11435354, upload-time = "2026-07-30T19:36:28.447Z" },
5610
+ { url = "https://files.pythonhosted.org/packages/7f/89/a1652b2daee52083c9554a6333b678a8b01d0400f976827bb87857f9449a/ruff-0.16.1-py3-none-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b0d1e1393b7648079e13669de1c1f4fde06d4583e84d8fd5c1551e0a77a2aa75", size = 12259033, upload-time = "2026-07-30T19:36:31.326Z" },
5611
+ { url = "https://files.pythonhosted.org/packages/16/96/ecdcb8c54ee7b123b487f807eb014e6e019155a0b81dfb669acd52f28ce3/ruff-0.16.1-py3-none-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:07bf434b1c95f4e093be4532068ef4fcf00924eb2ade8796075980902d6fd54a", size = 11667981, upload-time = "2026-07-30T19:36:34.394Z" },
5612
+ { url = "https://files.pythonhosted.org/packages/cd/90/c52e12e0d862e9572f2a33aa227409143520abe53111e9a6babbac7b4af8/ruff-0.16.1-py3-none-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:39897739f112253ee4fdd2e8aa9a4f9ded99fb2be367d5f31dfa4ded6025584c", size = 11468183, upload-time = "2026-07-30T19:36:37.339Z" },
5613
+ { url = "https://files.pythonhosted.org/packages/2c/6b/4ffb7ad1d83eb16cf8cbb3c8815d3f11c88460fd162d4b372a2059be1c2a/ruff-0.16.1-py3-none-manylinux_2_31_riscv64.whl", hash = "sha256:82ae3c0c0d74daf17b968a10b7b3bb3ef297ab7de0c1f749646b25e690ccb150", size = 11470071, upload-time = "2026-07-30T19:36:39.91Z" },
5614
+ { url = "https://files.pythonhosted.org/packages/9c/72/32ae7db4c0b5e32ab611787caa19d1546800676d79f7483b7100a3561bf4/ruff-0.16.1-py3-none-musllinux_1_2_aarch64.whl", hash = "sha256:4d5f2ed10f8242d83fc08d521301089364e3375375705356f20c0e31606ef3ef", size = 10919503, upload-time = "2026-07-30T19:36:42.65Z" },
5615
+ { url = "https://files.pythonhosted.org/packages/f7/ca/3d901ba6ad6fc38da39c3448fc6c59ac945679293a17c3ceb6d6c1cba13e/ruff-0.16.1-py3-none-musllinux_1_2_armv7l.whl", hash = "sha256:a4665b309891f83f3e3c25447935f1213e9abbd4b5640af7a1f2def9f8d413c1", size = 10649861, upload-time = "2026-07-30T19:36:45.18Z" },
5616
+ { url = "https://files.pythonhosted.org/packages/92/79/894ef1ced26552d5f8c9cf6d85b0687840e1128c55aeab7b9c2d54a0d880/ruff-0.16.1-py3-none-musllinux_1_2_i686.whl", hash = "sha256:26e9ca5c9bc3971f20d3cf18a957f52ffd6a5f6564ff15c4912a144dcac22494", size = 11148137, upload-time = "2026-07-30T19:36:47.936Z" },
5617
+ { url = "https://files.pythonhosted.org/packages/2d/69/3609a09fa1cb46cc28b762363e440a354204e5dff01bd0c8d7437874d6b9/ruff-0.16.1-py3-none-musllinux_1_2_x86_64.whl", hash = "sha256:67e1e1e3fa4f0c82f0e36d4cd61e661f6e7a6196cb1aa92fe0828fa7b8f257cd", size = 11559211, upload-time = "2026-07-30T19:36:50.448Z" },
5618
+ { url = "https://files.pythonhosted.org/packages/fc/8a/fb22af2fd78a736e241fabf67e30ce1799a64244026377a49e133af90762/ruff-0.16.1-py3-none-win32.whl", hash = "sha256:d31765e131295b8445caf301e3e8a85b34d1b9b211b4109b7ba457888b051806", size = 10838258, upload-time = "2026-07-30T19:36:53.298Z" },
5619
+ { url = "https://files.pythonhosted.org/packages/d4/35/e57fd9fb5d423961df087a00b12d42c0a830288dc2f3b45ecca299158b4f/ruff-0.16.1-py3-none-win_amd64.whl", hash = "sha256:09b05e8b90c2cb06ad63464350e7a45e8e44a2dfe52072ebfba6666ca8d3f596", size = 11961111, upload-time = "2026-07-30T19:36:56.107Z" },
5620
+ { url = "https://files.pythonhosted.org/packages/cb/46/240ea004bf6dc4feb40e9832f2205a476a47dd5b8a3f8211a5fc5f95e20e/ruff-0.16.1-py3-none-win_arm64.whl", hash = "sha256:dbaadaac38c70239f056d306b7476f246b0bf000fa6b3876402acbf5b227eaf8", size = 11309414, upload-time = "2026-07-30T19:36:58.79Z" },
5621
5621
  ]
5622
5622
 
5623
5623
  [[package]]
File without changes