classifyre-cli 0.4.90__tar.gz → 0.4.92__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 (285) hide show
  1. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/.turbo/turbo-build.log +1 -1
  2. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/PKG-INFO +1 -1
  3. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/package.json +1 -1
  4. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/pyproject.toml +1 -1
  5. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/file_evaluation/runner.py +1 -1
  6. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/models/generated_input.py +229 -0
  7. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/atlassian_common.py +6 -1
  8. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/base.py +6 -5
  9. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/confluence/source.py +4 -0
  10. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/email/source.py +6 -1
  11. classifyre_cli-0.4.92/src/sources/git/__init__.py +3 -0
  12. classifyre_cli-0.4.92/src/sources/git/source.py +1007 -0
  13. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/google_workspace/source.py +10 -1
  14. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/hugging_face/source.py +3 -0
  15. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/microsoft_365/source.py +10 -1
  16. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/notion/source.py +4 -0
  17. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/object_storage/base.py +13 -2
  18. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/embedded_files.py +175 -52
  19. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/file_metadata.py +25 -0
  20. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/file_parser.py +486 -40
  21. classifyre_cli-0.4.92/tests/test_arrow_ipc_payloads.py +473 -0
  22. classifyre_cli-0.4.92/tests/test_git_source.py +600 -0
  23. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_object_storage_download_efficiency.py +27 -0
  24. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_source_strategy_conformance.py +3 -0
  25. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_file_parser.py +81 -0
  26. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/uv.lock +22 -22
  27. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/.gitignore +0 -0
  28. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/.python-version +0 -0
  29. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/README.md +0 -0
  30. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/main.py +0 -0
  31. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/scripts/generate_models.py +0 -0
  32. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/__init__.py +0 -0
  33. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/config.py +0 -0
  34. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/__init__.py +0 -0
  35. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/base.py +0 -0
  36. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/broken_links/__init__.py +0 -0
  37. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/broken_links/detector.py +0 -0
  38. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/config.py +0 -0
  39. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/content/__init__.py +0 -0
  40. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/__init__.py +0 -0
  41. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/detector.py +0 -0
  42. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/extractor.py +0 -0
  43. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/__init__.py +0 -0
  44. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_base.py +0 -0
  45. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_factory.py +0 -0
  46. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_gliner2.py +0 -0
  47. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_image_classification.py +0 -0
  48. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_llm.py +0 -0
  49. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_object_detection.py +0 -0
  50. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_regex.py +0 -0
  51. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/runners/_text_classification.py +0 -0
  52. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/custom/trainer.py +0 -0
  53. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/dependencies.py +0 -0
  54. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/engine_version.py +0 -0
  55. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/pii/__init__.py +0 -0
  56. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/pii/detector.py +0 -0
  57. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/secrets/__init__.py +0 -0
  58. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/secrets/detector.py +0 -0
  59. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/threat/__init__.py +0 -0
  60. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/threat/code_security_detector.py +0 -0
  61. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/detectors/threat/yara_detector.py +0 -0
  62. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/file_evaluation/__init__.py +0 -0
  63. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/main.py +0 -0
  64. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/models/generated_detectors.py +0 -0
  65. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/models/generated_single_asset_scan_results.py +0 -0
  66. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/outputs/__init__.py +0 -0
  67. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/outputs/base.py +0 -0
  68. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/outputs/console.py +0 -0
  69. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/outputs/factory.py +0 -0
  70. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/outputs/file.py +0 -0
  71. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/outputs/rest.py +0 -0
  72. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/__init__.py +0 -0
  73. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/content_provider.py +0 -0
  74. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/detector_pipeline.py +0 -0
  75. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/parsed_content_provider.py +0 -0
  76. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/payload_window.py +0 -0
  77. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/scan_cache.py +0 -0
  78. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/text_artifact.py +0 -0
  79. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/pipeline/worker_pool.py +0 -0
  80. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/__init__.py +0 -0
  81. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/asset_metadata.py +0 -0
  82. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/azure_blob_storage/__init__.py +0 -0
  83. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/azure_blob_storage/source.py +0 -0
  84. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/confluence/__init__.py +0 -0
  85. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/databricks/__init__.py +0 -0
  86. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/databricks/source.py +0 -0
  87. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/delta_lake/__init__.py +0 -0
  88. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/delta_lake/source.py +0 -0
  89. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/dependencies.py +0 -0
  90. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/dropbox/__init__.py +0 -0
  91. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/dropbox/auth.py +0 -0
  92. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/dropbox/source.py +0 -0
  93. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/elasticsearch/__init__.py +0 -0
  94. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/elasticsearch/source.py +0 -0
  95. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/email/__init__.py +0 -0
  96. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/google_cloud_storage/__init__.py +0 -0
  97. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/google_cloud_storage/source.py +0 -0
  98. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/google_workspace/__init__.py +0 -0
  99. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/hive/__init__.py +0 -0
  100. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/hive/source.py +0 -0
  101. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/hugging_face/__init__.py +0 -0
  102. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/iceberg/__init__.py +0 -0
  103. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/iceberg/source.py +0 -0
  104. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/jira/__init__.py +0 -0
  105. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/jira/source.py +0 -0
  106. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/kafka/__init__.py +0 -0
  107. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/kafka/rest.py +0 -0
  108. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/kafka/source.py +0 -0
  109. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/lakehouse_base.py +0 -0
  110. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/local_folder/__init__.py +0 -0
  111. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/local_folder/source.py +0 -0
  112. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/meilisearch/__init__.py +0 -0
  113. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/meilisearch/source.py +0 -0
  114. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/microsoft_365/__init__.py +0 -0
  115. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/mongodb/__init__.py +0 -0
  116. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/mongodb/source.py +0 -0
  117. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/mssql/__init__.py +0 -0
  118. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/mssql/source.py +0 -0
  119. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/mysql/__init__.py +0 -0
  120. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/mysql/source.py +0 -0
  121. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/neo4j/__init__.py +0 -0
  122. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/neo4j/source.py +0 -0
  123. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/notion/__init__.py +0 -0
  124. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/notion/client.py +0 -0
  125. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/opensearch/__init__.py +0 -0
  126. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/opensearch/source.py +0 -0
  127. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/oracle/__init__.py +0 -0
  128. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/oracle/source.py +0 -0
  129. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/postgresql/__init__.py +0 -0
  130. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/postgresql/source.py +0 -0
  131. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/powerbi/__init__.py +0 -0
  132. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/powerbi/source.py +0 -0
  133. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/recipe_normalizer.py +0 -0
  134. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/reddit/__init__.py +0 -0
  135. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/reddit/source.py +0 -0
  136. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/s3_client.py +0 -0
  137. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/s3_compatible_storage/README.md +0 -0
  138. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/s3_compatible_storage/__init__.py +0 -0
  139. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/s3_compatible_storage/source.py +0 -0
  140. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/sandbox/__init__.py +0 -0
  141. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/sandbox/source.py +0 -0
  142. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/search_engine_base.py +0 -0
  143. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/servicedesk/__init__.py +0 -0
  144. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/servicedesk/source.py +0 -0
  145. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/slack/__init__.py +0 -0
  146. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/slack/source.py +0 -0
  147. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/snowflake/__init__.py +0 -0
  148. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/snowflake/source.py +0 -0
  149. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/sqlite/__init__.py +0 -0
  150. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/sqlite/source.py +0 -0
  151. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/tableau/__init__.py +0 -0
  152. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/tableau/source.py +0 -0
  153. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/tabular_base.py +0 -0
  154. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/tabular_utils.py +0 -0
  155. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/wordpress/__init__.py +0 -0
  156. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/wordpress/source.py +0 -0
  157. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/youtube/__init__.py +0 -0
  158. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/sources/youtube/source.py +0 -0
  159. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/telemetry.py +0 -0
  160. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/__init__.py +0 -0
  161. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/archive_extraction.py +0 -0
  162. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/content_extraction.py +0 -0
  163. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/dependency_groups.py +0 -0
  164. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/external_video.py +0 -0
  165. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/file_to_images.py +0 -0
  166. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/hashing.py +0 -0
  167. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/legacy_office.py +0 -0
  168. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/payload.py +0 -0
  169. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/range_reader.py +0 -0
  170. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/resources.py +0 -0
  171. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/transcription.py +0 -0
  172. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/uv_sync.py +0 -0
  173. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/validation.py +0 -0
  174. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/src/utils/video_processing.py +0 -0
  175. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/__init__.py +0 -0
  176. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/_lakehouse_fakes.py +0 -0
  177. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/conftest.py +0 -0
  178. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/__init__.py +0 -0
  179. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/broken_links/test_broken_links_detector.py +0 -0
  180. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/conftest.py +0 -0
  181. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/content/__init__.py +0 -0
  182. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/__init__.py +0 -0
  183. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/conftest.py +0 -0
  184. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/test_gliner2_classification.py +0 -0
  185. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/test_invoice_extraction.py +0 -0
  186. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/test_llm_runner.py +0 -0
  187. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/test_pipeline_integration.py +0 -0
  188. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/test_regex_runner.py +0 -0
  189. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/test_runner_hardening.py +0 -0
  190. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/custom/test_transformer_runners.py +0 -0
  191. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/__init__.py +0 -0
  192. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/conftest.py +0 -0
  193. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/sample_invoice.pdf +0 -0
  194. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/test_pii_chunking.py +0 -0
  195. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/test_pii_detector.py +0 -0
  196. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/test_pii_detector_extended.py +0 -0
  197. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/test_pii_regional_entities.py +0 -0
  198. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/pii/test_pii_severity.py +0 -0
  199. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/secrets/__init__.py +0 -0
  200. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/secrets/test_secrets_detector.py +0 -0
  201. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/secrets/test_secrets_detector_extended.py +0 -0
  202. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_base_detector.py +0 -0
  203. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_custom_detector_examples_runtime.py +0 -0
  204. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_detector_catalog_commercial.py +0 -0
  205. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_detector_pipeline_types.py +0 -0
  206. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_detector_schema_examples.py +0 -0
  207. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_detector_types.py +0 -0
  208. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_phase2_detectors.py +0 -0
  209. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/test_registry.py +0 -0
  210. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/threat/__init__.py +0 -0
  211. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/threat/test_code_security_detector.py +0 -0
  212. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/detectors/threat/test_yara_detector.py +0 -0
  213. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/integration/test_wordpress_broken_links_detector.py +0 -0
  214. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/integration/test_wordpress_links_assets.py +0 -0
  215. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/pipeline/test_detector_outcomes.py +0 -0
  216. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/pipeline/test_detector_pipeline.py +0 -0
  217. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/pipeline/test_worker_pool.py +0 -0
  218. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_assets_metadata_catalog.py +0 -0
  219. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_azure_blob_storage_source.py +0 -0
  220. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_base_source_attachment.py +0 -0
  221. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_base_source_sampling.py +0 -0
  222. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_byte_valued_fields.py +0 -0
  223. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_config.py +0 -0
  224. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_confluence_source.py +0 -0
  225. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_custom_extractor.py +0 -0
  226. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_databricks_source.py +0 -0
  227. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_delta_lake_source.py +0 -0
  228. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_dependency_groups.py +0 -0
  229. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_dropbox_auth_command.py +0 -0
  230. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_dropbox_source.py +0 -0
  231. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_elasticsearch_source.py +0 -0
  232. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_email_source.py +0 -0
  233. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_file_evaluation_runner.py +0 -0
  234. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_google_cloud_storage_source.py +0 -0
  235. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_google_workspace_source.py +0 -0
  236. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_hashing.py +0 -0
  237. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_hive_source.py +0 -0
  238. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_hugging_face_source.py +0 -0
  239. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_iceberg_source.py +0 -0
  240. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_jira_source.py +0 -0
  241. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_kafka_source.py +0 -0
  242. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_local_folder_source.py +0 -0
  243. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_main.py +0 -0
  244. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_meilisearch_source.py +0 -0
  245. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_microsoft_365_source.py +0 -0
  246. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_mongodb_source.py +0 -0
  247. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_mssql_source.py +0 -0
  248. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_mysql_source.py +0 -0
  249. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_neo4j_source.py +0 -0
  250. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_notion_source.py +0 -0
  251. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_opensearch_source.py +0 -0
  252. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_oracle_source.py +0 -0
  253. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_outputs.py +0 -0
  254. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_payload_window.py +0 -0
  255. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_payload_window_parquet.py +0 -0
  256. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_postgresql_source.py +0 -0
  257. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_powerbi_source.py +0 -0
  258. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_range_reading.py +0 -0
  259. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_recipe_normalizer.py +0 -0
  260. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_reddit_source.py +0 -0
  261. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_s3_compatible_storage_source.py +0 -0
  262. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_sampling_automatic.py +0 -0
  263. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_sandbox_source.py +0 -0
  264. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_scan_cache.py +0 -0
  265. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_servicedesk_source.py +0 -0
  266. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_slack_source.py +0 -0
  267. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_snowflake_source.py +0 -0
  268. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_source_dependency_groups.py +0 -0
  269. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_sqlite_source.py +0 -0
  270. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_tableau_source.py +0 -0
  271. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_tabular_automatic_sampling.py +0 -0
  272. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_tabular_utils.py +0 -0
  273. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_uv_sync.py +0 -0
  274. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_wordpress_source.py +0 -0
  275. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_youtube_source.py +0 -0
  276. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/test_youtube_source_integration.py +0 -0
  277. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_archive_extraction.py +0 -0
  278. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_content_extraction.py +0 -0
  279. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_embedded_files.py +0 -0
  280. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_file_metadata.py +0 -0
  281. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_file_to_images.py +0 -0
  282. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_legacy_office.py +0 -0
  283. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_payload.py +0 -0
  284. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_transcription.py +0 -0
  285. {classifyre_cli-0.4.90 → classifyre_cli-0.4.92}/tests/utils/test_video_processing.py +0 -0
