sift-stack-py 0.16.1__tar.gz → 0.16.2__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 (622) hide show
  1. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/PKG-INFO +1 -1
  2. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/exports.py +16 -7
  3. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/rules.py +12 -2
  4. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/channels.py +3 -0
  5. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_channels.py +19 -0
  6. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_data_imports.py +153 -1
  7. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_calculated_channel.py +63 -0
  8. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_channel.py +95 -1
  9. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_rule.py +73 -0
  10. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/data_imports.py +42 -2
  11. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/calculated_channel.py +29 -5
  12. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/channel.py +46 -5
  13. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/rule.py +6 -1
  14. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_stack_py.egg-info/PKG-INFO +1 -1
  15. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/pyproject.toml +1 -1
  16. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/LICENSE +0 -0
  17. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/README.md +0 -0
  18. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/__init__.py +0 -0
  19. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotation_logs/__init__.py +0 -0
  20. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotation_logs/v1/__init__.py +0 -0
  21. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotation_logs/v1/annotation_logs_pb2.py +0 -0
  22. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotation_logs/v1/annotation_logs_pb2.pyi +0 -0
  23. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotation_logs/v1/annotation_logs_pb2_grpc.py +0 -0
  24. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotation_logs/v1/annotation_logs_pb2_grpc.pyi +0 -0
  25. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotations/__init__.py +0 -0
  26. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotations/v1/__init__.py +0 -0
  27. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotations/v1/annotations_pb2.py +0 -0
  28. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotations/v1/annotations_pb2.pyi +0 -0
  29. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotations/v1/annotations_pb2_grpc.py +0 -0
  30. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/annotations/v1/annotations_pb2_grpc.pyi +0 -0
  31. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/api_keys/__init__.py +0 -0
  32. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/api_keys/v2/__init__.py +0 -0
  33. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/api_keys/v2/api_keys_pb2.py +0 -0
  34. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/api_keys/v2/api_keys_pb2.pyi +0 -0
  35. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/api_keys/v2/api_keys_pb2_grpc.py +0 -0
  36. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/api_keys/v2/api_keys_pb2_grpc.pyi +0 -0
  37. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/assets/__init__.py +0 -0
  38. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/assets/v1/__init__.py +0 -0
  39. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/assets/v1/assets_pb2.py +0 -0
  40. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/assets/v1/assets_pb2.pyi +0 -0
  41. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/assets/v1/assets_pb2_grpc.py +0 -0
  42. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/assets/v1/assets_pb2_grpc.pyi +0 -0
  43. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/__init__.py +0 -0
  44. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v1/__init__.py +0 -0
  45. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v1/calculated_channels_pb2.py +0 -0
  46. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v1/calculated_channels_pb2.pyi +0 -0
  47. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v1/calculated_channels_pb2_grpc.py +0 -0
  48. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v1/calculated_channels_pb2_grpc.pyi +0 -0
  49. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v2/__init__.py +0 -0
  50. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v2/calculated_channels_pb2.py +0 -0
  51. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v2/calculated_channels_pb2.pyi +0 -0
  52. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v2/calculated_channels_pb2_grpc.py +0 -0
  53. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/calculated_channels/v2/calculated_channels_pb2_grpc.pyi +0 -0
  54. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/campaigns/__init__.py +0 -0
  55. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/campaigns/v1/__init__.py +0 -0
  56. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/campaigns/v1/campaigns_pb2.py +0 -0
  57. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/campaigns/v1/campaigns_pb2.pyi +0 -0
  58. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/campaigns/v1/campaigns_pb2_grpc.py +0 -0
  59. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/campaigns/v1/campaigns_pb2_grpc.pyi +0 -0
  60. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/__init__.py +0 -0
  61. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v1/__init__.py +0 -0
  62. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v1/channel_schemas_pb2.py +0 -0
  63. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v1/channel_schemas_pb2.pyi +0 -0
  64. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v1/channel_schemas_pb2_grpc.py +0 -0
  65. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v1/channel_schemas_pb2_grpc.pyi +0 -0
  66. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v2/__init__.py +0 -0
  67. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v2/channel_schemas_pb2.py +0 -0
  68. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v2/channel_schemas_pb2.pyi +0 -0
  69. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v2/channel_schemas_pb2_grpc.py +0 -0
  70. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channel_schemas/v2/channel_schemas_pb2_grpc.pyi +0 -0
  71. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/__init__.py +0 -0
  72. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v2/__init__.py +0 -0
  73. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v2/channels_pb2.py +0 -0
  74. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v2/channels_pb2.pyi +0 -0
  75. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v2/channels_pb2_grpc.py +0 -0
  76. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v2/channels_pb2_grpc.pyi +0 -0
  77. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v3/__init__.py +0 -0
  78. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v3/channels_pb2.py +0 -0
  79. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v3/channels_pb2.pyi +0 -0
  80. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v3/channels_pb2_grpc.py +0 -0
  81. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/channels/v3/channels_pb2_grpc.pyi +0 -0
  82. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/comment/__init__.py +0 -0
  83. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/comment/v1/__init__.py +0 -0
  84. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/comment/v1/comment_pb2.py +0 -0
  85. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/comment/v1/comment_pb2.pyi +0 -0
  86. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/comment/v1/comment_pb2_grpc.py +0 -0
  87. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/comment/v1/comment_pb2_grpc.pyi +0 -0
  88. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/__init__.py +0 -0
  89. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/__init__.py +0 -0
  90. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/__init__.py +0 -0
  91. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/calculated_channels_pb2.py +0 -0
  92. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/calculated_channels_pb2.pyi +0 -0
  93. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/calculated_channels_pb2_grpc.py +0 -0
  94. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/calculated_channels_pb2_grpc.pyi +0 -0
  95. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_bit_field_element_pb2.py +0 -0
  96. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_bit_field_element_pb2.pyi +0 -0
  97. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_bit_field_element_pb2_grpc.py +0 -0
  98. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_bit_field_element_pb2_grpc.pyi +0 -0
  99. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_config_pb2.py +0 -0
  100. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_config_pb2.pyi +0 -0
  101. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_config_pb2_grpc.py +0 -0
  102. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_config_pb2_grpc.pyi +0 -0
  103. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_data_type_pb2.py +0 -0
  104. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_data_type_pb2.pyi +0 -0
  105. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_data_type_pb2_grpc.py +0 -0
  106. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_data_type_pb2_grpc.pyi +0 -0
  107. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_enum_type_pb2.py +0 -0
  108. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_enum_type_pb2.pyi +0 -0
  109. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_enum_type_pb2_grpc.py +0 -0
  110. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/channel_enum_type_pb2_grpc.pyi +0 -0
  111. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/organization_pb2.py +0 -0
  112. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/organization_pb2.pyi +0 -0
  113. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/organization_pb2_grpc.py +0 -0
  114. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/organization_pb2_grpc.pyi +0 -0
  115. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_identifier_pb2.py +0 -0
  116. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_identifier_pb2.pyi +0 -0
  117. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_identifier_pb2_grpc.py +0 -0
  118. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_identifier_pb2_grpc.pyi +0 -0
  119. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_ref_pb2.py +0 -0
  120. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_ref_pb2.pyi +0 -0
  121. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_ref_pb2_grpc.py +0 -0
  122. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/resource_ref_pb2_grpc.pyi +0 -0
  123. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_defined_functions_pb2.py +0 -0
  124. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_defined_functions_pb2.pyi +0 -0
  125. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_defined_functions_pb2_grpc.py +0 -0
  126. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_defined_functions_pb2_grpc.pyi +0 -0
  127. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_pb2.py +0 -0
  128. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_pb2.pyi +0 -0
  129. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_pb2_grpc.py +0 -0
  130. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/type/v1/user_pb2_grpc.pyi +0 -0
  131. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/__init__.py +0 -0
  132. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/action_type_pb2.py +0 -0
  133. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/action_type_pb2.pyi +0 -0
  134. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/action_type_pb2_grpc.py +0 -0
  135. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/action_type_pb2_grpc.pyi +0 -0
  136. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/filter_field_pb2.py +0 -0
  137. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/filter_field_pb2.pyi +0 -0
  138. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/filter_field_pb2_grpc.py +0 -0
  139. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/filter_field_pb2_grpc.pyi +0 -0
  140. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/resource_type_pb2.py +0 -0
  141. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/resource_type_pb2.pyi +0 -0
  142. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/resource_type_pb2_grpc.py +0 -0
  143. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/common/v1/resource_type_pb2_grpc.pyi +0 -0
  144. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/__init__.py +0 -0
  145. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v1/__init__.py +0 -0
  146. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v1/data_pb2.py +0 -0
  147. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v1/data_pb2.pyi +0 -0
  148. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v1/data_pb2_grpc.py +0 -0
  149. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v1/data_pb2_grpc.pyi +0 -0
  150. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v2/__init__.py +0 -0
  151. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v2/data_pb2.py +0 -0
  152. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v2/data_pb2.pyi +0 -0
  153. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v2/data_pb2_grpc.py +0 -0
  154. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data/v2/data_pb2_grpc.pyi +0 -0
  155. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data_imports/__init__.py +0 -0
  156. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data_imports/v2/__init__.py +0 -0
  157. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data_imports/v2/data_imports_pb2.py +0 -0
  158. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data_imports/v2/data_imports_pb2.pyi +0 -0
  159. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data_imports/v2/data_imports_pb2_grpc.py +0 -0
  160. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/data_imports/v2/data_imports_pb2_grpc.pyi +0 -0
  161. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/dlq_errors/__init__.py +0 -0
  162. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/dlq_errors/v2/__init__.py +0 -0
  163. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/dlq_errors/v2/dlq_errors_pb2.py +0 -0
  164. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/dlq_errors/v2/dlq_errors_pb2.pyi +0 -0
  165. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/dlq_errors/v2/dlq_errors_pb2_grpc.py +0 -0
  166. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/dlq_errors/v2/dlq_errors_pb2_grpc.pyi +0 -0
  167. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/exports/__init__.py +0 -0
  168. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/exports/v1/__init__.py +0 -0
  169. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/exports/v1/exports_pb2.py +0 -0
  170. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/exports/v1/exports_pb2.pyi +0 -0
  171. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/exports/v1/exports_pb2_grpc.py +0 -0
  172. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/exports/v1/exports_pb2_grpc.pyi +0 -0
  173. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/external_sync/__init__.py +0 -0
  174. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/external_sync/v1/__init__.py +0 -0
  175. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/external_sync/v1/external_sync_pb2.py +0 -0
  176. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/external_sync/v1/external_sync_pb2.pyi +0 -0
  177. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/external_sync/v1/external_sync_pb2_grpc.py +0 -0
  178. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/external_sync/v1/external_sync_pb2_grpc.pyi +0 -0
  179. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingest/__init__.py +0 -0
  180. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingest/v1/__init__.py +0 -0
  181. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingest/v1/ingest_pb2.py +0 -0
  182. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingest/v1/ingest_pb2.pyi +0 -0
  183. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingest/v1/ingest_pb2_grpc.py +0 -0
  184. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingest/v1/ingest_pb2_grpc.pyi +0 -0
  185. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/__init__.py +0 -0
  186. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v1/__init__.py +0 -0
  187. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v1/ingestion_configs_pb2.py +0 -0
  188. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v1/ingestion_configs_pb2.pyi +0 -0
  189. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v1/ingestion_configs_pb2_grpc.py +0 -0
  190. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v1/ingestion_configs_pb2_grpc.pyi +0 -0
  191. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v2/__init__.py +0 -0
  192. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v2/ingestion_configs_pb2.py +0 -0
  193. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v2/ingestion_configs_pb2.pyi +0 -0
  194. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v2/ingestion_configs_pb2_grpc.py +0 -0
  195. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ingestion_configs/v2/ingestion_configs_pb2_grpc.pyi +0 -0
  196. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/jobs/__init__.py +0 -0
  197. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/jobs/v1/__init__.py +0 -0
  198. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/jobs/v1/jobs_pb2.py +0 -0
  199. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/jobs/v1/jobs_pb2.pyi +0 -0
  200. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/jobs/v1/jobs_pb2_grpc.py +0 -0
  201. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/jobs/v1/jobs_pb2_grpc.pyi +0 -0
  202. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/me/__init__.py +0 -0
  203. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/me/v2/__init__.py +0 -0
  204. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/me/v2/me_pb2.py +0 -0
  205. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/me/v2/me_pb2.pyi +0 -0
  206. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/me/v2/me_pb2_grpc.py +0 -0
  207. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/me/v2/me_pb2_grpc.pyi +0 -0
  208. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/metadata/__init__.py +0 -0
  209. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/metadata/v1/__init__.py +0 -0
  210. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/metadata/v1/metadata_pb2.py +0 -0
  211. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/metadata/v1/metadata_pb2.pyi +0 -0
  212. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/metadata/v1/metadata_pb2_grpc.py +0 -0
  213. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/metadata/v1/metadata_pb2_grpc.pyi +0 -0
  214. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/notifications/__init__.py +0 -0
  215. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/notifications/v1/__init__.py +0 -0
  216. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/notifications/v1/notifications_pb2.py +0 -0
  217. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/notifications/v1/notifications_pb2.pyi +0 -0
  218. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/notifications/v1/notifications_pb2_grpc.py +0 -0
  219. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/notifications/v1/notifications_pb2_grpc.pyi +0 -0
  220. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/panel_configurations/__init__.py +0 -0
  221. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/panel_configurations/v1/__init__.py +0 -0
  222. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/panel_configurations/v1/panel_configuration_pb2.py +0 -0
  223. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/panel_configurations/v1/panel_configuration_pb2.pyi +0 -0
  224. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/panel_configurations/v1/panel_configuration_pb2_grpc.py +0 -0
  225. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/panel_configurations/v1/panel_configuration_pb2_grpc.pyi +0 -0
  226. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ping/__init__.py +0 -0
  227. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ping/v1/__init__.py +0 -0
  228. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ping/v1/ping_pb2.py +0 -0
  229. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ping/v1/ping_pb2.pyi +0 -0
  230. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ping/v1/ping_pb2_grpc.py +0 -0
  231. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/ping/v1/ping_pb2_grpc.pyi +0 -0
  232. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/__init__.py +0 -0
  233. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/__init__.py +0 -0
  234. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/channel_parsing_options_pb2.py +0 -0
  235. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/channel_parsing_options_pb2.pyi +0 -0
  236. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/channel_parsing_options_pb2_grpc.py +0 -0
  237. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/channel_parsing_options_pb2_grpc.pyi +0 -0
  238. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/protobuf_descriptors_pb2.py +0 -0
  239. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/protobuf_descriptors_pb2.pyi +0 -0
  240. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/protobuf_descriptors_pb2_grpc.py +0 -0
  241. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/protobuf_descriptors/v2/protobuf_descriptors_pb2_grpc.pyi +0 -0
  242. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/py.typed +0 -0
  243. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/remote_files/__init__.py +0 -0
  244. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/remote_files/v1/__init__.py +0 -0
  245. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/remote_files/v1/remote_files_pb2.py +0 -0
  246. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/remote_files/v1/remote_files_pb2.pyi +0 -0
  247. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/remote_files/v1/remote_files_pb2_grpc.py +0 -0
  248. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/remote_files/v1/remote_files_pb2_grpc.pyi +0 -0
  249. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/report_templates/__init__.py +0 -0
  250. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/report_templates/v1/__init__.py +0 -0
  251. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/report_templates/v1/report_templates_pb2.py +0 -0
  252. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/report_templates/v1/report_templates_pb2.pyi +0 -0
  253. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/report_templates/v1/report_templates_pb2_grpc.py +0 -0
  254. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/report_templates/v1/report_templates_pb2_grpc.pyi +0 -0
  255. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/reports/__init__.py +0 -0
  256. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/reports/v1/__init__.py +0 -0
  257. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/reports/v1/reports_pb2.py +0 -0
  258. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/reports/v1/reports_pb2.pyi +0 -0
  259. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/reports/v1/reports_pb2_grpc.py +0 -0
  260. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/reports/v1/reports_pb2_grpc.pyi +0 -0
  261. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/roles/__init__.py +0 -0
  262. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/roles/v2/__init__.py +0 -0
  263. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/roles/v2/roles_pb2.py +0 -0
  264. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/roles/v2/roles_pb2.pyi +0 -0
  265. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/roles/v2/roles_pb2_grpc.py +0 -0
  266. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/roles/v2/roles_pb2_grpc.pyi +0 -0
  267. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rule_evaluation/__init__.py +0 -0
  268. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rule_evaluation/v1/__init__.py +0 -0
  269. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rule_evaluation/v1/rule_evaluation_pb2.py +0 -0
  270. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rule_evaluation/v1/rule_evaluation_pb2.pyi +0 -0
  271. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rule_evaluation/v1/rule_evaluation_pb2_grpc.py +0 -0
  272. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rule_evaluation/v1/rule_evaluation_pb2_grpc.pyi +0 -0
  273. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rules/__init__.py +0 -0
  274. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rules/v1/__init__.py +0 -0
  275. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rules/v1/rules_pb2.py +0 -0
  276. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rules/v1/rules_pb2.pyi +0 -0
  277. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rules/v1/rules_pb2_grpc.py +0 -0
  278. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/rules/v1/rules_pb2_grpc.pyi +0 -0
  279. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/runs/__init__.py +0 -0
  280. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/runs/v2/__init__.py +0 -0
  281. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/runs/v2/runs_pb2.py +0 -0
  282. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/runs/v2/runs_pb2.pyi +0 -0
  283. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/runs/v2/runs_pb2_grpc.py +0 -0
  284. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/runs/v2/runs_pb2_grpc.pyi +0 -0
  285. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/saved_searches/__init__.py +0 -0
  286. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/saved_searches/v1/__init__.py +0 -0
  287. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/saved_searches/v1/saved_searches_pb2.py +0 -0
  288. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/saved_searches/v1/saved_searches_pb2.pyi +0 -0
  289. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/saved_searches/v1/saved_searches_pb2_grpc.py +0 -0
  290. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/saved_searches/v1/saved_searches_pb2_grpc.pyi +0 -0
  291. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/__init__.py +0 -0
  292. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v1/__init__.py +0 -0
  293. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v1/tags_pb2.py +0 -0
  294. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v1/tags_pb2.pyi +0 -0
  295. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v1/tags_pb2_grpc.py +0 -0
  296. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v1/tags_pb2_grpc.pyi +0 -0
  297. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v2/__init__.py +0 -0
  298. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v2/tags_pb2.py +0 -0
  299. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v2/tags_pb2.pyi +0 -0
  300. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v2/tags_pb2_grpc.py +0 -0
  301. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/tags/v2/tags_pb2_grpc.pyi +0 -0
  302. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/test_reports/__init__.py +0 -0
  303. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/test_reports/v1/__init__.py +0 -0
  304. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/test_reports/v1/test_reports_pb2.py +0 -0
  305. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/test_reports/v1/test_reports_pb2.pyi +0 -0
  306. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/test_reports/v1/test_reports_pb2_grpc.py +0 -0
  307. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/test_reports/v1/test_reports_pb2_grpc.pyi +0 -0
  308. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/unit/__init__.py +0 -0
  309. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/unit/v2/__init__.py +0 -0
  310. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/unit/v2/unit_pb2.py +0 -0
  311. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/unit/v2/unit_pb2.pyi +0 -0
  312. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/unit/v2/unit_pb2_grpc.py +0 -0
  313. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/unit/v2/unit_pb2_grpc.pyi +0 -0
  314. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_defined_functions/__init__.py +0 -0
  315. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_defined_functions/v1/__init__.py +0 -0
  316. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_defined_functions/v1/user_defined_functions_pb2.py +0 -0
  317. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_defined_functions/v1/user_defined_functions_pb2.pyi +0 -0
  318. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_defined_functions/v1/user_defined_functions_pb2_grpc.py +0 -0
  319. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_defined_functions/v1/user_defined_functions_pb2_grpc.pyi +0 -0
  320. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_groups/__init__.py +0 -0
  321. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_groups/v2/__init__.py +0 -0
  322. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_groups/v2/user_groups_pb2.py +0 -0
  323. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_groups/v2/user_groups_pb2.pyi +0 -0
  324. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_groups/v2/user_groups_pb2_grpc.py +0 -0
  325. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/user_groups/v2/user_groups_pb2_grpc.pyi +0 -0
  326. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/users/__init__.py +0 -0
  327. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/users/v2/__init__.py +0 -0
  328. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/users/v2/users_pb2.py +0 -0
  329. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/users/v2/users_pb2.pyi +0 -0
  330. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/users/v2/users_pb2_grpc.py +0 -0
  331. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/users/v2/users_pb2_grpc.pyi +0 -0
  332. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/__init__.py +0 -0
  333. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v1/__init__.py +0 -0
  334. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v1/views_pb2.py +0 -0
  335. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v1/views_pb2.pyi +0 -0
  336. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v1/views_pb2_grpc.py +0 -0
  337. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v1/views_pb2_grpc.pyi +0 -0
  338. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v2/__init__.py +0 -0
  339. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v2/views_pb2.py +0 -0
  340. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v2/views_pb2.pyi +0 -0
  341. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v2/views_pb2_grpc.py +0 -0
  342. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/views/v2/views_pb2_grpc.pyi +0 -0
  343. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/webhooks/__init__.py +0 -0
  344. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/webhooks/v1/__init__.py +0 -0
  345. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/webhooks/v1/webhooks_pb2.py +0 -0
  346. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/webhooks/v1/webhooks_pb2.pyi +0 -0
  347. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/webhooks/v1/webhooks_pb2_grpc.py +0 -0
  348. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift/webhooks/v1/webhooks_pb2_grpc.pyi +0 -0
  349. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/__init__.py +0 -0
  350. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/__init__.py +0 -0
  351. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/gen_pyi.py +0 -0
  352. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/__init__.py +0 -0
  353. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_async_interceptors/__init__.py +0 -0
  354. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_async_interceptors/base.py +0 -0
  355. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_async_interceptors/metadata.py +0 -0
  356. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_interceptors/__init__.py +0 -0
  357. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_interceptors/base.py +0 -0
  358. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_interceptors/context.py +0 -0
  359. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_interceptors/metadata.py +0 -0
  360. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/_retry.py +0 -0
  361. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/keepalive.py +0 -0
  362. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/server_interceptors/__init__.py +0 -0
  363. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/server_interceptors/server_interceptor.py +0 -0
  364. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/transport.py +0 -0
  365. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/grpc_transport/transport_test.py +0 -0
  366. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/__init__.py +0 -0
  367. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/_test_results_log.py +0 -0
  368. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/assets.py +0 -0
  369. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/base.py +0 -0
  370. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/calculated_channels.py +0 -0
  371. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/channels.py +0 -0
  372. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/data.py +0 -0
  373. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/data_imports.py +0 -0
  374. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/ingestion.py +0 -0
  375. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/jobs.py +0 -0
  376. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/ping.py +0 -0
  377. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/remote_files.py +0 -0
  378. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/reports.py +0 -0
  379. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/runs.py +0 -0
  380. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/tags.py +0 -0
  381. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/test_results.py +0 -0
  382. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/low_level_wrappers/upload.py +0 -0
  383. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/rest.py +0 -0
  384. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/sync_wrapper.py +0 -0
  385. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/time.py +0 -0
  386. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/__init__.py +0 -0
  387. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/executor.py +0 -0
  388. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/file.py +0 -0
  389. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/hdf5.py +0 -0
  390. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/numpy_types.py +0 -0
  391. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/tdms.py +0 -0
  392. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/timestamp.py +0 -0
  393. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_internal/util/util.py +0 -0
  394. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/__init__.py +0 -0
  395. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/__init__.py +0 -0
  396. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/low_level_wrappers/__init__.py +0 -0
  397. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/low_level_wrappers/test_base.py +0 -0
  398. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/low_level_wrappers/test_ingestion.py +0 -0
  399. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/low_level_wrappers/test_upload.py +0 -0
  400. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_gen_pyi.py +0 -0
  401. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_hdf5.py +0 -0
  402. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_stub_module/__init__.py +0 -0
  403. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_stub_module/test_py.py +0 -0
  404. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_sync_wrapper.py +0 -0
  405. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_tdms.py +0 -0
  406. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/_internal/test_transport.py +0 -0
  407. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/conftest.py +0 -0
  408. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/__init__.py +0 -0
  409. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_assets.py +0 -0
  410. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_calculated_channels.py +0 -0
  411. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_channels.py +0 -0
  412. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_exports.py +0 -0
  413. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_file_attachments.py +0 -0
  414. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_jobs.py +0 -0
  415. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_ping.py +0 -0
  416. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_reports.py +0 -0
  417. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_rules.py +0 -0
  418. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_runs.py +0 -0
  419. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_tags.py +0 -0
  420. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/resources/test_test_results.py +0 -0
  421. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/__init__.py +0 -0
  422. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_asset.py +0 -0
  423. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_base.py +0 -0
  424. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_ingestion.py +0 -0
  425. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_job.py +0 -0
  426. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_report.py +0 -0
  427. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_results.py +0 -0
  428. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_run.py +0 -0
  429. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/sift_types/test_tag.py +0 -0
  430. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/test_client.py +0 -0
  431. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/util/__init__.py +0 -0
  432. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/util/conftest.py +0 -0
  433. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/util/test_cel_utils.py +0 -0
  434. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/_tests/util/test_test_results_utils.py +0 -0
  435. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/client.py +0 -0
  436. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/config.py +0 -0
  437. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/errors.py +0 -0
  438. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/py.typed +0 -0
  439. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/__init__.py +0 -0
  440. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/_base.py +0 -0
  441. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/assets.py +0 -0
  442. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/calculated_channels.py +0 -0
  443. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/channels.py +0 -0
  444. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/exports.py +0 -0
  445. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/file_attachments.py +0 -0
  446. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/ingestion.py +0 -0
  447. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/jobs.py +0 -0
  448. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/ping.py +0 -0
  449. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/py.typed +0 -0
  450. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/reports.py +0 -0
  451. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/rules.py +0 -0
  452. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/runs.py +0 -0
  453. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/sync_stubs/__init__.py +0 -0
  454. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/sync_stubs/__init__.pyi +0 -0
  455. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/sync_stubs/py.typed +0 -0
  456. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/tags.py +0 -0
  457. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/resources/test_results.py +0 -0
  458. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/scripts/__init__.py +0 -0
  459. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/scripts/import_test_result_log.py +0 -0
  460. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/__init__.py +0 -0
  461. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/_base.py +0 -0
  462. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/_mixins/__init__.py +0 -0
  463. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/_mixins/file_attachments.py +0 -0
  464. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/asset.py +0 -0
  465. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/data_import.py +0 -0
  466. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/export.py +0 -0
  467. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/file_attachment.py +0 -0
  468. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/ingestion.py +0 -0
  469. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/job.py +0 -0
  470. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/report.py +0 -0
  471. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/run.py +0 -0
  472. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/tag.py +0 -0
  473. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/sift_types/test_report.py +0 -0
  474. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/transport/__init__.py +0 -0
  475. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/transport/base_connection.py +0 -0
  476. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/transport/grpc_transport.py +0 -0
  477. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/transport/rest_transport.py +0 -0
  478. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/__init__.py +0 -0
  479. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/cel_utils.py +0 -0
  480. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/metadata.py +0 -0
  481. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/test_results/__init__.py +0 -0
  482. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/test_results/bounds.py +0 -0
  483. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/test_results/context_manager.py +0 -0
  484. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/test_results/pytest_util.py +0 -0
  485. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_client/util/util.py +0 -0
  486. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/__init__.py +0 -0
  487. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/__init__.py +0 -0
  488. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/cel.py +0 -0
  489. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/channel.py +0 -0
  490. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/convert/__init__.py +0 -0
  491. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/convert/json.py +0 -0
  492. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/convert/protobuf.py +0 -0
  493. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/convert/timestamp.py +0 -0
  494. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/metadata.py +0 -0
  495. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/metadata_test.py +0 -0
  496. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/test_util/__init__.py +0 -0
  497. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/test_util/channel.py +0 -0
  498. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/test_util/fn.py +0 -0
  499. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/test_util/server_interceptor.py +0 -0
  500. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/time.py +0 -0
  501. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_internal/user.py +0 -0
  502. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/_rest_test.py +0 -0
  503. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/asset/__init__.py +0 -0
  504. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/asset/_config_test.py +0 -0
  505. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/asset/_internal/shared.py +0 -0
  506. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/asset/_service_test.py +0 -0
  507. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/asset/config.py +0 -0
  508. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/asset/service.py +0 -0
  509. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/calculated_channels/__init__.py +0 -0
  510. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/calculated_channels/_service_test.py +0 -0
  511. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/calculated_channels/config.py +0 -0
  512. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/calculated_channels/service.py +0 -0
  513. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/__init__.py +0 -0
  514. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/_channel.py +0 -0
  515. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/_deserialize.py +0 -0
  516. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/_deserialize_test.py +0 -0
  517. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/_service_test.py +0 -0
  518. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/_validate.py +0 -0
  519. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/error.py +0 -0
  520. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/query.py +0 -0
  521. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data/service.py +0 -0
  522. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/__init__.py +0 -0
  523. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_config.py +0 -0
  524. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_config_test.py +0 -0
  525. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_csv_test.py +0 -0
  526. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_hdf5_test.py +0 -0
  527. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_parquet_test.py +0 -0
  528. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_ros_channel.py +0 -0
  529. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_rosbag_test.py +0 -0
  530. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_status_test.py +0 -0
  531. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_tdms_test.py +0 -0
  532. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_utils.py +0 -0
  533. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/_utils_test.py +0 -0
  534. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/ch10.py +0 -0
  535. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/config.py +0 -0
  536. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/csv.py +0 -0
  537. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/hdf5.py +0 -0
  538. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/parquet.py +0 -0
  539. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/parquet_complex_types.py +0 -0
  540. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/rosbags.py +0 -0
  541. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/status.py +0 -0
  542. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/tdms.py +0 -0
  543. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/tempfile.py +0 -0
  544. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/data_import/time_format.py +0 -0
  545. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/error.py +0 -0
  546. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/__init__.py +0 -0
  547. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/_internal/__init__.py +0 -0
  548. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/_internal/download.py +0 -0
  549. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/_internal/upload.py +0 -0
  550. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/_service_test.py +0 -0
  551. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/entity.py +0 -0
  552. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/metadata.py +0 -0
  553. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/file_attachment/service.py +0 -0
  554. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/__init__.py +0 -0
  555. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_async_interceptors/__init__.py +0 -0
  556. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_async_interceptors/base.py +0 -0
  557. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_async_interceptors/metadata.py +0 -0
  558. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_interceptors/__init__.py +0 -0
  559. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_interceptors/base.py +0 -0
  560. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_interceptors/context.py +0 -0
  561. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_interceptors/metadata.py +0 -0
  562. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/_retry.py +0 -0
  563. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/keepalive.py +0 -0
  564. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/transport.py +0 -0
  565. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/grpc/transport_test.py +0 -0
  566. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/__init__.py +0 -0
  567. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_internal/__init__.py +0 -0
  568. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_internal/channel.py +0 -0
  569. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_internal/error.py +0 -0
  570. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_internal/ingest.py +0 -0
  571. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_internal/ingest_test.py +0 -0
  572. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_internal/ingestion_config.py +0 -0
  573. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_internal/run.py +0 -0
  574. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/_service_test.py +0 -0
  575. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/buffer.py +0 -0
  576. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/channel.py +0 -0
  577. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/__init__.py +0 -0
  578. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/_telemetry_test.py +0 -0
  579. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/telemetry.py +0 -0
  580. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/yaml/__init__.py +0 -0
  581. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/yaml/error.py +0 -0
  582. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/yaml/load.py +0 -0
  583. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/yaml/spec.py +0 -0
  584. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/config/yaml/test_load.py +0 -0
  585. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/flow.py +0 -0
  586. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/manager.py +0 -0
  587. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/rule/__init__.py +0 -0
  588. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/rule/config.py +0 -0
  589. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/ingestion/service.py +0 -0
  590. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/py.typed +0 -0
  591. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/report/_report_test.py +0 -0
  592. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/report/service.py +0 -0
  593. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/report_templates/__init__.py +0 -0
  594. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/report_templates/_config_test.py +0 -0
  595. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/report_templates/_service_test.py +0 -0
  596. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/report_templates/config.py +0 -0
  597. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/report_templates/service.py +0 -0
  598. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rest.py +0 -0
  599. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rule/__init__.py +0 -0
  600. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rule/_config_test.py +0 -0
  601. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rule/_service_test.py +0 -0
  602. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rule/config.py +0 -0
  603. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rule/service.py +0 -0
  604. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rule_evaluation/_service_test.py +0 -0
  605. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/rule_evaluation/service.py +0 -0
  606. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/tag/_internal/shared.py +0 -0
  607. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/__init__.py +0 -0
  608. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/_channel_test.py +0 -0
  609. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/_rule_test.py +0 -0
  610. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/_utils_test.py +0 -0
  611. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/calculated_channels.py +0 -0
  612. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/channel.py +0 -0
  613. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/report_templates.py +0 -0
  614. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/rule.py +0 -0
  615. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_py/yaml/utils.py +0 -0
  616. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_stack_py.egg-info/SOURCES.txt +0 -0
  617. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_stack_py.egg-info/dependency_links.txt +0 -0
  618. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_stack_py.egg-info/entry_points.txt +0 -0
  619. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_stack_py.egg-info/requires.txt +0 -0
  620. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/lib/sift_stack_py.egg-info/top_level.txt +0 -0
  621. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/setup.cfg +0 -0
  622. {sift_stack_py-0.16.1 → sift_stack_py-0.16.2}/setup.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: sift_stack_py
