classifyre-cli 0.6.12__tar.gz → 0.6.14__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 (394) hide show
  1. classifyre_cli-0.6.14/.turbo/turbo-build.log +3 -0
  2. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/PKG-INFO +1 -1
  3. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/package.json +1 -1
  4. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/pyproject.toml +1 -1
  5. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/session.py +19 -5
  6. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/graph/edges.py +9 -0
  7. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/models/generated_detectors.py +8 -0
  8. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/models/generated_input.py +125 -0
  9. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/sdk.py +14 -10
  10. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/detector_pipeline.py +29 -0
  11. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/scan_cache.py +20 -1
  12. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/custom/source.py +21 -0
  13. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/mssql/source.py +5 -59
  14. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/mysql/source.py +18 -5
  15. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/oracle/source.py +2 -62
  16. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/postgresql/source.py +3 -0
  17. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/snowflake/source.py +83 -79
  18. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/tabular_base.py +32 -10
  19. classifyre_cli-0.6.14/src/utils/sql_lineage.py +424 -0
  20. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_custom_detector_session.py +44 -2
  21. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_automatic_new_first.py +23 -5
  22. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_source.py +26 -0
  23. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_detector_scope.py +24 -0
  24. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_mssql_source.py +0 -5
  25. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_mysql_source.py +51 -0
  26. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_scan_cache.py +66 -0
  27. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_snowflake_source.py +27 -2
  28. classifyre_cli-0.6.14/tests/test_sql_lineage.py +153 -0
  29. classifyre_cli-0.6.14/tests/test_view_dependencies_are_not_foreign_keys.py +231 -0
  30. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/uv.lock +637 -615
  31. classifyre_cli-0.6.12/.turbo/turbo-build.log +0 -3
  32. classifyre_cli-0.6.12/src/utils/sql_lineage.py +0 -282
  33. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/.gitignore +0 -0
  34. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/.python-version +0 -0
  35. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/README.md +0 -0
  36. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/main.py +0 -0
  37. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/scripts/generate_models.py +0 -0
  38. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/scripts/generate_runtime_packages.py +0 -0
  39. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/scripts/generate_sdk_completions.py +0 -0
  40. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/__init__.py +0 -0
  41. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/augmentation/__init__.py +0 -0
  42. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/augmentation/contract.py +0 -0
  43. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/augmentation/preview.py +0 -0
  44. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/augmentation/runner.py +0 -0
  45. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/augmentation/sdk.py +0 -0
  46. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/augmentation/session.py +0 -0
  47. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/config.py +0 -0
  48. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/__init__.py +0 -0
  49. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/base.py +0 -0
  50. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/broken_links/__init__.py +0 -0
  51. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/broken_links/detector.py +0 -0
  52. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/config.py +0 -0
  53. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/content/__init__.py +0 -0
  54. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/__init__.py +0 -0
  55. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/detector.py +0 -0
  56. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/extractor.py +0 -0
  57. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/__init__.py +0 -0
  58. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_base.py +0 -0
  59. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_custom_detector.py +0 -0
  60. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_decision.py +0 -0
  61. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_factory.py +0 -0
  62. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_gliner2.py +0 -0
  63. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_image_classification.py +0 -0
  64. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_llm.py +0 -0
  65. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_object_detection.py +0 -0
  66. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_provider_call.py +0 -0
  67. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_regex.py +0 -0
  68. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_tag.py +0 -0
  69. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/runners/_text_classification.py +0 -0
  70. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom/trainer.py +0 -0
  71. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/__init__.py +0 -0
  72. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/contract.py +0 -0
  73. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/files.py +0 -0
  74. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/preview.py +0 -0
  75. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/results.py +0 -0
  76. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/runner.py +0 -0
  77. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/custom_detector/sdk.py +0 -0
  78. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/dependencies.py +0 -0
  79. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/engine_version.py +0 -0
  80. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/errors.py +0 -0
  81. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/pii/__init__.py +0 -0
  82. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/pii/detector.py +0 -0
  83. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/secrets/__init__.py +0 -0
  84. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/secrets/detector.py +0 -0
  85. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/threat/__init__.py +0 -0
  86. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/threat/code_security_detector.py +0 -0
  87. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/detectors/threat/yara_detector.py +0 -0
  88. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/file_evaluation/__init__.py +0 -0
  89. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/file_evaluation/asset_fixture.py +0 -0
  90. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/file_evaluation/runner.py +0 -0
  91. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/graph/__init__.py +0 -0
  92. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/main.py +0 -0
  93. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/models/generated_single_asset_scan_results.py +0 -0
  94. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/__init__.py +0 -0
  95. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/child.py +0 -0
  96. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/cli.py +0 -0
  97. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/cohort.py +0 -0
  98. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/contract.py +0 -0
  99. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/execute.py +0 -0
  100. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/files.py +0 -0
  101. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/groups.py +0 -0
  102. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/outputs.py +0 -0
  103. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/packages.py +0 -0
  104. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/protocol.py +0 -0
  105. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/redact.py +0 -0
  106. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/scaffold.py +0 -0
  107. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/notebook/serialize.py +0 -0
  108. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/outputs/__init__.py +0 -0
  109. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/outputs/base.py +0 -0
  110. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/outputs/console.py +0 -0
  111. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/outputs/factory.py +0 -0
  112. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/outputs/file.py +0 -0
  113. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/outputs/rest.py +0 -0
  114. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/__init__.py +0 -0
  115. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/asset_payload_server.py +0 -0
  116. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/content_provider.py +0 -0
  117. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/detector_breaker.py +0 -0
  118. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/finding_context.py +0 -0
  119. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/media_artifact.py +0 -0
  120. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/parsed_content_provider.py +0 -0
  121. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/payload_window.py +0 -0
  122. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/text_artifact.py +0 -0
  123. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/pipeline/worker_pool.py +0 -0
  124. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/__init__.py +0 -0
  125. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/asset_metadata.py +0 -0
  126. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/atlassian_common.py +0 -0
  127. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/azure_blob_storage/__init__.py +0 -0
  128. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/azure_blob_storage/source.py +0 -0
  129. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/base.py +0 -0
  130. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/confluence/__init__.py +0 -0
  131. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/confluence/source.py +0 -0
  132. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/custom/__init__.py +0 -0
  133. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/custom/env.py +0 -0
  134. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/custom/runner.py +0 -0
  135. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/databricks/__init__.py +0 -0
  136. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/databricks/source.py +0 -0
  137. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/delta_lake/__init__.py +0 -0
  138. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/delta_lake/source.py +0 -0
  139. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/dependencies.py +0 -0
  140. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/dremio/__init__.py +0 -0
  141. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/dremio/client.py +0 -0
  142. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/dremio/source.py +0 -0
  143. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/dropbox/__init__.py +0 -0
  144. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/dropbox/auth.py +0 -0
  145. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/dropbox/source.py +0 -0
  146. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/elasticsearch/__init__.py +0 -0
  147. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/elasticsearch/source.py +0 -0
  148. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/email/__init__.py +0 -0
  149. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/email/source.py +0 -0
  150. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/git/__init__.py +0 -0
  151. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/git/source.py +0 -0
  152. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/google_cloud_storage/__init__.py +0 -0
  153. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/google_cloud_storage/source.py +0 -0
  154. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/google_workspace/__init__.py +0 -0
  155. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/google_workspace/source.py +0 -0
  156. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/hive/__init__.py +0 -0
  157. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/hive/source.py +0 -0
  158. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/hugging_face/__init__.py +0 -0
  159. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/hugging_face/source.py +0 -0
  160. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/iceberg/__init__.py +0 -0
  161. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/iceberg/source.py +0 -0
  162. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/jira/__init__.py +0 -0
  163. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/jira/source.py +0 -0
  164. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/kafka/__init__.py +0 -0
  165. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/kafka/rest.py +0 -0
  166. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/kafka/source.py +0 -0
  167. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/lakehouse_base.py +0 -0
  168. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/local_folder/__init__.py +0 -0
  169. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/local_folder/source.py +0 -0
  170. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/meilisearch/__init__.py +0 -0
  171. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/meilisearch/source.py +0 -0
  172. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/microsoft_365/__init__.py +0 -0
  173. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/microsoft_365/source.py +0 -0
  174. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/mongodb/__init__.py +0 -0
  175. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/mongodb/source.py +0 -0
  176. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/mssql/__init__.py +0 -0
  177. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/mysql/__init__.py +0 -0
  178. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/neo4j/__init__.py +0 -0
  179. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/neo4j/source.py +0 -0
  180. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/notion/__init__.py +0 -0
  181. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/notion/client.py +0 -0
  182. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/notion/source.py +0 -0
  183. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/object_storage/base.py +0 -0
  184. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/opensearch/__init__.py +0 -0
  185. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/opensearch/source.py +0 -0
  186. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/oracle/__init__.py +0 -0
  187. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/postgresql/__init__.py +0 -0
  188. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/powerbi/__init__.py +0 -0
  189. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/powerbi/source.py +0 -0
  190. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/recipe_normalizer.py +0 -0
  191. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/reddit/__init__.py +0 -0
  192. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/reddit/source.py +0 -0
  193. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/s3_client.py +0 -0
  194. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/s3_compatible_storage/README.md +0 -0
  195. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/s3_compatible_storage/__init__.py +0 -0
  196. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/s3_compatible_storage/source.py +0 -0
  197. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/sandbox/__init__.py +0 -0
  198. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/sandbox/source.py +0 -0
  199. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/search_engine_base.py +0 -0
  200. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/servicedesk/__init__.py +0 -0
  201. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/servicedesk/source.py +0 -0
  202. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/slack/__init__.py +0 -0
  203. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/slack/source.py +0 -0
  204. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/snowflake/__init__.py +0 -0
  205. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/sqlite/__init__.py +0 -0
  206. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/sqlite/source.py +0 -0
  207. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/tableau/__init__.py +0 -0
  208. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/tableau/source.py +0 -0
  209. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/tabular_utils.py +0 -0
  210. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/wordpress/__init__.py +0 -0
  211. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/wordpress/source.py +0 -0
  212. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/youtube/__init__.py +0 -0
  213. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/sources/youtube/source.py +0 -0
  214. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/telemetry.py +0 -0
  215. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/__init__.py +0 -0
  216. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/archive_extraction.py +0 -0
  217. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/content_extraction.py +0 -0
  218. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/dependency_groups.py +0 -0
  219. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/embedded_files.py +0 -0
  220. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/external_video.py +0 -0
  221. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/file_metadata.py +0 -0
  222. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/file_parser.py +0 -0
  223. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/file_to_images.py +0 -0
  224. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/hashing.py +0 -0
  225. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/legacy_office.py +0 -0
  226. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/payload.py +0 -0
  227. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/range_reader.py +0 -0
  228. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/redaction.py +0 -0
  229. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/resources.py +0 -0
  230. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/sampling_cursor.py +0 -0
  231. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/sampling_frontier.py +0 -0
  232. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/source_files.py +0 -0
  233. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/torch_runtime.py +0 -0
  234. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/transcription.py +0 -0
  235. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/urn.py +0 -0
  236. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/uv_sync.py +0 -0
  237. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/validation.py +0 -0
  238. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/src/utils/video_processing.py +0 -0
  239. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/__init__.py +0 -0
  240. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/_lakehouse_fakes.py +0 -0
  241. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/conftest.py +0 -0
  242. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/__init__.py +0 -0
  243. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/broken_links/test_broken_links_detector.py +0 -0
  244. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/conftest.py +0 -0
  245. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/content/__init__.py +0 -0
  246. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/__init__.py +0 -0
  247. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/conftest.py +0 -0
  248. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_decision_runner.py +0 -0
  249. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_gliner2_classification.py +0 -0
  250. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_invoice_extraction.py +0 -0
  251. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_llm_runner.py +0 -0
  252. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_pipeline_integration.py +0 -0
  253. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_regex_runner.py +0 -0
  254. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_runner_hardening.py +0 -0
  255. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/custom/test_transformer_runners.py +0 -0
  256. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/__init__.py +0 -0
  257. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/conftest.py +0 -0
  258. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/sample_invoice.pdf +0 -0
  259. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/test_pii_chunking.py +0 -0
  260. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/test_pii_detector.py +0 -0
  261. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/test_pii_detector_extended.py +0 -0
  262. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/test_pii_regional_entities.py +0 -0
  263. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/pii/test_pii_severity.py +0 -0
  264. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/secrets/__init__.py +0 -0
  265. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/secrets/test_secrets_detector.py +0 -0
  266. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/secrets/test_secrets_detector_extended.py +0 -0
  267. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_base_detector.py +0 -0
  268. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_custom_detector_examples_runtime.py +0 -0
  269. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_detector_catalog_commercial.py +0 -0
  270. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_detector_pipeline_types.py +0 -0
  271. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_detector_schema_examples.py +0 -0
  272. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_detector_types.py +0 -0
  273. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_phase2_detectors.py +0 -0
  274. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_registry.py +0 -0
  275. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/test_tag_runner.py +0 -0
  276. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/threat/__init__.py +0 -0
  277. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/threat/test_code_security_detector.py +0 -0
  278. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/detectors/threat/test_yara_detector.py +0 -0
  279. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/integration/test_wordpress_broken_links_detector.py +0 -0
  280. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/integration/test_wordpress_links_assets.py +0 -0
  281. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/pipeline/test_detector_breaker.py +0 -0
  282. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/pipeline/test_detector_outcomes.py +0 -0
  283. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/pipeline/test_detector_pipeline.py +0 -0
  284. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/pipeline/test_worker_pool.py +0 -0
  285. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_arrow_ipc_payloads.py +0 -0
  286. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_assets_metadata_catalog.py +0 -0
  287. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_augmentation_contract.py +0 -0
  288. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_augmentation_edges.py +0 -0
  289. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_augmentation_patch.py +0 -0
  290. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_augmentation_scan_cache.py +0 -0
  291. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_augmentation_sdk.py +0 -0
  292. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_augmentation_session.py +0 -0
  293. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_augmentation_tags_end_to_end.py +0 -0
  294. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_azure_blob_storage_source.py +0 -0
  295. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_base_source_attachment.py +0 -0
  296. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_base_source_sampling.py +0 -0
  297. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_byte_valued_fields.py +0 -0
  298. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_config.py +0 -0
  299. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_confluence_source.py +0 -0
  300. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_detector_end_to_end.py +0 -0
  301. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_detector_evaluation.py +0 -0
  302. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_detector_notebook.py +0 -0
  303. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_detector_templates.py +0 -0
  304. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_extractor.py +0 -0
  305. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_source_relationships.py +0 -0
  306. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_custom_source_tags_end_to_end.py +0 -0
  307. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_databricks_source.py +0 -0
  308. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_delta_lake_source.py +0 -0
  309. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_dependency_groups.py +0 -0
  310. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_dremio_source.py +0 -0
  311. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_dropbox_auth_command.py +0 -0
  312. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_dropbox_source.py +0 -0
  313. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_elasticsearch_source.py +0 -0
  314. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_email_source.py +0 -0
  315. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_file_evaluation_runner.py +0 -0
  316. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_finding_context.py +0 -0
  317. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_git_source.py +0 -0
  318. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_google_cloud_storage_source.py +0 -0
  319. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_google_workspace_source.py +0 -0
  320. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_graph_edges.py +0 -0
  321. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_hashing.py +0 -0
  322. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_hive_source.py +0 -0
  323. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_hugging_face_source.py +0 -0
  324. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_iceberg_source.py +0 -0
  325. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_jira_source.py +0 -0
  326. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_kafka_source.py +0 -0
  327. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_lineage_loss_reporting.py +0 -0
  328. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_local_folder_source.py +0 -0
  329. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_main.py +0 -0
  330. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_media_embedding.py +0 -0
  331. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_meilisearch_source.py +0 -0
  332. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_microsoft_365_source.py +0 -0
  333. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_mongodb_source.py +0 -0
  334. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_neo4j_source.py +0 -0
  335. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_asset_entity.py +0 -0
  336. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_asset_extract.py +0 -0
  337. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_asset_tags.py +0 -0
  338. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_cohort.py +0 -0
  339. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_execute.py +0 -0
  340. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_files.py +0 -0
  341. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_groups.py +0 -0
  342. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_log_levels.py +0 -0
  343. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_packages.py +0 -0
  344. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_query_assets.py +0 -0
  345. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_sdk_exports.py +0 -0
  346. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_serialize.py +0 -0
  347. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notebook_templates.py +0 -0
  348. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_notion_source.py +0 -0
  349. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_object_storage_download_efficiency.py +0 -0
  350. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_opensearch_source.py +0 -0
  351. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_oracle_source.py +0 -0
  352. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_outputs.py +0 -0
  353. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_payload_window.py +0 -0
  354. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_payload_window_parquet.py +0 -0
  355. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_postgresql_source.py +0 -0
  356. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_powerbi_source.py +0 -0
  357. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_range_reading.py +0 -0
  358. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_recipe_normalizer.py +0 -0
  359. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_reddit_source.py +0 -0
  360. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_rest_backpressure.py +0 -0
  361. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_runtime_packages.py +0 -0
  362. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_s3_compatible_storage_source.py +0 -0
  363. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_sampling_automatic.py +0 -0
  364. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_sampling_cursor.py +0 -0
  365. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_sampling_frontier.py +0 -0
  366. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_sandbox_source.py +0 -0
  367. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_sdk_completions.py +0 -0
  368. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_secret_redaction.py +0 -0
  369. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_semantic_declarations.py +0 -0
  370. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_servicedesk_source.py +0 -0
  371. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_slack_source.py +0 -0
  372. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_source_dependency_groups.py +0 -0
  373. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_source_strategy_conformance.py +0 -0
  374. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_sqlite_source.py +0 -0
  375. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_tableau_source.py +0 -0
  376. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_tabular_automatic_sampling.py +0 -0
  377. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_tabular_lineage.py +0 -0
  378. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_tabular_utils.py +0 -0
  379. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_torch_runtime.py +0 -0
  380. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_urn.py +0 -0
  381. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_uv_sync.py +0 -0
  382. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_wordpress_source.py +0 -0
  383. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_youtube_source.py +0 -0
  384. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/test_youtube_source_integration.py +0 -0
  385. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_archive_extraction.py +0 -0
  386. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_content_extraction.py +0 -0
  387. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_embedded_files.py +0 -0
  388. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_file_metadata.py +0 -0
  389. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_file_parser.py +0 -0
  390. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_file_to_images.py +0 -0
  391. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_legacy_office.py +0 -0
  392. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_payload.py +0 -0
  393. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_transcription.py +0 -0
  394. {classifyre_cli-0.6.12 → classifyre_cli-0.6.14}/tests/utils/test_video_processing.py +0 -0