@@ -1,3 +1,3 @@
1
1
  $ uv sync
2
- Resolved 307 packages in 235ms
2
+ Resolved 307 packages in 317ms
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.90
3
+ Version: 0.4.92
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.90",
3
+ "version": "0.4.92",
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.90"
3
+ version = "0.4.92"
4
4
  description = "Classifyre CLI — scan and classify unstructured data sources"
5
5
  readme = "README.md"
6
6
  requires-python = ">=3.12"
@@ -148,7 +148,7 @@ class FileEvaluationRunner:
148
148
  file_mime,
149
149
  )
150
150
 
151
- # Files that embed whole other files (parquet file columns, office media)
151
+ # Files that embed whole other files (parquet/Arrow file columns, office media)
152
152
  # get each embedded file run through the binary detectors directly, with
153
153
  # findings tagged by the embedded location so the UI can group them.
154
154
  embedded_files = has_embedded_files(mime_type)
@@ -58,6 +58,7 @@ class AssetType(StrEnum):
58
58
  DROPBOX = 'DROPBOX'
59
59
  HUGGING_FACE = 'HUGGING_FACE'
60
60
  SANDBOX = 'SANDBOX'
61
+ GIT = 'GIT'
61
62
 
62
63
 
63
64
  class DetectorType(StrEnum):