3
- Version: 0.16.1
3
+ Version: 0.16.2
4
4
  Summary: Python client library for the Sift API
5
5
  Maintainer-email: Sift Software Engineers <engineering@siftstack.com>
6
6
  License: Copyright (c) 2024 Azimuth Industries Inc.
@@ -26,10 +26,25 @@ from sift_client.transport import WithGrpcClient
26
26
  if TYPE_CHECKING:
27
27
  from datetime import datetime
28
28
 
29
+ from sift_client.sift_types.channel import ChannelReference
29
30
  from sift_client.sift_types.export import ExportOutputFormat
30
31
  from sift_client.transport.grpc_transport import GrpcClient
31
32
 
32
33
 
34
+ def _abstract_ref_to_proto(ref: ChannelReference) -> CalculatedChannelAbstractChannelReference:
35
+ # After ChannelReference validation, calculated_channel is always a version_id string.
36
+ if ref.calculated_channel:
37
+ assert isinstance(ref.calculated_channel, str)
38
+ return CalculatedChannelAbstractChannelReference(
39
+ channel_reference=ref.channel_reference,
40
+ calculated_channel_version_id=ref.calculated_channel,
41
+ )
42
+ return CalculatedChannelAbstractChannelReference(
43
+ channel_reference=ref.channel_reference,
44
+ channel_identifier=ref.channel_identifier or "",
45
+ )
46
+
47
+
33
48
  def _build_calc_channel_configs(
34
49
  calculated_channels: list[CalculatedChannel | CalculatedChannelCreate] | None,
35
50
  ) -> list[CalculatedChannelConfig]:
@@ -46,13 +61,7 @@ def _build_calc_channel_configs(
46
61
  CalculatedChannelConfig(
47
62
  name=cc.name,
48
63
  expression=cc.expression or "",
49
- channel_references=[
50
- CalculatedChannelAbstractChannelReference(
51
- channel_reference=ref.channel_reference,
52
- channel_identifier=ref.channel_identifier,
53
- )
54
- for ref in refs
55
- ],
64
+ channel_references=[_abstract_ref_to_proto(ref) for ref in refs],
56
65
  units=cc.units,
57
66
  )
58
67
  )
@@ -75,6 +75,16 @@ if TYPE_CHECKING:
75
75
  logger = logging.getLogger(__name__)
76
76
 
77
77
 
78
+ def _channel_reference_to_proto(ref: ChannelReference) -> ChannelReferenceProto:
79
+ # ChannelReference's validator normalizes calculated_channel to a version_id str
80
+ # and guarantees exactly one of calculated_channel / channel_identifier is set.
81
+ if ref.calculated_channel:
82
+ return ChannelReferenceProto(
83
+ calculated_channel_version_id=cast("str", ref.calculated_channel)
84
+ )
85
+ return ChannelReferenceProto(name=cast("str", ref.channel_identifier))
86
+
87
+
78
88
  class RulesLowLevelClient(LowLevelClientBase, WithGrpcClient):