@@ -0,0 +1,3 @@
1
+ $ uv sync
2
+ Resolved 325 packages in 232ms
3
+ Checked 52 packages in 3ms
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: classifyre-cli
3
- Version: 0.6.12
3
+ Version: 0.6.14
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.6.12",
3
+ "version": "0.6.14",
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.6.12"
3
+ version = "0.6.14"
4
4
  description = "Classifyre CLI — scan and classify unstructured data sources"
5
5
  readme = "README.md"
6
6
  # Upper bound is load-bearing: onnxruntime publishes no cp315 wheels (notably
@@ -426,14 +426,28 @@ def prior_finding_payload(finding: Any) -> dict[str, Any]:
426
426
  "severity": str(getattr(data.get("severity"), "value", data.get("severity")) or ""),
427
427
  "confidence": data.get("confidence") or 0.0,
428
428
  "location": dict(location),
429
- "metadata": {
430
- key: value
431
- for key, value in metadata.items()
432
- if key in {"tabular_row_index", "tabular_column_name", "entity_label", "label"}
433
- },
429
+ "metadata": {key: value for key, value in metadata.items() if key in _PRIOR_METADATA_KEYS},
434
430
  }
435
431
 
436
432
 
433
+ #: What a rule may read of another detector's finding metadata: where it sits,
434
+ #: what it is called, and what a model said -- an LLM's extracted ``fields``, a
435
+ #: decision model's ``question`` and ``answer``. Runner internals stay out.
436
+ _PRIOR_METADATA_KEYS = frozenset(
437
+ {
438
+ "tabular_row_index",
439
+ "tabular_column_name",
440
+ "entity_label",
441
+ "label",
442
+ "fields",
443
+ "question",
444
+ "answer",
445
+ "certainty",
446
+ "model",
447
+ }
448
+ )
449
+
450
+
437
451
  __all__ = [
438
452
  "DEFAULT_LIMITS",
439
453
  "CustomDetectorSession",
@@ -150,10 +150,17 @@ class FieldMapping:
150
150
  upstreams: Sequence[str] = ()
151
151
  transform: str | None = None
152
152
  type: FieldTransform = FieldTransform.TRANSFORMED
153
+ #: The transformations the value passes through, outermost first
154
+ #: (``("SUM", "CASE")``) — what a reader scans for before the full
155
+ #: ``transform`` text.
156
+ steps: Sequence[str] = ()
153
157
 
154
158
  def __post_init__(self) -> None:
155
159
  cleaned = tuple(str(name).strip() for name in self.upstreams if str(name).strip())
156
160
  object.__setattr__(self, "upstreams", cleaned)
161
+ object.__setattr__(
162
+ self, "steps", tuple(str(step).strip() for step in self.steps if str(step).strip())
163
+ )
157
164
  if self.downstream is not None:
158
165
  object.__setattr__(self, "downstream", str(self.downstream).strip() or None)
159
166
  if self.downstream is None and self.type is not FieldTransform.INDIRECT:
@@ -167,6 +174,7 @@ class FieldMapping:
167
174
  "downstream": self.downstream,
168
175
  "upstreams": list(self.upstreams),
169
176
  "transform": self.transform,
177
+ "steps": list(self.steps),
170
178
  "type": str(self.type),
171
179
  }