@@ -389,6 +390,7 @@ class Type(StrEnum):
389
390
  DROPBOX = 'DROPBOX'
390
391
  HUGGING_FACE = 'HUGGING_FACE'
391
392
  SANDBOX = 'SANDBOX'
393
+ GIT = 'GIT'
392
394
 
393
395
 
394
396
  class YouTubeRequired(BaseModel):
@@ -3470,6 +3472,7 @@ class Type22(StrEnum):
3470
3472
  DROPBOX = 'DROPBOX'
3471
3473
  HUGGING_FACE = 'HUGGING_FACE'
3472
3474
  SANDBOX = 'SANDBOX'
3475
+ GIT = 'GIT'
3473
3476
 
3474
3477
 
3475
3478
  class ConfluenceInput(CoreInput):
@@ -5051,6 +5054,230 @@ class SlackOptionalAttachments(BaseModel):
5051
5054
  )
5052
5055
 
5053
5056
 
5057
+ class GitAuthMethod(StrEnum):
5058
+ """
5059
+ How the scan authenticates to the Git server. none scans a public repository over http(s). token uses a personal access / deploy token (GitHub, GitLab, Bitbucket, Azure DevOps). basic uses a username and password. ssh_key uses an SSH private key with an ssh:// or git@host:org/repo.git URL. client_certificate uses mutual TLS against an enterprise Git server. Credentials are never written to the runner's git configuration: they are materialised into a private, per-run directory that is deleted when the scan ends.
5060
+ """
5061
+
5062
+ none = 'none'
5063
+ token = 'token'
5064
+ basic = 'basic'
5065
+ ssh_key = 'ssh_key'
5066
+ client_certificate = 'client_certificate'
5067
+
5068
+
5069
+ class GitCloneStrategy(StrEnum):
5070
+ """
5071
+ How much of the repository is transferred up front. blob_limit (recommended) fetches the file tree plus the contents of every file at or below the memory threshold in one pack, and leaves larger files to be fetched individually only if the scan reaches them. blobless fetches the file tree only, so every file is catalogued from Git metadata and downloaded one at a time as it is scanned — the cheapest option for a very large repository where only a slice is sampled, at the cost of one request per file and unknown file sizes until a file is read. full transfers every file in the commit up front.
5072
+ """
5073
+
5074
+ blob_limit = 'blob_limit'
5075
+ blobless = 'blobless'
5076
+ full = 'full'
5077
+
5078
+
5079
+ class GitRequired(BaseModel):
5080
+ model_config = ConfigDict(
5081
+ extra='forbid',
5082
+ )
5083
+ repository_url: str = Field(
5084
+ ...,
5085
+ description='Repository to scan. Works with GitHub, GitLab, Bitbucket, Azure DevOps, Gitea and any other Git server. Accepts https://host/org/repo.git, ssh://git@host/org/repo.git, or the scp-style git@host:org/repo.git.',
5086
+ )
5087
+
5088
+
5089
+ class GitMasked(BaseModel):
5090
+ """
5091
+ Secrets for the selected authentication method. Leave the whole block empty for a public repository. Every value is encrypted at rest and only ever materialised into a private, per-run directory that is deleted when the scan ends.
5092
+ """
5093
+
5094
+ model_config = ConfigDict(
5095
+ extra='forbid',
5096
+ )
5097
+ username: str | None = Field(
5098
+ None,
5099
+ description='Username for basic authentication, or the token user for token authentication. Optional for tokens: the correct user for the detected host is used when this is empty (x-access-token for GitHub, oauth2 for GitLab, x-token-auth for Bitbucket).',
5100
+ )
5101
+ password: str | None = Field(None, description='Password for basic authentication.')
5102
+ token: str | None = Field(
5103
+ None,
5104
+ description='Personal access token, deploy token or app installation token with read access to the repository.',
5105
+ )
5106
+ ssh_private_key: str | None = Field(
5107
+ None,
5108
+ description='OpenSSH private key in PEM form, including the BEGIN and END lines. Used with an ssh:// or git@host:org/repo.git URL.',
5109
+ )
5110
+ ssh_private_key_passphrase: str | None = Field(
5111
+ None, description='Passphrase protecting the SSH private key, when it has one.'
5112
+ )
5113
+ client_certificate_pem: str | None = Field(
5114
+ None, description='PEM client certificate for mutual-TLS authentication.'
5115
+ )
5116
+ client_key_pem: str | None = Field(
5117
+ None, description='PEM private key matching the client certificate.'
5118
+ )
5119
+ ca_certificate_pem: str | None = Field(
5120
+ None,
5121
+ description='PEM certificate authority bundle used to verify the server, for an internal Git server with a private CA. Applies to any http(s) authentication method.',
5122
+ )
5123
+
5124
+
5125
+ class GitOptionalAuth(BaseModel):
5126
+ """
5127
+ Which credentials to use and how the server is verified.
5128
+ """
5129
+
5130
+ model_config = ConfigDict(
5131
+ extra='forbid',
5132
+ )
5133
+ auth_method: GitAuthMethod | None = 'none'
5134
+ ssh_known_hosts: str | None = Field(
5135
+ None,
5136
+ description='known_hosts entries for the Git server, one per line (the output of ssh-keyscan host). Required for SSH unless host key checking is turned off.',
5137
+ )
5138
+ ssh_strict_host_key_checking: bool | None = Field(
5139
+ True,
5140
+ description='Refuse to connect over SSH to a host that is not in ssh_known_hosts. Leave on unless you are connecting to a server whose host key you cannot pin.',
5141
+ )
5142
+ verify_ssl: bool | None = Field(
5143
+ True,
5144
+ description="Verify the server's TLS certificate on http(s) remotes. Turn off only for an internal server with a self-signed certificate; prefer ca_certificate_pem.",
5145
+ )
5146
+
5147
+
5148
+ class GitOptionalScope(BaseModel):
5149
+ """
5150
+ Which branch is read and which files inside it become assets. One branch is scanned per source; add a second source to scan a second branch.
5151
+ """
5152
+
5153
+ model_config = ConfigDict(
5154
+ extra='forbid',
5155
+ )
5156
+ branch: str | None = Field(
5157
+ None,
5158
+ description="Branch or tag to scan, for example main or release/2026-01. Defaults to the repository's default branch.",
5159
+ )
5160
+ include_paths: list[str] | None = Field(
5161
+ None,
5162
+ description='Folders or glob patterns to scan, for example docs, src/config or **/*.sql. A file is kept when it matches at least one entry. Leave empty to scan the whole repository.',
5163
+ )
5164
+ exclude_paths: list[str] | None = Field(
5165
+ None,
5166
+ description='Folders or glob patterns to skip, for example node_modules, vendor or **/fixtures/*. Applied after include_paths, so an excluded folder inside an included one is still skipped.',
5167
+ )
5168
+ include_extensions: list[str] | None = Field(
5169
+ None,
5170
+ description='Optional extension allowlist (for example, .py, .sql, .env, .md)',
5171
+ )
5172
+ exclude_extensions: list[str] | None = Field(
5173
+ None,
5174
+ description='Optional extension denylist (for example, .png, .lock, .min.js)',
5175
+ )
5176
+ include_last_commit: bool | None = Field(
5177
+ False,
5178
+ description="Record each file's own last-commit date, which is what LATEST and AUTOMATIC sampling order by. Needs the branch's commit history, so it makes the initial transfer larger. When off, every file inherits the date of the scanned commit.",
5179
+ )
5180
+ include_empty_objects: bool | None = Field(
5181
+ False, description='Include zero-byte files in extraction results'
5182
+ )
5183
+ include_object_metadata: bool | None = Field(
5184
+ True,
5185
+ description='Attach Git metadata (blob object id, size, commit) to asset checksums. The blob id is a content hash, so leaving this on lets an unchanged file be skipped on the next run without re-reading it.',
5186
+ )
5187
+ include_content_preview: bool | None = Field(
5188
+ True,
5189
+ description='Read file contents to infer type and extract detector-ready text. Turn off for a metadata-only inventory of the repository.',
5190
+ )
5191
+
5192
+
5193
+ class GitOptionalConnection(BaseModel):
5194
+ """
5195
+ How the repository is transferred and how much of one file may be held at once. Every run clones into its own empty directory and deletes it afterwards — nothing is shared or cached between runs or between sources.
5196
+ """
5197
+
5198
+ model_config = ConfigDict(
5199
+ extra='forbid',
5200
+ )
5201
+ clone_strategy: GitCloneStrategy | None = 'blob_limit'
5202
+ depth: int | None = Field(
5203
+ 1,
5204
+ description='How many commits of history to fetch. 1 (default) fetches only the commit being scanned. 0 fetches the full history, which is what per-file commit dates need.',
5205
+ ge=0,
5206
+ le=1000,
5207
+ )
5208
+ clone_timeout_seconds: float | None = Field(
5209
+ 1800, description='Time limit for the initial clone.', ge=30.0, le=86400.0
5210
+ )
5211
+ command_timeout_seconds: float | None = Field(
5212
+ 300,
5213
+ description='Time limit for each subsequent Git command, including fetching one file.',
5214
+ ge=5.0,
5215
+ le=3600.0,
5216
+ )
5217
+ max_object_bytes: int | None = Field(
5218
+ 26214400,
5219
+ description='Maximum bytes of one file held in memory. Larger files are streamed to a temporary file, so this bounds memory rather than the size of file that can be scanned. Also the threshold used by the blob_limit clone strategy. See max_file_bytes to refuse large files outright.',
5220
+ ge=1024,
5221
+ )
5222
+ max_file_bytes: int | None = Field(
5223
+ None,
5224
+ description='Refuse any file larger than this many bytes. 0 or unset means no limit: a file above max_object_bytes is spooled to disk rather than held in memory, so file size is bounded by free disk, not by RAM.',
5225
+ ge=0,
5226
+ )
5227
+ max_archive_members: int | None = Field(
5228
+ 200,
5229
+ description='Maximum member files expanded from one archive into child assets. Bounds fan-out, and is the guard against a zip bomb.',
5230
+ ge=1,
5231
+ le=10000,
5232
+ )
5233
+ max_archive_member_bytes: int | None = Field(
5234
+ 10485760,
5235
+ description='Maximum uncompressed bytes read from a single archive member',
5236
+ ge=1024,
5237
+ )
5238
+ max_archive_total_bytes: int | None = Field(
5239
+ 104857600,
5240
+ description='Maximum uncompressed bytes read across all members of one archive. The decompression-ratio ceiling: a zip bomb hits this before it hits memory.',
5241
+ ge=1024,
5242
+ )
5243
+ max_embedded_files: int | None = Field(
5244
+ 200,
5245
+ description='Maximum embedded files (parquet image/audio columns, office media) expanded from one container into child assets per run',
5246
+ ge=1,
5247
+ le=10000,
5248
+ )
5249
+
5250
+
5251
+ class GitOptional(BaseModel):
5252
+ model_config = ConfigDict(
5253
+ extra='forbid',
5254
+ )
5255
+ auth: GitOptionalAuth | None = None
5256
+ scope: GitOptionalScope | None = None
5257
+ connection: GitOptionalConnection | None = None
5258
+
5259
+
5260
+ class GitInput(CoreInput):
5261
+ type: Literal['GIT'] = Field(..., description='Type of the asset or source')
5262
+ required: GitRequired
5263
+ masked: GitMasked | None = None
5264
+ optional: GitOptional | None = None
5265
+ detectors: list[Detector] | None = Field(
5266
+ None, description='Detectors to run on ingested content'
5267
+ )
5268
+ custom_detectors: list[CustomDetectorSelection] | None = Field(
5269
+ None,
5270
+ description='Reusable custom detector IDs selected from the custom detector catalog.',
5271
+ )
5272
+ sampling: SamplingConfig
5273
+ scan_cache: ScanCacheConfig | None = None
5274
+ resources: ResourceOverrides | None = None
5275
+ cleanup_removed_detector_findings: bool | None = Field(
5276
+ True,
5277
+ description='When enabled (default), findings produced by detectors that are no longer configured on this source (removed or disabled) are automatically resolved at the start of the next run, keeping the findings list in step with the current detector set.',
5278
+ )
5279
+
5280
+
5054
5281
  class YouTubeInput(CoreInput):