79
89
  """Low-level client for the RulesAPI.
80
90
 
@@ -126,7 +136,7 @@ class RulesLowLevelClient(LowLevelClientBase, WithGrpcClient):
126
136
  calculated_channel=CalculatedChannelConfig(
127
137
  expression=create.expression,
128
138
  channel_references={
129
- c.channel_reference: ChannelReferenceProto(name=c.channel_identifier)
139
+ c.channel_reference: _channel_reference_to_proto(c)
130
140
  for c in create.channel_references
131
141
  },
132
142
  )
@@ -259,7 +269,7 @@ class RulesLowLevelClient(LowLevelClientBase, WithGrpcClient):
259
269
  CalculatedChannelConfig(
260
270
  expression=expression,
261
271
  channel_references={
262
- c.channel_reference: ChannelReferenceProto(name=c.channel_identifier)
272
+ c.channel_reference: _channel_reference_to_proto(c)
263
273
  for c in channel_references
264
274
  },
265
275
  )
@@ -32,6 +32,9 @@ async def resolve_calculated_channels(
32
32
 
33
33
  resolved_refs: list[ChannelReference] = []
34
34
  for ref in refs:
35
+ if ref.calculated_channel:
36
+ resolved_refs.append(ref)
37
+ continue
35
38
  channel = await channels_api.find(
36
39
  name=ref.channel_identifier,
37
40
  assets=cc.asset_ids,
@@ -41,6 +41,25 @@ class TestResolveCalculatedChannels:
41
41
  assert refs is not None
42
42
  assert refs[0].channel_identifier == "resolved-uuid"
43
43
 
44
+ @pytest.mark.asyncio
45
+ async def test_skips_lookup_for_calculated_channel_version_id(self):
46
+ api = MagicMock()
47
+ api.find = AsyncMock()
48
+ cc = CalculatedChannelCreate(
49
+ name="nested",
50
+ expression="$1 + 1",
51
+ expression_channel_references=[
52
+ ChannelReference(channel_reference="$1", calculated_channel="v-nested")
53
+ ],
54
+ )
55
+ result = await resolve_calculated_channels([cc], channels_api=api)
56
+ api.find.assert_not_awaited()
57
+ assert result is not None
58
+ refs = result[0].expression_channel_references
59
+ assert refs is not None
60
+ assert refs[0].calculated_channel == "v-nested"
61
+ assert refs[0].channel_identifier is None
62
+
44
63
  @pytest.mark.asyncio
45
64
  async def test_keeps_identifier_when_not_found(self):
46
65
  api = MagicMock()
@@ -1,11 +1,31 @@
1
1
  """Unit tests for data import config models and helpers."""
2
2
 
3
+ from __future__ import annotations
4
+
3
5
  from datetime import datetime, timezone
6
+ from typing import TYPE_CHECKING, cast
4
7
 
5
8
  import pytest
9
+ from sift.common.type.v1.channel_config_pb2 import ChannelConfig as ChannelConfigProto
10
+ from sift.data_imports.v2.data_imports_pb2 import (
11
+ ParquetColumn,
12
+ ParquetConfig,
13
+ ParquetFlatDatasetConfig,
14
+ ParquetSingleChannelPerRowConfig,
15
+ )
16
+ from sift.data_imports.v2.data_imports_pb2 import (
17
+ ParquetDataColumn as ParquetDataColumnProto,
18
+ )
19
+ from sift.data_imports.v2.data_imports_pb2 import (
20
+ ParquetTimeColumn as ParquetTimeColumnProto,
21
+ )
6
22
 
7
23
  from sift_client.resources import DataImportAPI, DataImportAPIAsync
8
- from sift_client.resources.data_imports import _resolve_data_type_key
24
+ from sift_client.resources.data_imports import (
25
+ _infer_time_column,
26
+ _parse_parquet_detect_response,
27
+ _resolve_data_type_key,
28
+ )
9
29
  from sift_client.sift_types.channel import ChannelDataType
10
30
  from sift_client.sift_types.data_import import (
11
31
  CsvDataColumn,
@@ -22,6 +42,11 @@ from sift_client.sift_types.data_import import (
22
42
  TimeFormat,
23
43
  )
24
44
 
45
+ if TYPE_CHECKING:
46
+ from sift.common.type.v1.channel_data_type_pb2 import (
47
+ ChannelDataType as ChannelDataTypeProto,
48
+ )
49
+
25
50
 
26
51
  @pytest.mark.integration
27
52
  def test_client_binding(sift_client):
@@ -362,3 +387,130 @@ class TestResolveDataTypeKey:
362
387
  def test_unknown_extension_raises(self):
363
388
  with pytest.raises(ValueError, match="Unsupported file extension"):
364
389
  _resolve_data_type_key(".xyz", None)
390
+
391
+
392
+ class TestInferTimeColumn:
393
+ def test_picks_canonical_skips_other_columns(self):
394
+ path = _infer_time_column(
395
+ [
396
+ ("delta_time", ChannelDataType.INT_64, "delta_time"),
397
+ ("voltage", ChannelDataType.DOUBLE, "voltage"),
398
+ ("timestamp", ChannelDataType.INT_64, "timestamp"),
399
+ ]
400
+ )
401
+ assert path == "timestamp"
402
+
403
+ def test_accepts_uint64(self):
404
+ path = _infer_time_column([("time", ChannelDataType.UINT_64, "time")])
405
+ assert path == "time"
406
+
407
+ def test_case_insensitive(self):
408
+ path = _infer_time_column([("TimeStamp", ChannelDataType.INT_64, "TimeStamp")])
409
+ assert path == "TimeStamp"
410
+
411
+ def test_multiple_candidates_sorted_alphabetically(self):
412
+ path = _infer_time_column(
413
+ [
414
+ ("timestamp", ChannelDataType.INT_64, "timestamp"),
415
+ ("time", ChannelDataType.INT_64, "time"),
416
+ ("ts", ChannelDataType.INT_64, "ts"),
417
+ ]
418
+ )
419
+ assert path == "time"
420
+
421
+ def test_returns_none_when_no_canonical_int_column(self):
422
+ path = _infer_time_column(
423
+ [
424
+ ("timestamp", ChannelDataType.DOUBLE, "timestamp"),
425
+ ("event_time", ChannelDataType.INT_64, "event_time"),
426
+ ]
427
+ )
428
+ assert path is None
429
+
430
+
431
+ def _make_flat_dataset_response(
432
+ time_path: str, data_columns: list[tuple[str, int]]
433
+ ) -> ParquetConfig:
434
+ return ParquetConfig(
435
+ flat_dataset=ParquetFlatDatasetConfig(
436
+ time_column=ParquetTimeColumnProto(path=time_path),
437
+ data_columns=[
438
+ ParquetDataColumnProto(
439
+ path=path,
440
+ channel_config=ChannelConfigProto(
441
+ name=path,
442
+ data_type=cast("ChannelDataTypeProto.ValueType", data_type),
443
+ ),
444
+ )
445
+ for path, data_type in data_columns
446
+ ],
447
+ )
448
+ )
449
+
450
+
451
+ def _make_scpr_response(time_path: str, columns: list[tuple[str, int]]) -> ParquetConfig:
452
+ return ParquetConfig(
453
+ single_channel_per_row=ParquetSingleChannelPerRowConfig(
454
+ time_column=ParquetTimeColumnProto(path=time_path),
455
+ columns=[
456
+ ParquetColumn(
457
+ path=path,
458
+ column_config=ChannelConfigProto(
459
+ name=path,
460
+ data_type=cast("ChannelDataTypeProto.ValueType", data_type),
461
+ ),
462
+ )
463
+ for path, data_type in columns
464
+ ],
465
+ )
466
+ )
467
+
468
+
469
+ class TestParseParquetDetectResponseTimeFallback:
470
+ def test_flat_dataset_infers_int64_time_column(self):
471
+ proto = _make_flat_dataset_response(
472
+ time_path="",
473
+ data_columns=[
474
+ ("voltage", ChannelDataType.DOUBLE.value),
475
+ ("timestamp", ChannelDataType.INT_64.value),
476
+ ("status", ChannelDataType.INT_32.value),
477
+ ],
478
+ )
479
+ config = _parse_parquet_detect_response(proto, "file.parquet", 0, 0)
480
+ assert isinstance(config, ParquetFlatDatasetImportConfig)
481
+ assert config.time_column.path == "timestamp"
482
+ assert [dc.path for dc in config.data_columns] == ["voltage", "status"]
483
+
484
+ def test_flat_dataset_keeps_server_time_column_when_set(self):
485
+ proto = _make_flat_dataset_response(
486
+ time_path="server_ts",
487
+ data_columns=[
488
+ ("server_ts", ChannelDataType.INT_64.value),
489
+ ("timestamp", ChannelDataType.INT_64.value),
490
+ ("voltage", ChannelDataType.DOUBLE.value),
491
+ ],
492
+ )
493
+ config = _parse_parquet_detect_response(proto, "file.parquet", 0, 0)
494
+ assert config.time_column.path == "server_ts"
495
+ assert [dc.path for dc in config.data_columns] == ["timestamp", "voltage"]
496
+
497
+ def test_flat_dataset_no_int64_match_leaves_time_empty(self):
498
+ proto = _make_flat_dataset_response(
499
+ time_path="",
500
+ data_columns=[("voltage", ChannelDataType.DOUBLE.value)],
501
+ )
502
+ config = _parse_parquet_detect_response(proto, "file.parquet", 0, 0)
503
+ assert config.time_column.path == ""
504
+ assert [dc.path for dc in config.data_columns] == ["voltage"]
505
+
506
+ def test_scpr_infers_int64_time_column(self):
507
+ proto = _make_scpr_response(
508
+ time_path="",
509
+ columns=[
510
+ ("voltage", ChannelDataType.DOUBLE.value),
511
+ ("timestamp", ChannelDataType.INT_64.value),
512
+ ],
513
+ )
514
+ config = _parse_parquet_detect_response(proto, "file.parquet", 0, 0)
515
+ assert isinstance(config, ParquetSingleChannelPerRowImportConfig)
516
+ assert config.time_column.path == "timestamp"
@@ -7,6 +7,7 @@ import pytest
7
7
 
8
8
  from sift_client.sift_types import CalculatedChannel
9
9
  from sift_client.sift_types.calculated_channel import (
10
+ CalculatedChannelCreate,
10
11
  CalculatedChannelUpdate,
11
12
  )
12
13
  from sift_client.sift_types.channel import ChannelReference
@@ -151,6 +152,68 @@ class TestCalculatedChannelBase:
151
152
  ],
152
153
  )
153
154
 
155
+ def test_nested_calculated_channel_reference_serialized_to_version_id_oneof(self):
156
+ """A ChannelReference with calculated_channel set routes to the proto oneof."""
157
+ update = CalculatedChannelUpdate(
158
+ expression="$1 + $2",
159
+ expression_channel_references=[
160
+ ChannelReference(channel_reference="$1", channel_identifier="channel1"),
161
+ ChannelReference(channel_reference="$2", calculated_channel="v-nested"),
162
+ ],
163
+ )
164
+ update.resource_id = "test_calc_channel_id"
165
+
166
+ proto, _ = update.to_proto_with_mask()
167
+
168
+ refs = proto.calculated_channel_configuration.query_configuration.sel.expression_channel_references
169
+ assert len(refs) == 2
170
+ assert refs[0].channel_identifier == "channel1"
171
+ assert refs[0].WhichOneof("calculated_channel_reference") is None
172
+ assert refs[1].WhichOneof("calculated_channel_reference") == "calculated_channel_version_id"
173
+ assert refs[1].calculated_channel_version_id == "v-nested"
174
+ assert refs[1].channel_identifier == ""
175
+
176
+ def test_create_serializes_nested_calculated_channel_reference(self):
177
+ """CalculatedChannelCreate.to_proto routes the version_id into the proto oneof."""
178
+ create = CalculatedChannelCreate(
179
+ name="nested-cc",
180
+ expression="$1 * 2",
181
+ expression_channel_references=[
182
+ ChannelReference(channel_reference="$1", calculated_channel="v-nested"),
183
+ ],
184
+ all_assets=True,
185
+ )
186
+
187
+ proto = create.to_proto()
188
+
189
+ refs = proto.calculated_channel_configuration.query_configuration.sel.expression_channel_references
190
+ assert len(refs) == 1
191
+ assert refs[0].WhichOneof("calculated_channel_reference") == "calculated_channel_version_id"
192
+ assert refs[0].calculated_channel_version_id == "v-nested"
193
+
194
+ def test_create_serializes_nested_reference_from_calculated_channel_object(
195
+ self, mock_calculated_channel
196
+ ):
197
+ """Passing a CalculatedChannel object to ChannelReference also serializes correctly."""
198
+ create = CalculatedChannelCreate(
199
+ name="nested-cc",
200
+ expression="$1 * 2",
201
+ expression_channel_references=[
202
+ ChannelReference(
203
+ channel_reference="$1", calculated_channel=mock_calculated_channel
204
+ ),
205
+ ],
206
+ all_assets=True,
207
+ )
208
+
209
+ proto = create.to_proto()
210
+
211
+ refs = proto.calculated_channel_configuration.query_configuration.sel.expression_channel_references
212
+ assert len(refs) == 1
213
+ assert refs[0].WhichOneof("calculated_channel_reference") == "calculated_channel_version_id"
214
+ # mock_calculated_channel fixture has version_id="v1"
215
+ assert refs[0].calculated_channel_version_id == "v1"
216
+
154
217
  def test_expression_validator_accepts_both_set(self):
155
218
  """Test validator accepts expression and channel references together."""
156
219
  # Should not raise
@@ -6,7 +6,7 @@ from unittest.mock import MagicMock
6
6
  import pytest
7
7
 
8
8
  from sift_client.sift_types import Channel
9
- from sift_client.sift_types.channel import ChannelDataType
9
+ from sift_client.sift_types.channel import ChannelDataType, ChannelReference
10
10
 
11
11
 
12
12
  @pytest.fixture
@@ -104,6 +104,100 @@ class TestChannel:
104
104
  mock_client.channels.get_data.assert_not_called()
105
105
  assert result == mock_data
106
106
 
107
+ def test_channel_reference_requires_one_target(self):
108
+ """ChannelReference must specify exactly one of identifier or calculated_channel."""
109
+ with pytest.raises(ValueError, match="exactly one"):
110
+ ChannelReference(channel_reference="$1")
111
+ with pytest.raises(ValueError, match="exactly one"):
112
+ ChannelReference(
113
+ channel_reference="$1",
114
+ channel_identifier="ch",
115
+ calculated_channel="v-id",
116
+ )
117
+
118
+ def test_channel_reference_accepts_version_id_string(self):
119
+ """A plain version_id string is stored as-is."""
120
+ ref = ChannelReference(channel_reference="$1", calculated_channel="v-abc")
121
+ assert ref.calculated_channel == "v-abc"
122
+ assert ref.channel_identifier is None
123
+
124
+ def test_channel_reference_accepts_calculated_channel_object(self):
125
+ """Passing a CalculatedChannel normalizes to its version_id string."""
126
+ from sift_client.sift_types.calculated_channel import CalculatedChannel
127
+
128
+ cc = CalculatedChannel(
129
+ proto=MagicMock(),
130
+ id_="cc-id",
131
+ name="parent",
132
+ description="",
133
+ expression="$1",
134
+ channel_references=[],
135
+ is_archived=False,
136
+ units=None,
137
+ asset_ids=["asset-1"],
138
+ tag_ids=None,
139
+ all_assets=False,
140
+ organization_id=None,
141
+ client_key=None,
142
+ archived_date=None,
143
+ version_id="v-abc",
144
+ version=1,
145
+ change_message=None,
146
+ user_notes=None,
147
+ created_date=datetime.now(timezone.utc),
148
+ modified_date=datetime.now(timezone.utc),
149
+ created_by_user_id="u",
150
+ modified_by_user_id="u",
151
+ )
152
+
153
+ ref = ChannelReference(channel_reference="$1", calculated_channel=cc)
154
+ assert ref.calculated_channel == "v-abc"
155
+
156
+ def test_channel_reference_rejects_calculated_channel_without_version_id(self):
157
+ """A CalculatedChannel missing version_id is unusable as a reference."""
158
+ from sift_client.sift_types.calculated_channel import CalculatedChannel
159
+
160
+ cc = CalculatedChannel(
161
+ proto=MagicMock(),
162
+ id_="cc-id",
163
+ name="parent",
164
+ description="",
165
+ expression="$1",
166
+ channel_references=[],
167
+ is_archived=False,
168
+ units=None,
169
+ asset_ids=["asset-1"],
170
+ tag_ids=None,
171
+ all_assets=False,
172
+ organization_id=None,
173
+ client_key=None,
174
+ archived_date=None,
175
+ version_id=None,
176
+ version=None,
177
+ change_message=None,
178
+ user_notes=None,
179
+ created_date=datetime.now(timezone.utc),
180
+ modified_date=datetime.now(timezone.utc),
181
+ created_by_user_id="u",
182
+ modified_by_user_id="u",
183
+ )
184
+
185
+ with pytest.raises(ValueError, match="no version_id"):
186
+ ChannelReference(channel_reference="$1", calculated_channel=cc)
187
+
188
+ def test_channel_reference_from_proto_reads_version_id_oneof(self):
189
+ """_from_proto picks calculated_channel when the proto oneof selects it."""
190
+ from sift.calculated_channels.v2.calculated_channels_pb2 import (
191
+ CalculatedChannelAbstractChannelReference,
192
+ )
193
+
194
+ proto = CalculatedChannelAbstractChannelReference(
195
+ channel_reference="$1", calculated_channel_version_id="v-abc"
196
+ )
197
+ ref = ChannelReference._from_proto(proto)
198
+ assert ref.calculated_channel == "v-abc"
199
+ assert ref.channel_identifier is None
200
+
107
201
  def test_data_method_with_minimal_params(self, mock_channel, mock_client):
108
202
  """Test that data() method works with minimal parameters."""
109
203
  mock_data = {"test_channel": MagicMock()}
@@ -147,3 +147,76 @@ class TestRule:
147
147
  mock_update.assert_called_once_with(unarchived_rule)
148
148
  # Verify it returns self
149
149
  assert result is mock_rule
150
+
151
+
152
+ class TestRuleChannelReferenceSerialization:
153
+ """Nested CC references flow through the low-level wrapper and back."""
154
+
155
+ def test_helper_routes_version_id_into_proto(self):
156
+ from sift_client._internal.low_level_wrappers.rules import (
157
+ _channel_reference_to_proto,
158
+ )
159
+
160
+ proto = _channel_reference_to_proto(
161
+ ChannelReference(channel_reference="$1", calculated_channel="v-abc")
162
+ )
163
+ assert proto.HasField("calculated_channel_version_id")
164
+ assert proto.calculated_channel_version_id == "v-abc"
165
+ assert proto.name == ""
166
+
167
+ def test_helper_routes_identifier_into_name(self):
168
+ from sift_client._internal.low_level_wrappers.rules import (
169
+ _channel_reference_to_proto,
170
+ )
171
+
172
+ proto = _channel_reference_to_proto(
173
+ ChannelReference(channel_reference="$1", channel_identifier="my-channel")
174
+ )
175
+ assert not proto.HasField("calculated_channel_version_id")
176
+ assert proto.name == "my-channel"
177
+
178
+ def test_from_proto_reads_version_id_when_present(self):
179
+ from google.protobuf.timestamp_pb2 import Timestamp
180
+ from sift.rules.v1.rules_pb2 import (
181
+ CalculatedChannelConfig,
182
+ RuleCondition,
183
+ RuleConditionExpression,
184
+ )
185
+ from sift.rules.v1.rules_pb2 import (
186
+ ChannelReference as ChannelReferenceProto,
187
+ )
188
+ from sift.rules.v1.rules_pb2 import (
189
+ Rule as RuleProto,
190
+ )
191
+ from sift.rules.v1.rules_pb2 import (
192
+ RuleAction as RuleActionProto,
193
+ )
194
+
195
+ ts = Timestamp()
196
+ ts.GetCurrentTime()
197
+ proto = RuleProto(
198
+ rule_id="r1",
199
+ name="r",
200
+ description="",
201
+ created_date=ts,
202
+ modified_date=ts,
203
+ conditions=[
204
+ RuleCondition(
205
+ expression=RuleConditionExpression(
206
+ calculated_channel=CalculatedChannelConfig(
207
+ expression="$1 > 0",
208
+ channel_references={
209
+ "$1": ChannelReferenceProto(calculated_channel_version_id="v-xyz"),
210
+ },
211
+ )
212
+ ),
213
+ actions=[RuleActionProto(created_date=ts, modified_date=ts)],
214
+ )
215
+ ],
216
+ )
217
+ rule = Rule._from_proto(proto)
218
+ assert rule.channel_references is not None
219
+ assert len(rule.channel_references) == 1
220
+ ref = rule.channel_references[0]
221
+ assert ref.calculated_channel == "v-xyz"
222
+ assert ref.channel_identifier is None
@@ -8,6 +8,7 @@ from sift_client._internal.util.executor import run_sync_function
8
8
  from sift_client._internal.util.file import extract_parquet_footer, upload_file
9
9
  from sift_client.resources._base import ResourceBase
10
10
  from sift_client.sift_types.asset import Asset
11
+ from sift_client.sift_types.channel import ChannelDataType
11
12
  from sift_client.sift_types.data_import import (
12
13
  EXTENSION_TO_DATA_TYPE_KEY,
13
14
  CsvImportConfig,
@@ -15,10 +16,13 @@ from sift_client.sift_types.data_import import (
15
16
  ImportConfig,
16
17
  ParquetFlatDatasetImportConfig,
17
18
  ParquetSingleChannelPerRowImportConfig,
19
+ ParquetTimeColumn,
18
20
  )
19
21
  from sift_client.sift_types.run import Run
20
22
 
21
23
  if TYPE_CHECKING:
24
+ from collections.abc import Iterable
25
+
22
26
  from sift_client.client import SiftClient
23
27
  from sift_client.sift_types.job import Job
24
28
 
@@ -320,6 +324,28 @@ def _parse_csv_detect_response(proto) -> CsvImportConfig:
320
324
  return csv_config
321
325
 
322
326
 
327
+ _TIME_COLUMN_NAMES: frozenset[str] = frozenset({"ts", "timestamp", "time"})
328
+ _TIME_COLUMN_TYPES: frozenset[ChannelDataType] = frozenset(
329
+ {ChannelDataType.INT_64, ChannelDataType.UINT_64}
330
+ )
331
+
332
+
333
+ def _infer_time_column(
334
+ columns: Iterable[tuple[str, ChannelDataType, str]],
335
+ ) -> str | None:
336
+ """Pick a likely time column when the server couldn't identify one.
337
+
338
+ Returns the path of an INT64 or UINT64 column whose name
339
+ (case-insensitive) matches one of ``ts``, ``timestamp``, or ``time``.
340
+ Returns None otherwise.
341
+ """
342
+ data_columns = sorted(columns, key=lambda c: c[0].lower())
343
+ for name, data_type, path in data_columns:
344
+ if data_type in _TIME_COLUMN_TYPES and name.lower() in _TIME_COLUMN_NAMES:
345
+ return path
346
+ return None
347
+
348
+
323
349
  def _parse_parquet_detect_response(
324
350
  proto, filename: str, footer_offset: int, footer_length: int
325
351
  ) -> ParquetFlatDatasetImportConfig | ParquetSingleChannelPerRowImportConfig:
@@ -328,16 +354,30 @@ def _parse_parquet_detect_response(
328
354
  parquet_config = ParquetFlatDatasetImportConfig._from_proto(
329
355
  proto, footer_offset=footer_offset, footer_length=footer_length
330
356
  )
331
- time_path = parquet_config.time_column.path
357
+ time_path: str | None = parquet_config.time_column.path
358
+ if not time_path:
359
+ time_path = _infer_time_column(
360
+ (dc.name, dc.data_type, dc.path) for dc in parquet_config.data_columns
361
+ )
362
+ if time_path:
363
+ parquet_config.time_column = ParquetTimeColumn(path=time_path)
332
364
  if time_path:
333
365
  parquet_config.data_columns = [
334
366
  dc for dc in parquet_config.data_columns if dc.path != time_path
335
367
  ]
336
368
  return parquet_config
337
369
  elif proto.HasField("single_channel_per_row"):
338
- return ParquetSingleChannelPerRowImportConfig._from_proto(
370
+ scpr_config = ParquetSingleChannelPerRowImportConfig._from_proto(
339
371
  proto, footer_offset=footer_offset, footer_length=footer_length
340
372
  )
373
+ if not scpr_config.time_column.path:
374
+ time_path = _infer_time_column(
375
+ (col.column_config.name, ChannelDataType(col.column_config.data_type), col.path)
376
+ for col in proto.single_channel_per_row.columns
377
+ )
378
+ if time_path is not None:
379
+ scpr_config.time_column = ParquetTimeColumn(path=time_path)
380
+ return scpr_config
341
381
  raise ValueError(f"Unsupported parquet layout in DetectConfig response for '{filename}'.")
342
382
 
343
383