172
180
 
@@ -339,6 +347,7 @@ def edge_from_payload(payload: dict[str, Any]) -> Edge:
339
347
  downstream=item.get("downstream"),
340
348
  upstreams=item.get("upstreams") or [],
341
349
  transform=item.get("transform"),
350
+ steps=item.get("steps") or [],
342
351
  type=FieldTransform(str(item.get("type") or FieldTransform.TRANSFORMED)),
343
352
  )
344
353
  for item in payload.get("fields") or []
@@ -964,6 +964,11 @@ class DetectorScope(BaseModel):
964
964
  None,
965
965
  description='Asset-metadata equality predicate, e.g. {"doc_type": "jab"}. Every named key must be present on the asset and equal (compared as strings, so 4 and "4" match). A key the asset does not carry excludes it — an absent field is not a match.',
966
966
  )
967
+ content_pattern: str | None = Field(
968
+ None,
969
+ description='Regular expression (case-insensitive) the text of a payload must contain for this detector to run on it. Applied per payload, so on a paged document only the pages that match are read: a language model asked about free cash flow reads the pages that use the term, not all 500 pages of the annual report. Payloads without text (pictures, raw bytes) never match.',
970
+ max_length=2000,
971
+ )
967
972
 
968
973
 
969
974
  class DetectorBudget(BaseModel):