5055
5282
  type: Literal['YOUTUBE'] = Field(..., description='Type of the asset or source')
5056
5283
  required: YouTubeRequired
@@ -5224,6 +5451,7 @@ class SourceInput(
5224
5451
  | GoogleWorkspaceInput
5225
5452
  | DropboxInput
5226
5453
  | HuggingFaceInput
5454
+ | GitInput
5227
5455
  ]
5228
5456
  ):
5229
5457
  root: (
@@ -5263,6 +5491,7 @@ class SourceInput(
5263
5491
  | GoogleWorkspaceInput
5264
5492
  | DropboxInput
5265
5493
  | HuggingFaceInput
5494
+ | GitInput
5266
5495
  ) = Field(
5267
5496
  ...,
5268
5497
  description='Merged configuration schema with all source types and common definitions',
@@ -11,7 +11,7 @@ from urllib.parse import urljoin, urlsplit, urlunsplit
11
11
 
12
12
  import requests
13
13
 
14
- from ..utils.file_parser import normalize_mime_type
14
+ from ..utils.file_parser import ARROW_MIME_TYPES, normalize_mime_type
15
15
  from ..utils.hashing import normalize_http_url
16
16
 
17
17
  logger = logging.getLogger(__name__)
@@ -25,6 +25,7 @@ TABULAR_MIME_TYPES = {
25
25
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
26
26
  "application/parquet",
27
27
  "application/vnd.apache.parquet",
28
+ *ARROW_MIME_TYPES,
28
29
  }
29
30
 
30
31
  TABULAR_FILE_EXTENSIONS = {
@@ -33,6 +34,10 @@ TABULAR_FILE_EXTENSIONS = {
33
34
  ".xls",
34
35
  ".xlsx",
35
36
  ".parquet",
37
+ ".arrow",
38
+ ".arrows",
39
+ ".feather",
40
+ ".ipc",
36
41
  }
37
42
 
38
43
 
@@ -399,7 +399,7 @@ class BaseSource(ABC):
399
399
  unchanged.
400
400
 
401
401
  ``file_bytes`` may be a seekable binary handle instead of bytes (Parquet
402
- only). The window then bounds what is *transferred*, not just what is
402
+ and Arrow). The window then bounds what is *transferred*, not just what is
403
403
  decoded: a source that can serve byte ranges reads the footer and the one
404
404
  row group this run needs out of an object it never downloads whole.
405
405
  """
@@ -432,11 +432,11 @@ class BaseSource(ABC):
432
432
  def _payload_rows_per_page_unit(mime_type: str, batch_size: int) -> int:
433
433
  """How many payload rows one page from ``iter_file_pages`` carries.
434
434
 
435
- Record-shaped readers (Parquet, CSV/TSV) emit a page per row. Spreadsheets
436
- reach the detectors as extracted text, which is paged in blocks of
437
- ``batch_size`` lines — one line per sheet row.
435
+ Record-shaped readers (Parquet, Arrow IPC, CSV/TSV) emit a page per row.
436
+ Spreadsheets reach the detectors as extracted text, which is paged in
437
+ blocks of ``batch_size`` lines — one line per sheet row.
438
438
  """
439
- from ..utils.file_parser import normalize_mime_type
439
+ from ..utils.file_parser import ARROW_MIME_TYPES, normalize_mime_type
440
440
 
441
441
  normalized = normalize_mime_type(mime_type)
442
442
  record_shaped = {
@@ -444,6 +444,7 @@ class BaseSource(ABC):
444
444
  "application/vnd.apache.parquet",
445
445
  "text/csv",
446
446
  "text/tab-separated-values",
447
+ *ARROW_MIME_TYPES,
447
448
  }
448
449
  return 1 if normalized in record_shaped else max(1, batch_size)
449
450
 
@@ -71,6 +71,10 @@ FILE_EXTENSION_HINTS: dict[str, OutputAssetType] = {
71
71
  ".tar": OutputAssetType.BINARY,
72
72
  ".gz": OutputAssetType.BINARY,
73
73
  ".parquet": OutputAssetType.TABLE,
74
+ ".arrow": OutputAssetType.TABLE,
75
+ ".arrows": OutputAssetType.TABLE,
76
+ ".feather": OutputAssetType.TABLE,
77
+ ".ipc": OutputAssetType.TABLE,
74
78
  ".json": OutputAssetType.TXT,
75
79
  ".xml": OutputAssetType.TXT,
76
80
  ".txt": OutputAssetType.TXT,
@@ -25,7 +25,11 @@ from ...models.generated_single_asset_scan_results import (
25
25
  )
26
26
  from ...utils.content_extraction import html_to_text
27
27
  from ...utils.file_metadata import extract_file_metadata
28
- from ...utils.file_parser import normalize_mime_type, resolve_mime_type
28
+ from ...utils.file_parser import (
29
+ ARROW_MIME_TYPES,
30
+ normalize_mime_type,
31
+ resolve_mime_type,
32
+ )
29
33
  from ...utils.hashing import hash_id
30
34
  from ..base import BaseSource
31
35
  from ..dependencies import require_module
@@ -39,6 +43,7 @@ _TABULAR_MIME_TYPES = {
39
43
  "application/vnd.openxmlformats-officedocument.spreadsheetml.sheet",
40
44
  "application/parquet",
41
45
  "application/vnd.apache.parquet",
46
+ *ARROW_MIME_TYPES,
42
47
  }
43
48
 
44
49
  # MIME types whose text can be extracted (by file_parser) and so should route
@@ -0,0 +1,3 @@
1
+ from .source import GitSource
2
+
3
+ __all__ = ["GitSource"]