@@ -1868,6 +1873,9 @@ class CustomDetectorConfig(DetectorConfig):
1868
1873
  Configuration for user-defined detector execution
1869
1874
  """
1870
1875
 
1876
+ model_config = ConfigDict(
1877
+ extra='forbid',
1878
+ )
1871
1879
  custom_detector_key: str = Field(
1872
1880
  ..., description='Stable key used to identify one custom detector instance'
1873
1881
  )
@@ -1357,6 +1357,10 @@ class PostgreSQLOptionalScope(BaseModel):
1357
1357
  None,
1358
1358
  description='Optional table allowlist. Accepted forms: schema.table or database.schema.table',
1359
1359
  )
1360
+ include_views: bool | None = Field(
1361
+ True,
1362
+ description="Include view assets in extraction. A view's column lineage is read from its SQL.",
1363
+ )
1360
1364
  table_limit: int | None = Field(
1361
1365
  None, description='Optional cap on number of table assets extracted', ge=1
1362
1366
  )
@@ -1443,6 +1447,10 @@ class MySQLOptionalScope(BaseModel):
1443
1447
  None,
1444
1448
  description='Optional table allowlist. Accepted forms: table or database.table',
1445
1449
  )
1450
+ include_views: bool | None = Field(
1451
+ True,
1452
+ description="Include view assets in extraction. A view's column lineage is read from its SQL.",
1453
+ )
1446
1454
  table_limit: int | None = Field(
1447
1455
  None,
1448
1456
  description='Optional cap on number of table assets extracted per database',
@@ -4979,6 +4987,9 @@ class CoreInput(BaseModel):
4979
4987
 
4980
4988
 
4981
4989
  class SlackInput(CoreInput):
4990
+ model_config = ConfigDict(
4991
+ extra='forbid',
4992
+ )
4982
4993
  type: Literal['SLACK'] = Field(..., description='Type of the asset or source')
4983
4994
  required: SlackRequired
4984
4995
  masked: SlackMasked
@@ -5001,6 +5012,9 @@ class SlackInput(CoreInput):
5001
5012
 
5002
5013
 
5003
5014
  class EmailInput(CoreInput):
5015
+ model_config = ConfigDict(
5016
+ extra='forbid',
5017
+ )
5004
5018
  type: Literal['EMAIL'] = Field(..., description='Type of the asset or source')
5005
5019
  required: EmailRequired
5006
5020
  masked: EmailMasked
@@ -5023,6 +5037,9 @@ class EmailInput(CoreInput):
5023
5037
 
5024
5038
 
5025
5039
  class S3CompatibleStorageInput(CoreInput):
5040
+ model_config = ConfigDict(
5041
+ extra='forbid',
5042
+ )
5026
5043
  type: Literal['S3_COMPATIBLE_STORAGE'] = Field(
5027
5044
  ..., description='Type of the asset or source'
5028
5045
  )
@@ -5047,6 +5064,9 @@ class S3CompatibleStorageInput(CoreInput):
5047
5064
 
5048
5065
 
5049
5066
  class LocalFolderInput(CoreInput):
5067
+ model_config = ConfigDict(
5068
+ extra='forbid',
5069
+ )
5050
5070
  type: Literal['LOCAL_FOLDER'] = Field(
5051
5071
  ..., description='Type of the asset or source'
5052
5072
  )
@@ -5071,6 +5091,9 @@ class LocalFolderInput(CoreInput):
5071
5091
 
5072
5092
 
5073
5093
  class SandboxInput(CoreInput):
5094
+ model_config = ConfigDict(
5095
+ extra='forbid',
5096
+ )
5074
5097
  type: Literal['SANDBOX'] = Field(..., description='Type of the asset or source')
5075
5098
  required: SandboxRequired
5076
5099
  masked: SandboxMasked | None = None
@@ -5093,6 +5116,9 @@ class SandboxInput(CoreInput):
5093
5116
 
5094
5117
 
5095
5118
  class AzureBlobStorageInput(CoreInput):
5119
+ model_config = ConfigDict(
5120
+ extra='forbid',
5121
+ )
5096
5122
  type: Literal['AZURE_BLOB_STORAGE'] = Field(
5097
5123
  ..., description='Type of the asset or source'
5098
5124
  )
@@ -5117,6 +5143,9 @@ class AzureBlobStorageInput(CoreInput):
5117
5143
 
5118
5144
 
5119
5145
  class GoogleCloudStorageInput(CoreInput):
5146
+ model_config = ConfigDict(
5147
+ extra='forbid',
5148
+ )
5120
5149
  type: Literal['GOOGLE_CLOUD_STORAGE'] = Field(
5121
5150
  ..., description='Type of the asset or source'
5122
5151
  )
@@ -5141,6 +5170,9 @@ class GoogleCloudStorageInput(CoreInput):
5141
5170
 
5142
5171
 
5143
5172
  class WordPressInput(CoreInput):
5173
+ model_config = ConfigDict(
5174
+ extra='forbid',
5175
+ )
5144
5176
  type: Literal['WORDPRESS'] = Field(..., description='Type of the asset or source')
5145
5177
  required: WordPressRequired
5146
5178
  masked: WordPressMasked
@@ -5163,6 +5195,9 @@ class WordPressInput(CoreInput):
5163
5195
 
5164
5196
 
5165
5197
  class PostgreSQLInput(CoreInput):
5198
+ model_config = ConfigDict(
5199
+ extra='forbid',
5200
+ )
5166
5201
  type: Literal['POSTGRESQL'] = Field(..., description='Type of the asset or source')
5167
5202
  required: PostgreSQLRequired
5168
5203
  masked: PostgreSQLMasked
@@ -5185,6 +5220,9 @@ class PostgreSQLInput(CoreInput):
5185
5220
 
5186
5221
 
5187
5222
  class MySQLInput(CoreInput):
5223
+ model_config = ConfigDict(
5224
+ extra='forbid',
5225
+ )
5188
5226
  type: Literal['MYSQL'] = Field(..., description='Type of the asset or source')
5189
5227
  required: MySQLRequired
5190
5228
  masked: MySQLMasked
@@ -5207,6 +5245,9 @@ class MySQLInput(CoreInput):
5207
5245
 
5208
5246
 
5209
5247
  class MSSQLInput(CoreInput):
5248
+ model_config = ConfigDict(
5249
+ extra='forbid',
5250
+ )
5210
5251
  type: Literal['MSSQL'] = Field(..., description='Type of the asset or source')
5211
5252
  required: MSSQLRequired
5212
5253
  masked: MSSQLMasked
@@ -5229,6 +5270,9 @@ class MSSQLInput(CoreInput):
5229
5270
 
5230
5271
 
5231
5272
  class OracleInput(CoreInput):
5273
+ model_config = ConfigDict(
5274
+ extra='forbid',
5275
+ )
5232
5276
  type: Literal['ORACLE'] = Field(..., description='Type of the asset or source')
5233
5277
  required: OracleRequired
5234
5278
  masked: OracleMasked
@@ -5251,6 +5295,9 @@ class OracleInput(CoreInput):
5251
5295
 
5252
5296
 
5253
5297
  class HiveInput(CoreInput):
5298
+ model_config = ConfigDict(
5299
+ extra='forbid',
5300
+ )
5254
5301
  type: Literal['HIVE'] = Field(..., description='Type of the asset or source')
5255
5302
  required: HiveRequired
5256
5303
  masked: HiveMasked
@@ -5273,6 +5320,9 @@ class HiveInput(CoreInput):
5273
5320
 
5274
5321
 
5275
5322
  class DatabricksInput(CoreInput):
5323
+ model_config = ConfigDict(
5324
+ extra='forbid',
5325
+ )
5276
5326
  type: Literal['DATABRICKS'] = Field(..., description='Type of the asset or source')
5277
5327
  required: PersonalAccessToken | ServicePrincipalOAuthM2M | AzureServicePrincipal = (
5278
5328
  Field(..., title='DatabricksRequired')
@@ -5299,6 +5349,9 @@ class DatabricksInput(CoreInput):
5299
5349
 
5300
5350
 
5301
5351
  class SnowflakeInput(CoreInput):
5352
+ model_config = ConfigDict(
5353
+ extra='forbid',
5354
+ )
5302
5355
  type: Literal['SNOWFLAKE'] = Field(..., description='Type of the asset or source')
5303
5356
  required: (
5304
5357
  SnowflakeRequiredDefaultAuthenticator
@@ -5331,6 +5384,9 @@ class SnowflakeInput(CoreInput):
5331
5384
 
5332
5385
 
5333
5386
  class DremioInput(CoreInput):
5387
+ model_config = ConfigDict(
5388
+ extra='forbid',
5389
+ )
5334
5390
  type: Literal['DREMIO'] = Field(..., description='Type of the asset or source')
5335
5391
  required: DremioRequiredSoftware | DremioRequiredCloud = Field(
5336
5392
  ..., title='DremioRequired'
@@ -5355,6 +5411,9 @@ class DremioInput(CoreInput):
5355
5411
 
5356
5412
 
5357
5413
  class MongoDBInput(CoreInput):
5414
+ model_config = ConfigDict(
5415
+ extra='forbid',
5416
+ )
5358
5417
  type: Literal['MONGODB'] = Field(..., description='Type of the asset or source')
5359
5418
  required: MongoDBRequiredAtlas | MongoDBRequiredOnPrem = Field(
5360
5419
  ..., title='MongoDBRequired'
@@ -5381,6 +5440,9 @@ class MongoDBInput(CoreInput):
5381
5440
 
5382
5441
 
5383
5442
  class Neo4jInput(CoreInput):
5443
+ model_config = ConfigDict(
5444
+ extra='forbid',
5445
+ )
5384
5446
  type: Literal['NEO4J'] = Field(..., description='Type of the asset or source')
5385
5447
  required: Neo4jRequired
5386
5448
  masked: Neo4jMaskedUsernamePassword | Neo4jMaskedNone = Field(
@@ -5405,6 +5467,9 @@ class Neo4jInput(CoreInput):
5405
5467
 
5406
5468
 
5407
5469
  class PowerBIInput(CoreInput):
5470
+ model_config = ConfigDict(
5471
+ extra='forbid',
5472
+ )
5408
5473
  type: Literal['POWERBI'] = Field(..., description='Type of the asset or source')
5409
5474
  required: PowerBIRequiredServicePrincipal | PowerBIRequiredAccessToken = Field(
5410
5475
  ..., title='PowerBIRequired'
@@ -5431,6 +5496,9 @@ class PowerBIInput(CoreInput):
5431
5496
 
5432
5497
 
5433
5498
  class TableauInput(CoreInput):
5499
+ model_config = ConfigDict(
5500
+ extra='forbid',
5501
+ )
5434
5502
  type: Literal['TABLEAU'] = Field(..., description='Type of the asset or source')
5435
5503
  required: TableauRequiredUsernamePassword | TableauRequiredPersonalAccessToken = (
5436
5504
  Field(..., title='TableauRequired')
@@ -5457,6 +5525,9 @@ class TableauInput(CoreInput):
5457
5525
 
5458
5526
 
5459
5527
  class ConfluenceInput(CoreInput):
5528
+ model_config = ConfigDict(
5529
+ extra='forbid',
5530
+ )
5460
5531
  type: Literal['CONFLUENCE'] = Field(..., description='Type of the asset or source')
5461
5532
  required: ConfluenceRequired
5462
5533
  masked: ConfluenceMasked
@@ -5479,6 +5550,9 @@ class ConfluenceInput(CoreInput):
5479
5550
 
5480
5551
 
5481
5552
  class JiraInput(CoreInput):
5553
+ model_config = ConfigDict(
5554
+ extra='forbid',
5555
+ )
5482
5556
  type: Literal['JIRA'] = Field(..., description='Type of the asset or source')
5483
5557
  required: JiraRequired
5484
5558
  masked: JiraMasked
@@ -5501,6 +5575,9 @@ class JiraInput(CoreInput):
5501
5575
 
5502
5576
 
5503
5577
  class ServiceDeskInput(CoreInput):
5578
+ model_config = ConfigDict(
5579
+ extra='forbid',
5580
+ )
5504
5581
  type: Literal['SERVICEDESK'] = Field(..., description='Type of the asset or source')
5505
5582
  required: ServiceDeskRequired
5506
5583
  masked: ServiceDeskMasked
@@ -5523,6 +5600,9 @@ class ServiceDeskInput(CoreInput):
5523
5600
 
5524
5601
 
5525
5602
  class SQLiteInput(CoreInput):
5603
+ model_config = ConfigDict(
5604
+ extra='forbid',
5605
+ )
5526
5606
  type: Literal['SQLITE'] = Field(..., description='Type of the asset or source')
5527
5607
  required: SQLiteRequired
5528
5608
  masked: dict[str, Any] | None = Field(
@@ -5549,6 +5629,9 @@ class SQLiteInput(CoreInput):
5549
5629
 
5550
5630
 
5551
5631
  class NotionInput(CoreInput):
5632
+ model_config = ConfigDict(
5633
+ extra='forbid',
5634
+ )
5552
5635
  type: Literal['NOTION'] = Field(..., description='Type of the asset or source')
5553
5636
  required: NotionRequired
5554
5637
  masked: NotionMasked
@@ -5579,6 +5662,9 @@ class DeltaLakeOptional(BaseModel):
5579
5662
 
5580
5663
 
5581
5664
  class DeltaLakeInput(CoreInput):
5665
+ model_config = ConfigDict(
5666
+ extra='forbid',
5667
+ )
5582
5668
  type: Literal['DELTA_LAKE'] = Field(..., description='Type of the asset or source')
5583
5669
  required: DeltaLakeRequired
5584
5670
  masked: S3CompatibleStorageMasked | None = None
@@ -5609,6 +5695,9 @@ class IcebergOptional(BaseModel):
5609
5695
 
5610
5696
 
5611
5697
  class IcebergInput(CoreInput):
5698
+ model_config = ConfigDict(
5699
+ extra='forbid',
5700
+ )
5612
5701
  type: Literal['ICEBERG'] = Field(..., description='Type of the asset or source')
5613
5702
  required: IcebergRequired
5614
5703
  masked: S3CompatibleStorageMasked | None = None
@@ -5631,6 +5720,9 @@ class IcebergInput(CoreInput):
5631
5720
 
5632
5721
 
5633
5722
  class KafkaInput(CoreInput):
5723
+ model_config = ConfigDict(
5724
+ extra='forbid',
5725
+ )
5634
5726
  type: Literal['KAFKA'] = Field(..., description='Type of the asset or source')
5635
5727
  required: (
5636
5728
  NoAuthentication
@@ -5664,6 +5756,9 @@ class KafkaInput(CoreInput):
5664
5756
 
5665
5757
 
5666
5758
  class ElasticsearchInput(CoreInput):
5759
+ model_config = ConfigDict(
5760
+ extra='forbid',
5761
+ )
5667
5762
  type: Literal['ELASTICSEARCH'] = Field(
5668
5763
  ..., description='Type of the asset or source'
5669
5764
  )
@@ -5692,6 +5787,9 @@ class ElasticsearchInput(CoreInput):
5692
5787
 
5693
5788
 
5694
5789
  class OpenSearchInput(CoreInput):
5790
+ model_config = ConfigDict(
5791
+ extra='forbid',
5792
+ )
5695
5793
  type: Literal['OPENSEARCH'] = Field(..., description='Type of the asset or source')
5696
5794
  required: NoAuthentication2 | BasicUsernamePassword | APIKeyBearerToken = Field(
5697
5795
  ..., title='OpenSearchRequired'
@@ -5718,6 +5816,9 @@ class OpenSearchInput(CoreInput):
5718
5816
 
5719
5817
 
5720
5818
  class MeilisearchInput(CoreInput):
5819
+ model_config = ConfigDict(
5820
+ extra='forbid',
5821
+ )
5721
5822
  type: Literal['MEILISEARCH'] = Field(..., description='Type of the asset or source')
5722
5823
  required: NoAuthentication4 | APIKeyBearerToken2 = Field(
5723
5824
  ..., title='MeilisearchRequired'
@@ -5744,6 +5845,9 @@ class MeilisearchInput(CoreInput):
5744
5845
 
5745
5846
 
5746
5847
  class Microsoft365Input(CoreInput):
5848
+ model_config = ConfigDict(
5849
+ extra='forbid',
5850
+ )
5747
5851
  type: Literal['MICROSOFT_365'] = Field(
5748
5852
  ..., description='Type of the asset or source'
5749
5853
  )
@@ -5776,6 +5880,9 @@ class Microsoft365Input(CoreInput):
5776
5880
 
5777
5881
 
5778
5882
  class GoogleWorkspaceInput(CoreInput):
5883
+ model_config = ConfigDict(
5884
+ extra='forbid',
5885
+ )
5779
5886
  type: Literal['GOOGLE_WORKSPACE'] = Field(
5780
5887
  ..., description='Type of the asset or source'
5781
5888
  )
@@ -5804,6 +5911,9 @@ class GoogleWorkspaceInput(CoreInput):
5804
5911
 
5805
5912
 
5806
5913
  class DropboxInput(CoreInput):
5914
+ model_config = ConfigDict(
5915
+ extra='forbid',
5916
+ )
5807
5917
  type: Literal['DROPBOX'] = Field(..., description='Type of the asset or source')
5808
5918
  required: (
5809
5919
  DropboxOAuthRefreshTokenRecommended
@@ -5832,6 +5942,9 @@ class DropboxInput(CoreInput):
5832
5942
 
5833
5943
 
5834
5944
  class HuggingFaceInput(CoreInput):
5945
+ model_config = ConfigDict(
5946
+ extra='forbid',
5947
+ )
5835
5948
  type: Literal['HUGGING_FACE'] = Field(
5836
5949
  ..., description='Type of the asset or source'
5837
5950
  )
@@ -5856,6 +5969,9 @@ class HuggingFaceInput(CoreInput):
5856
5969
 
5857
5970
 
5858
5971
  class GitInput(CoreInput):
5972
+ model_config = ConfigDict(
5973
+ extra='forbid',
5974
+ )
5859
5975
  type: Literal['GIT'] = Field(..., description='Type of the asset or source')
5860
5976
  required: GitRequired
5861
5977
  masked: GitMasked | None = None
@@ -5907,6 +6023,9 @@ class CustomCohortWeights(BaseModel):
5907
6023
 
5908
6024
 
5909
6025
  class YouTubeInput(CoreInput):
6026
+ model_config = ConfigDict(
6027
+ extra='forbid',
6028
+ )
5910
6029
  type: Literal['YOUTUBE'] = Field(..., description='Type of the asset or source')
5911
6030
  required: YouTubeRequired
5912
6031
  masked: YouTubeMasked | None = None
@@ -5929,6 +6048,9 @@ class YouTubeInput(CoreInput):
5929
6048
 
5930
6049
 
5931
6050
  class RedditInput(CoreInput):
6051
+ model_config = ConfigDict(
6052
+ extra='forbid',
6053
+ )
5932
6054
  type: Literal['REDDIT'] = Field(..., description='Type of the asset or source')
5933
6055
  required: (
5934
6056
  RedditRequiredReadOnly | RedditRequiredScript | RedditRequiredRefreshToken
@@ -5983,6 +6105,9 @@ class CustomOptional(BaseModel):
5983
6105
 
5984
6106
 
5985
6107
  class CustomInput(CoreInput):
6108
+ model_config = ConfigDict(
6109
+ extra='forbid',
6110
+ )
5986
6111
  type: Literal['CUSTOM'] = Field(..., description='Type of the asset or source')
5987
6112
  required: CustomRequired
5988
6113
  masked: CustomMasked | None = None
@@ -716,12 +716,14 @@ class Context:
716
716
 
717
717
  @property
718
718
  def config_changed(self) -> bool:
719
- """True on the first run after this source's settings changed.
719
+ """True on the first run after this source's settings changed, and on a
720
+ run started as a full rescan.
720
721
 
721
722
  "Settings" is anything in the source's configuration -- scope,
722
723
  sampling, variables, the notebook itself, which detectors are on --
723
724
  and the definition of any custom detector it uses. Rotating a secret
724
- does not count.
725
+ does not count. A full rescan asks for the whole sweep again with the
726
+ same settings, so it sets the flag as well.
725
727
 
726
728
  A built-in source starts its sweep over when that happens. A notebook
727
729
  owns its own cursor, so nothing is taken from it; it is told instead,
@@ -758,10 +760,11 @@ class Context:
758
760
  ``(rank, id)``: ``rank`` is what makes an item newer -- a timestamp, an
759
761
  increasing number -- and must be an int, float or string of one
760
762
  consistent type that only changes when the item does; ``id`` is unique
761
- to the item. Each run gets ``limit`` items (``rows_per_page`` by
762
- default): everything newer than what earlier runs read comes first,
763
- the rest continues backwards from where the last run stopped, and once
764
- the whole listing has been read only new items are returned.
763
+ to the item. Each run gets ``limit`` items -- by default ``ctx.limit``:
764
+ the whole listing under the ALL strategy, ``rows_per_page`` otherwise.
765
+ Everything newer than what earlier runs read comes first, the rest
766
+ continues backwards from where the last run stopped, and once the whole
767
+ listing has been read only new items are returned.
765
768
 
766
769
  The position is kept in the cursor beside whatever you store there,
767
770
  one per ``name``, and starts over when ``ctx.config_changed``. Calling
@@ -770,10 +773,11 @@ class Context:
770
773
  stored = self._cursor.get("frontier")
771
774
  previous = stored.get(str(name)) if isinstance(stored, dict) else None
772
775
  frontier = ListFrontier(None if self._config_changed else previous)
773
- window = frontier.window(
774
- ((*order(item), item) for item in items),
775
- int(limit) if limit else self.page_size,
776
- )
776
+ entries = [(*order(item), item) for item in items]
777
+ # Without a limit of its own the run takes what the source's sampling
778
+ # asks for: everything under ALL, ``rows_per_page`` otherwise.
779
+ budget = int(limit) if limit else (self.limit if self.limit is not None else len(entries))
780
+ window = frontier.window(entries, budget)
777
781
  state = frontier.to_state()
778
782
  if state is not None:
779
783
  self._frontier_state[str(name)] = state
@@ -3,7 +3,9 @@
3
3
  from __future__ import annotations
4
4
 
5
5
  import asyncio
6
+ import functools
6
7
  import logging
8
+ import re
7
9
  import time
8
10
  from collections.abc import AsyncGenerator, Awaitable, Callable
9
11
  from datetime import UTC, datetime
@@ -107,6 +109,32 @@ def _detector_covers_content_type(detector: BaseDetector, content_type: str) ->
107
109
  return any(actual.startswith(str(prefix).strip().lower()) for prefix in content_types)
108
110
 
109
111
 
112
+ @functools.lru_cache(maxsize=256)
113
+ def _content_pattern(pattern: str) -> re.Pattern[str] | None:
114
+ try:
115
+ return re.compile(pattern, re.IGNORECASE)
116
+ except re.error:
117
+ logger.warning("Ignoring invalid detector scope content_pattern %r", pattern)
118
+ return None
119
+
120
+
121
+ def _detector_covers_text(detector: BaseDetector, content: str | bytes) -> bool:
122
+ """Whether a payload's text contains the scope's ``content_pattern``.
123
+
124
+ Checked per payload, so a paged document is narrowed page by page: an
125
+ expensive model runs on the pages that use the words it is asked about,
126
+ not on the whole report. A payload without text never matches.
127
+ """
128
+ scope = _detector_scope(detector)
129
+ pattern = getattr(scope, "content_pattern", None) if scope is not None else None
130
+ if not pattern:
131
+ return True
132
+ if not isinstance(content, str):
133
+ return False
134
+ compiled = _content_pattern(str(pattern))
135
+ return compiled is None or compiled.search(content) is not None
136
+
137
+
110
138
  class _DetectorInfo:
111
139
  """Serialisable metadata for routing a detector through the process pool."""
112
140
 
@@ -909,6 +937,7 @@ class DetectorPipeline:
909
937
  # A declared scope narrows what the engine already supports; it
910
938
  # can never widen it, so this runs after the engine's own check.
911
939
  and _detector_covers_content_type(detector, content_type)
940
+ and _detector_covers_text(detector, content)
912
941
  ]
913
942
  async with self._breaker.first_contact(
914
943
  *(self._breaker_key_or_default(detector) for detector in compatible)
@@ -367,6 +367,7 @@ class ScanCache:
367
367
  self._verify: str = verify if verify in {"metadata", "content"} else "content"
368
368
 
369
369
  self._cacheable, self._always_run = self._build_fingerprints(recipe)
370
+ self._reads_findings = self._rules_reading_findings(recipe)
370
371
 
371
372
  if not supported:
372
373
  self._disabled_reason = "source does not support the scan cache"
@@ -423,6 +424,20 @@ class ScanCache:
423
424
 
424
425
  return cacheable, frozenset(always_run)
425
426
 
427
+ @staticmethod
428
+ def _rules_reading_findings(recipe: dict[str, Any]) -> frozenset[str]:
429
+ """Keys of the code detectors that read the other detectors' findings."""
430
+ keys: set[str] = set()
431
+ entries = recipe.get("detectors")
432
+ for entry in entries if isinstance(entries, list) else []:
433
+ if not isinstance(entry, dict) or not entry.get("enabled", True):
434
+ continue
435
+ config = entry.get("config")
436
+ schema = config.get("pipeline_schema") if isinstance(config, dict) else None
437
+ if isinstance(schema, dict) and schema.get("needs_findings"):
438
+ keys.add(detector_cache_key(str(entry.get("type") or ""), config))
439
+ return frozenset(keys)
440
+
426
441
  @property
427
442
  def enabled(self) -> bool:
428
443
  return self._enabled
@@ -515,8 +530,12 @@ class ScanCache:
515
530
  if prior.detectors.get(key) != fingerprint
516
531
  }
517
532
  run_keys = stale | set(self._always_run)
533
+ if run_keys & self._reads_findings:
534
+ # A rule with needs_findings sees only what ran in this pass: re-run
535
+ # alone, it would judge an asset as if nothing else had found anything.
536
+ run_keys |= set(self._cacheable)
518
537
  carried = {
519
- key: fingerprint for key, fingerprint in self._cacheable.items() if key not in stale
538
+ key: fingerprint for key, fingerprint in self._cacheable.items() if key not in run_keys
520
539
  }
521
540
 
522
541
  # Media the workspace embeds and this asset has not yet sent under the