UncountablePythonSDK 0.0.189__tar.gz → 0.0.191__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 (462) hide show
  1. {uncountablepythonsdk-0.0.189/UncountablePythonSDK.egg-info → uncountablepythonsdk-0.0.191}/PKG-INFO +2 -1
  2. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191/UncountablePythonSDK.egg-info}/PKG-INFO +2 -1
  3. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/UncountablePythonSDK.egg-info/SOURCES.txt +5 -0
  4. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/UncountablePythonSDK.egg-info/requires.txt +1 -0
  5. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/UncountablePythonSDK.egg-info/scm_file_list.json +5 -0
  6. uncountablepythonsdk-0.0.191/pkgs/type_spec/AGENTS.md +13 -0
  7. uncountablepythonsdk-0.0.191/pkgs/type_spec/CLAUDE.md +5 -0
  8. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/emit_typescript_util.py +25 -4
  9. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/parts/base.ts.prepart +6 -1
  10. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pyproject.toml +1 -0
  11. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/__init__.py +2 -1
  12. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/client.py +8 -1
  13. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/types.py +6 -1
  14. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/cli.py +2 -0
  15. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/job.py +47 -30
  16. uncountablepythonsdk-0.0.191/uncountable/integration/job_queue.py +14 -0
  17. uncountablepythonsdk-0.0.191/uncountable/integration/ownership_lock.py +77 -0
  18. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/command_client.py +2 -0
  19. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/command_server.py +2 -0
  20. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/protocol/command_server.proto +1 -0
  21. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +4 -4
  22. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +2 -0
  23. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/types.py +1 -0
  24. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/datastore/datastore_sql_base.py +14 -7
  25. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/datastore/interface.py +6 -1
  26. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/job_scheduler.py +66 -23
  27. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/worker.py +8 -0
  28. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/scheduler.py +102 -60
  29. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/webhook_server/entrypoint.py +17 -5
  30. uncountablepythonsdk-0.0.191/uncountable/integration/webhook_server/gunicorn_config.py +9 -0
  31. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/entity_t.py +102 -100
  32. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/.github/workflows/documentation.yml +0 -0
  33. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/.github/workflows/publish.yml +0 -0
  34. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/.gitignore +0 -0
  35. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/README.md +0 -0
  36. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/UncountablePythonSDK.egg-info/dependency_links.txt +0 -0
  37. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/UncountablePythonSDK.egg-info/top_level.txt +0 -0
  38. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/.flowmarkignore +0 -0
  39. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/.gitignore +0 -0
  40. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/conf.py +0 -0
  41. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/index.md +0 -0
  42. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/integration_examples/add_file_to_folder.md +0 -0
  43. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/integration_examples/create_ingredient.md +0 -0
  44. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/integration_examples/create_output.md +0 -0
  45. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/integration_examples/index.md +0 -0
  46. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/integration_examples/upload_file.md +0 -0
  47. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/justfile +0 -0
  48. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/requirements.txt +0 -0
  49. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/android-chrome-192x192.png +0 -0
  50. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/android-chrome-512x512.png +0 -0
  51. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/apple-touch-icon.png +0 -0
  52. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/browserconfig.xml +0 -0
  53. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/favicon-16x16.png +0 -0
  54. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/favicon-32x32.png +0 -0
  55. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/manifest.json +0 -0
  56. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/mstile-150x150.png +0 -0
  57. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/favicons/safari-pinned-tab.svg +0 -0
  58. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/docs/static/logo_blue.png +0 -0
  59. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/async_batch.py +0 -0
  60. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/async_batch_large_parse.py +0 -0
  61. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/basic_auth.py +0 -0
  62. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/create_entity.py +0 -0
  63. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/create_ingredient_sdk.py +0 -0
  64. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/download_files.py +0 -0
  65. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/edit_recipe_inputs.py +0 -0
  66. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/concurrent_cron.py +0 -0
  67. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_cron.py +0 -0
  68. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_http.py +0 -0
  69. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_http_get.py +0 -0
  70. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_instrument.py +0 -0
  71. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_parse.py +0 -0
  72. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_predictions.py +0 -0
  73. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +0 -0
  74. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_scale_connection.py +0 -0
  75. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/example_wh.py +0 -0
  76. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/jobs/materials_auto/profile.yaml +0 -0
  77. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/integration-server/pyproject.toml +0 -0
  78. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/invoke_uploader.py +0 -0
  79. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/oauth.py +0 -0
  80. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/set_input_pdf_attribute.py +0 -0
  81. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/set_recipe_metadata_file.py +0 -0
  82. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/set_recipe_output_file_sdk.py +0 -0
  83. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/stream_dataset_measurements.py +0 -0
  84. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/examples/upload_files.py +0 -0
  85. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/__init__.py +0 -0
  86. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/__init__.py +0 -0
  87. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/cached_parser.py +0 -0
  88. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/case_convert.py +0 -0
  89. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/field_name_resolution.py +0 -0
  90. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/parser_base.py +0 -0
  91. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/parser_builder.py +0 -0
  92. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/parser_cache.py +0 -0
  93. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/parser_error.py +0 -0
  94. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/parser_function_type.py +0 -0
  95. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/parser_inner.py +0 -0
  96. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/parser_options.py +0 -0
  97. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/argument_parser/type_predicates.py +0 -0
  98. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/__init__.py +0 -0
  99. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/_blob_session.py +0 -0
  100. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/_file_share_session.py +0 -0
  101. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/_gdrive_session.py +0 -0
  102. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/_local_session.py +0 -0
  103. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/_s3_session.py +0 -0
  104. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/_sftp_connection.py +0 -0
  105. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/_sftp_session.py +0 -0
  106. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/file_type_utils.py +0 -0
  107. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/filesystem_utils/filesystem_session.py +0 -0
  108. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/py.typed +0 -0
  109. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/__init__.py +0 -0
  110. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/annotation.py +0 -0
  111. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/missing_sentry.py +0 -0
  112. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/opaque_key.py +0 -0
  113. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/serial_alias.py +0 -0
  114. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/serial_class.py +0 -0
  115. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/serial_generic.py +0 -0
  116. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/serial_union.py +0 -0
  117. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/unknown.py +0 -0
  118. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/usage.py +0 -0
  119. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization/yaml.py +0 -0
  120. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/__init__.py +0 -0
  121. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/_get_type_for_serialization.py +0 -0
  122. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/convert_to_snakecase.py +0 -0
  123. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/dataclasses.py +0 -0
  124. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/reuse_containers.py +0 -0
  125. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/serialization_helpers.py +0 -0
  126. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/serialize_for_api_encoding.py +0 -0
  127. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/serialization_util/source_encoding_serializer.py +0 -0
  128. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/strenum_compat/__init__.py +0 -0
  129. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/strenum_compat/strenum_compat.py +0 -0
  130. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/__init__.py +0 -0
  131. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/__main__.py +0 -0
  132. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/actions_registry/__init__.py +0 -0
  133. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/actions_registry/__main__.py +0 -0
  134. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/actions_registry/emit_python.py +0 -0
  135. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/actions_registry/emit_typescript.py +0 -0
  136. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/builder.py +0 -0
  137. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/builder_types.py +0 -0
  138. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/config.py +0 -0
  139. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/cross_output_links.py +0 -0
  140. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/emit_io_ts.py +0 -0
  141. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/emit_open_api.py +0 -0
  142. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/emit_open_api_util.py +0 -0
  143. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/emit_python.py +0 -0
  144. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/emit_scss.py +0 -0
  145. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/emit_typescript.py +0 -0
  146. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/load_types.py +0 -0
  147. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/non_discriminated_union_exceptions.py +0 -0
  148. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/open_api_util.py +0 -0
  149. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/parts/base.py.prepart +0 -0
  150. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/test.py +0 -0
  151. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/type_info/__main__.py +0 -0
  152. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/type_info/emit_type_info.py +0 -0
  153. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/ui_entry_actions/__init__.py +0 -0
  154. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +0 -0
  155. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/util.py +0 -0
  156. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/value_spec/__init__.py +0 -0
  157. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/value_spec/__main__.py +0 -0
  158. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/value_spec/convert_type.py +0 -0
  159. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/value_spec/emit_python.py +0 -0
  160. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/pkgs/type_spec/value_spec/types.py +0 -0
  161. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/setup.cfg +0 -0
  162. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/__init__.py +0 -0
  163. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/async_batch.py +0 -0
  164. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/environment.py +0 -0
  165. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/file_upload.py +0 -0
  166. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/query/__init__.py +0 -0
  167. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/query/builder.py +0 -0
  168. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/query/column.py +0 -0
  169. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/query/row.py +0 -0
  170. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/core/query/types.py +0 -0
  171. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/__init__.py +0 -0
  172. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/construct_client.py +0 -0
  173. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/cron.py +0 -0
  174. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/db/__init__.py +0 -0
  175. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/db/connect.py +0 -0
  176. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/db/session.py +0 -0
  177. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/entrypoint.py +0 -0
  178. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/executors/__init__.py +0 -0
  179. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/executors/executors.py +0 -0
  180. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/executors/generic_upload_executor.py +0 -0
  181. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/executors/script_executor.py +0 -0
  182. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/http_server/__init__.py +0 -0
  183. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/http_server/types.py +0 -0
  184. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/__init__.py +0 -0
  185. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/__init__.py +0 -0
  186. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/constants.py +0 -0
  187. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/protocol/__init__.py +0 -0
  188. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +0 -0
  189. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/command_server/provision_webhook.py +0 -0
  190. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/datastore/__init__.py +0 -0
  191. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/datastore/datastore_postgres.py +0 -0
  192. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/datastore/datastore_sqlite.py +0 -0
  193. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/datastore/factory.py +0 -0
  194. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/datastore/model.py +0 -0
  195. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/job_process.py +0 -0
  196. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/job_runner.py +0 -0
  197. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/queue_runner.py +0 -0
  198. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/queue_runner/types.py +0 -0
  199. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/request_context.py +0 -0
  200. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/scan_profiles.py +0 -0
  201. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/secret_retrieval/__init__.py +0 -0
  202. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/secret_retrieval/basic_secret.py +0 -0
  203. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/secret_retrieval/retrieve_secret.py +0 -0
  204. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/server.py +0 -0
  205. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/service.py +0 -0
  206. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/service_runner.py +0 -0
  207. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/telemetry.py +0 -0
  208. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/webhook_bootstrap.py +0 -0
  209. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/integration/webhook_entity.py +0 -0
  210. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/py.typed +0 -0
  211. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/__init__.py +0 -0
  212. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/__init__.py +0 -0
  213. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/batch/__init__.py +0 -0
  214. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/batch/execute_batch.py +0 -0
  215. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/batch/execute_batch_load_async.py +0 -0
  216. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/chemical/__init__.py +0 -0
  217. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/chemical/convert_chemical_formats.py +0 -0
  218. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/condition_parameters/__init__.py +0 -0
  219. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/condition_parameters/upsert_condition_match.py +0 -0
  220. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/condition_parameters/upsert_condition_matches.py +0 -0
  221. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/__init__.py +0 -0
  222. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/add_entity_comment.py +0 -0
  223. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/create_entities.py +0 -0
  224. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/create_entity.py +0 -0
  225. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/create_or_update_entities.py +0 -0
  226. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/create_or_update_entity.py +0 -0
  227. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/export_entities.py +0 -0
  228. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/get_entities_data.py +0 -0
  229. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/grant_entity_permissions.py +0 -0
  230. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/list_aggregate.py +0 -0
  231. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/list_entities.py +0 -0
  232. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/lock_entity.py +0 -0
  233. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/lookup_entity.py +0 -0
  234. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/resolve_entity_ids.py +0 -0
  235. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/set_barcode.py +0 -0
  236. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/set_entities_field_values.py +0 -0
  237. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/set_entity_field_values.py +0 -0
  238. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/set_values.py +0 -0
  239. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/transition_entity_phase.py +0 -0
  240. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/entity/unlock_entity.py +0 -0
  241. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/equipment/__init__.py +0 -0
  242. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/equipment/associate_equipment_input.py +0 -0
  243. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/field_options/__init__.py +0 -0
  244. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/field_options/upsert_field_options.py +0 -0
  245. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/file_folders/__init__.py +0 -0
  246. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/file_folders/add_file_to_folder.py +0 -0
  247. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/file_folders/modify_file_system.py +0 -0
  248. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/files/__init__.py +0 -0
  249. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/files/download_file.py +0 -0
  250. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/id_source/__init__.py +0 -0
  251. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/id_source/list_id_source.py +0 -0
  252. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/id_source/match_id_source.py +0 -0
  253. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/input_groups/__init__.py +0 -0
  254. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/input_groups/get_input_group_names.py +0 -0
  255. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/__init__.py +0 -0
  256. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/create_inputs.py +0 -0
  257. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/get_input_data.py +0 -0
  258. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/get_input_names.py +0 -0
  259. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/get_inputs_data.py +0 -0
  260. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/set_input_attribute_values.py +0 -0
  261. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/set_input_category.py +0 -0
  262. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/set_input_subcategories.py +0 -0
  263. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/inputs/set_intermediate_type.py +0 -0
  264. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/integrations/__init__.py +0 -0
  265. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/integrations/publish_realtime_data.py +0 -0
  266. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/integrations/push_notification.py +0 -0
  267. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/integrations/register_sockets_token.py +0 -0
  268. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/listing/__init__.py +0 -0
  269. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/listing/export_listing.py +0 -0
  270. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/listing/fetch_listing.py +0 -0
  271. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/material_families/__init__.py +0 -0
  272. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/material_families/update_entity_material_families.py +0 -0
  273. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/ml/__init__.py +0 -0
  274. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/ml/get_analyze_results.py +0 -0
  275. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/ml/get_suggest_results.py +0 -0
  276. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/ml/submit_async_job.py +0 -0
  277. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/notebooks/__init__.py +0 -0
  278. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/notebooks/add_notebook_content.py +0 -0
  279. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/notebooks/get_notebook_content.py +0 -0
  280. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/output_parameters/__init__.py +0 -0
  281. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/output_parameters/swap_output_condition_parameters.py +0 -0
  282. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/outputs/__init__.py +0 -0
  283. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/outputs/get_output_data.py +0 -0
  284. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/outputs/get_output_names.py +0 -0
  285. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/outputs/get_output_organization.py +0 -0
  286. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/outputs/resolve_output_conditions.py +0 -0
  287. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/outputs/update_output_condition_parameter.py +0 -0
  288. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/permissions/__init__.py +0 -0
  289. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/permissions/set_core_permissions.py +0 -0
  290. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/permissions/set_entity_permission.py +0 -0
  291. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/project/__init__.py +0 -0
  292. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/project/get_projects.py +0 -0
  293. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/project/get_projects_data.py +0 -0
  294. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipe_links/__init__.py +0 -0
  295. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipe_links/create_recipe_link.py +0 -0
  296. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipe_links/create_recipe_links.py +0 -0
  297. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipe_links/remove_recipe_link.py +0 -0
  298. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipe_metadata/__init__.py +0 -0
  299. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +0 -0
  300. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/__init__.py +0 -0
  301. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/add_recipe_to_project.py +0 -0
  302. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/add_time_series_data.py +0 -0
  303. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/archive_recipes.py +0 -0
  304. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/associate_recipe_as_input.py +0 -0
  305. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/associate_recipe_as_lot.py +0 -0
  306. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/clear_recipe_outputs.py +0 -0
  307. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/create_mix_order.py +0 -0
  308. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/create_recipe.py +0 -0
  309. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/create_recipes.py +0 -0
  310. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/disassociate_recipe_as_input.py +0 -0
  311. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/edit_recipe_inputs.py +0 -0
  312. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/get_column_calculation_values.py +0 -0
  313. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/get_curve.py +0 -0
  314. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/get_recipe_calculations.py +0 -0
  315. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/get_recipe_links.py +0 -0
  316. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/get_recipe_names.py +0 -0
  317. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/get_recipe_output_metadata.py +0 -0
  318. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/get_recipes_data.py +0 -0
  319. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/lock_recipes.py +0 -0
  320. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/remove_recipe_from_project.py +0 -0
  321. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/set_recipe_inputs.py +0 -0
  322. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/set_recipe_metadata.py +0 -0
  323. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/set_recipe_output_annotations.py +0 -0
  324. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/set_recipe_output_file.py +0 -0
  325. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/set_recipe_outputs.py +0 -0
  326. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/set_recipe_tags.py +0 -0
  327. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/set_recipe_total.py +0 -0
  328. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/unarchive_recipes.py +0 -0
  329. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/unlock_recipes.py +0 -0
  330. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/upsert_recipe_workflow_step.py +0 -0
  331. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/recipes/upsert_step_relationships.py +0 -0
  332. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/runsheet/__init__.py +0 -0
  333. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/runsheet/complete_async_upload.py +0 -0
  334. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/runsheet/export_default_runsheet.py +0 -0
  335. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/time_series/__init__.py +0 -0
  336. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/time_series/ingest_dataset_measurements.py +0 -0
  337. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/triggers/__init__.py +0 -0
  338. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/triggers/run_trigger.py +0 -0
  339. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/uploader/__init__.py +0 -0
  340. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/uploader/complete_async_parse.py +0 -0
  341. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/uploader/invoke_uploader.py +0 -0
  342. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/user/__init__.py +0 -0
  343. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/api/user/get_current_user_info.py +0 -0
  344. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/async_batch.py +0 -0
  345. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/async_batch_processor.py +0 -0
  346. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/async_batch_t.py +0 -0
  347. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/async_jobs.py +0 -0
  348. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/async_jobs_t.py +0 -0
  349. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/auth_retrieval.py +0 -0
  350. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/auth_retrieval_t.py +0 -0
  351. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/base.py +0 -0
  352. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/base_t.py +0 -0
  353. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/calculations.py +0 -0
  354. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/calculations_t.py +0 -0
  355. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/chemical_structure.py +0 -0
  356. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/chemical_structure_t.py +0 -0
  357. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/client_base.py +0 -0
  358. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/client_config.py +0 -0
  359. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/client_config_t.py +0 -0
  360. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/condition_match.py +0 -0
  361. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/condition_match_t.py +0 -0
  362. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/curves.py +0 -0
  363. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/curves_t.py +0 -0
  364. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/data.py +0 -0
  365. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/data_t.py +0 -0
  366. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/dataset_measurements.py +0 -0
  367. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/dataset_measurements_t.py +0 -0
  368. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/entity.py +0 -0
  369. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/experiment_groups.py +0 -0
  370. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/experiment_groups_t.py +0 -0
  371. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/exports.py +0 -0
  372. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/exports_t.py +0 -0
  373. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/field_values.py +0 -0
  374. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/field_values_t.py +0 -0
  375. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/fields.py +0 -0
  376. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/fields_t.py +0 -0
  377. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/generic_upload.py +0 -0
  378. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/generic_upload_t.py +0 -0
  379. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/id_source.py +0 -0
  380. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/id_source_t.py +0 -0
  381. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/identifier.py +0 -0
  382. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/identifier_t.py +0 -0
  383. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/input_attributes.py +0 -0
  384. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/input_attributes_t.py +0 -0
  385. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/inputs.py +0 -0
  386. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/inputs_t.py +0 -0
  387. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/integration_server.py +0 -0
  388. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/integration_server_t.py +0 -0
  389. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/integration_session.py +0 -0
  390. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/integration_session_t.py +0 -0
  391. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/integrations.py +0 -0
  392. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/integrations_t.py +0 -0
  393. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/job_definition.py +0 -0
  394. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/job_definition_t.py +0 -0
  395. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/listing.py +0 -0
  396. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/listing_t.py +0 -0
  397. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/ml_reports.py +0 -0
  398. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/ml_reports_t.py +0 -0
  399. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/notices.py +0 -0
  400. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/notices_t.py +0 -0
  401. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/notifications.py +0 -0
  402. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/notifications_t.py +0 -0
  403. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/outputs.py +0 -0
  404. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/outputs_t.py +0 -0
  405. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/overrides.py +0 -0
  406. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/overrides_t.py +0 -0
  407. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/permissions.py +0 -0
  408. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/permissions_t.py +0 -0
  409. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/phases.py +0 -0
  410. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/phases_t.py +0 -0
  411. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/post_base.py +0 -0
  412. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/post_base_t.py +0 -0
  413. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/queued_job.py +0 -0
  414. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/queued_job_t.py +0 -0
  415. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_identifiers.py +0 -0
  416. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_identifiers_t.py +0 -0
  417. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_inputs.py +0 -0
  418. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_inputs_t.py +0 -0
  419. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_links.py +0 -0
  420. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_links_t.py +0 -0
  421. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_metadata.py +0 -0
  422. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_metadata_t.py +0 -0
  423. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_output_metadata.py +0 -0
  424. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_output_metadata_t.py +0 -0
  425. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_step_relationships.py +0 -0
  426. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_step_relationships_t.py +0 -0
  427. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_tags.py +0 -0
  428. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_tags_t.py +0 -0
  429. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_workflow_step_types.py +0 -0
  430. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_workflow_step_types_t.py +0 -0
  431. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_workflow_steps.py +0 -0
  432. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipe_workflow_steps_t.py +0 -0
  433. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipes.py +0 -0
  434. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/recipes_t.py +0 -0
  435. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/request_headers.py +0 -0
  436. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/request_headers_t.py +0 -0
  437. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/response.py +0 -0
  438. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/response_t.py +0 -0
  439. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/runsheet.py +0 -0
  440. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/runsheet_format.py +0 -0
  441. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/runsheet_format_t.py +0 -0
  442. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/runsheet_t.py +0 -0
  443. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/secret_retrieval.py +0 -0
  444. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/secret_retrieval_t.py +0 -0
  445. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/sockets.py +0 -0
  446. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/sockets_t.py +0 -0
  447. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/specs.py +0 -0
  448. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/specs_t.py +0 -0
  449. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/step_relationships.py +0 -0
  450. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/step_relationships_t.py +0 -0
  451. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/units.py +0 -0
  452. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/units_t.py +0 -0
  453. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/uploader.py +0 -0
  454. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/uploader_t.py +0 -0
  455. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/users.py +0 -0
  456. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/users_t.py +0 -0
  457. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/webhook.py +0 -0
  458. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/webhook_job.py +0 -0
  459. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/webhook_job_t.py +0 -0
  460. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/webhook_t.py +0 -0
  461. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/workflows.py +0 -0
  462. {uncountablepythonsdk-0.0.189 → uncountablepythonsdk-0.0.191}/uncountable/types/workflows_t.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.189
3
+ Version: 0.0.191
4
4
  Summary: Uncountable SDK
5
5
  Project-URL: Homepage, https://github.com/uncountableinc/uncountable-python-sdk
6
6
  Project-URL: Repository, https://github.com/uncountableinc/uncountable-python-sdk.git
@@ -33,6 +33,7 @@ Requires-Dist: opentelemetry-sdk>=1.39.1
33
33
  Requires-Dist: paramiko==5.*
34
34
  Requires-Dist: boto3==1.*
35
35
  Requires-Dist: flask==3.*
36
+ Requires-Dist: gunicorn==26.*
36
37
  Requires-Dist: simplejson==3.*
37
38
  Requires-Dist: grpcio==1.83.0
38
39
  Requires-Dist: protobuf>=4.21.1
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.189
3
+ Version: 0.0.191
4
4
  Summary: Uncountable SDK
5
5
  Project-URL: Homepage, https://github.com/uncountableinc/uncountable-python-sdk
6
6
  Project-URL: Repository, https://github.com/uncountableinc/uncountable-python-sdk.git
@@ -33,6 +33,7 @@ Requires-Dist: opentelemetry-sdk>=1.39.1
33
33
  Requires-Dist: paramiko==5.*
34
34
  Requires-Dist: boto3==1.*
35
35
  Requires-Dist: flask==3.*
36
+ Requires-Dist: gunicorn==26.*
36
37
  Requires-Dist: simplejson==3.*
37
38
  Requires-Dist: grpcio==1.83.0
38
39
  Requires-Dist: protobuf>=4.21.1
@@ -101,6 +101,8 @@ pkgs/serialization_util/serialize_for_api_encoding.py
101
101
  pkgs/serialization_util/source_encoding_serializer.py
102
102
  pkgs/strenum_compat/__init__.py
103
103
  pkgs/strenum_compat/strenum_compat.py
104
+ pkgs/type_spec/AGENTS.md
105
+ pkgs/type_spec/CLAUDE.md
104
106
  pkgs/type_spec/__init__.py
105
107
  pkgs/type_spec/__main__.py
106
108
  pkgs/type_spec/builder.py
@@ -153,6 +155,8 @@ uncountable/integration/construct_client.py
153
155
  uncountable/integration/cron.py
154
156
  uncountable/integration/entrypoint.py
155
157
  uncountable/integration/job.py
158
+ uncountable/integration/job_queue.py
159
+ uncountable/integration/ownership_lock.py
156
160
  uncountable/integration/request_context.py
157
161
  uncountable/integration/scan_profiles.py
158
162
  uncountable/integration/scheduler.py
@@ -200,6 +204,7 @@ uncountable/integration/secret_retrieval/__init__.py
200
204
  uncountable/integration/secret_retrieval/basic_secret.py
201
205
  uncountable/integration/secret_retrieval/retrieve_secret.py
202
206
  uncountable/integration/webhook_server/entrypoint.py
207
+ uncountable/integration/webhook_server/gunicorn_config.py
203
208
  uncountable/types/__init__.py
204
209
  uncountable/types/async_batch.py
205
210
  uncountable/types/async_batch_processor.py
@@ -15,6 +15,7 @@ opentelemetry-sdk>=1.39.1
15
15
  paramiko==5.*
16
16
  boto3==1.*
17
17
  flask==3.*
18
+ gunicorn==26.*
18
19
  simplejson==3.*
19
20
  grpcio==1.83.0
20
21
  protobuf>=4.21.1
@@ -96,6 +96,8 @@
96
96
  "pkgs/serialization_util/source_encoding_serializer.py",
97
97
  "pkgs/strenum_compat/__init__.py",
98
98
  "pkgs/strenum_compat/strenum_compat.py",
99
+ "pkgs/type_spec/AGENTS.md",
100
+ "pkgs/type_spec/CLAUDE.md",
99
101
  "pkgs/type_spec/__init__.py",
100
102
  "pkgs/type_spec/__main__.py",
101
103
  "pkgs/type_spec/actions_registry/__init__.py",
@@ -157,6 +159,8 @@
157
159
  "uncountable/integration/http_server/__init__.py",
158
160
  "uncountable/integration/http_server/types.py",
159
161
  "uncountable/integration/job.py",
162
+ "uncountable/integration/job_queue.py",
163
+ "uncountable/integration/ownership_lock.py",
160
164
  "uncountable/integration/queue_runner/__init__.py",
161
165
  "uncountable/integration/queue_runner/command_server/__init__.py",
162
166
  "uncountable/integration/queue_runner/command_server/command_client.py",
@@ -195,6 +199,7 @@
195
199
  "uncountable/integration/webhook_bootstrap.py",
196
200
  "uncountable/integration/webhook_entity.py",
197
201
  "uncountable/integration/webhook_server/entrypoint.py",
202
+ "uncountable/integration/webhook_server/gunicorn_config.py",
198
203
  "uncountable/py.typed",
199
204
  "uncountable/types/__init__.py",
200
205
  "uncountable/types/api/__init__.py",
@@ -0,0 +1,13 @@
1
+ <!-- DO NOT EDIT: this file is generated by `docs/tools/compile.py`.
2
+ Edit fragments under `docs/fragments/` or manifests under `docs/manifests/`,
3
+ then run `just docs compile` to regenerate. -->
4
+
5
+ ## Keep feature-specific mechanisms out of the type_spec type system unless universally applicable
6
+
7
+ Do not extend the type_spec type system with a mechanism scoped to one feature's view of how types
8
+ serialize or behave — for example, custom key conversions added in preparation for LLM/JSON-schema
9
+ tool responses — unless it has been proven universally applicable across type_spec's consumers.
10
+ type_spec is a generic type-definition system shared by the backend, frontend, and SDK, so tying it
11
+ to one view of a feature (such as LLM features) couples the generic types too closely to that single
12
+ consumer. Keep a capability that only one feature needs at that feature's own layer, and promote it
13
+ into the shared type_spec builder/emitter only once multiple consumers demonstrably need it.
@@ -0,0 +1,5 @@
1
+ <!-- DO NOT EDIT: this file is generated by `docs/tools/compile.py`.
2
+ Edit fragments under `docs/fragments/` or manifests under `docs/manifests/`,
3
+ then run `just docs compile` to regenerate. -->
4
+
5
+ @AGENTS.md
@@ -175,6 +175,27 @@ def emit_constant_ts(ctx: EmitTypescriptContext, sconst: builder.SpecConstant) -
175
175
  ctx.out.write(f"export const {const_name} = {value}\n")
176
176
 
177
177
 
178
+ def _collect_object_properties(
179
+ stype: builder.SpecTypeDefnObject,
180
+ ) -> dict[str, builder.SpecProperty]:
181
+ base_properties = (
182
+ _collect_object_properties(stype.base) if stype.base is not None else {}
183
+ )
184
+ return {**base_properties, **(stype.properties or {})}
185
+
186
+
187
+ def _type_info_ref_type_ts(*, stype: builder.SpecTypeDefnObject, base_ref: str) -> str:
188
+ defaulted_names = sorted(
189
+ ts_property_name(prop)
190
+ for prop in _collect_object_properties(stype).values()
191
+ if prop.has_default and not prop.parse_require and prop.default is not None
192
+ )
193
+ if len(defaulted_names) == 0:
194
+ return f"{base_ref}.TypeInfoRef<{stype.name}>"
195
+ defaulted_keys = " | ".join(f'"{name}"' for name in defaulted_names)
196
+ return f"{base_ref}.TypeInfoRef<{stype.name}, {base_ref}.WithDefaultsApplied<{stype.name}, {defaulted_keys}>>"
197
+
198
+
178
199
  def emit_type_info_ref_ts(
179
200
  ctx: EmitTypescriptContext,
180
201
  stype: builder.SpecTypeDefn,
@@ -184,9 +205,9 @@ def emit_type_info_ref_ts(
184
205
  assert ctx.namespace.emit_type_info, (
185
206
  f"{ctx.namespace.name}: $emit_type_info_refs requires $emit_type_info"
186
207
  )
187
- assert (
188
- isinstance(stype, builder.SpecTypeDefnObject) and len(stype.parameters) == 0
189
- ), (
208
+ if not isinstance(stype, builder.SpecTypeDefnObject):
209
+ return
210
+ assert len(stype.parameters) == 0, (
190
211
  f"{ctx.namespace.name}.{stype.name}: type info refs support non-generic objects only"
191
212
  )
192
213
 
@@ -195,7 +216,7 @@ def emit_type_info_ref_ts(
195
216
  ctx.out.write("\n")
196
217
  ctx.out.write(MODIFY_NOTICE)
197
218
  ctx.out.write(
198
- f"export const {stype.name}TypeInfoRef: {base_ref}.TypeInfoRef<{stype.name}> = {{\n"
219
+ f"export const {stype.name}TypeInfoRef: {_type_info_ref_type_ts(stype=stype, base_ref=base_ref)} = {{\n"
199
220
  )
200
221
  ctx.out.write(f'{INDENT}typeName: "{ctx.namespace.name}.{stype.name}",\n')
201
222
  ctx.out.write("}\n")
@@ -40,11 +40,16 @@ declare const brand: unique symbol
40
40
  export type Branded<TBase, TBrand extends string> = TBase & { readonly [brand]: TBrand }
41
41
 
42
42
  declare const typeInfoValue: unique symbol
43
- export interface TypeInfoRef<T> {
43
+ declare const typeInfoParsedValue: unique symbol
44
+ export interface TypeInfoRef<T, TParsed extends T = T> {
44
45
  readonly typeName: string
45
46
  readonly [typeInfoValue]?: T
47
+ readonly [typeInfoParsedValue]?: TParsed
46
48
  }
47
49
 
50
+ export type WithDefaultsApplied<T, TDefaultedKey extends keyof T> = Omit<T, TDefaultedKey> &
51
+ Required<Pick<T, TDefaultedKey>>
52
+
48
53
  // Ids matching a strict integer number are converted to integers
49
54
  export const ID_REGEX = /^-?[1-9][0-9]{0,20}$/
50
55
  // Matches ISO 8601 dates. Stricter than `Date.parse`.
@@ -68,6 +68,7 @@ dependencies = [
68
68
  "paramiko ==5.*",
69
69
  "boto3 == 1.*",
70
70
  "flask == 3.*",
71
+ "gunicorn == 26.*",
71
72
  "simplejson == 3.*",
72
73
  "grpcio == 1.83.0",
73
74
  "protobuf >= 4.21.1",
@@ -1,10 +1,11 @@
1
1
  from .async_batch import AsyncBatchProcessor
2
2
  from .client import Client
3
3
  from .file_upload import MediaFileUpload, UploadedFile
4
- from .types import AuthDetailsApiKey, AuthDetailsOAuth
4
+ from .types import AuthDetailsApiKey, AuthDetailsBearerToken, AuthDetailsOAuth
5
5
 
6
6
  __all__: list[str] = [
7
7
  "AuthDetailsApiKey",
8
+ "AuthDetailsBearerToken",
8
9
  "AuthDetailsOAuth",
9
10
  "AsyncBatchProcessor",
10
11
  "Client",
@@ -31,7 +31,12 @@ from uncountable.types.request_headers_t import (
31
31
  )
32
32
 
33
33
  from .file_upload import FileUpload, FileUploader, UploadedFile
34
- from .types import AuthDetailsAll, AuthDetailsApiKey, AuthDetailsOAuth
34
+ from .types import (
35
+ AuthDetailsAll,
36
+ AuthDetailsApiKey,
37
+ AuthDetailsBearerToken,
38
+ AuthDetailsOAuth,
39
+ )
35
40
 
36
41
  DT = typing.TypeVar("DT")
37
42
 
@@ -351,6 +356,8 @@ class Client(ClientMethods):
351
356
  case AuthDetailsOAuth():
352
357
  token = self._get_oauth_bearer_token(oauth_details=self._auth_details)
353
358
  return {"Authorization": f"Bearer {token}"}
359
+ case AuthDetailsBearerToken():
360
+ return {"Authorization": f"Bearer {self._auth_details.token}"}
354
361
  typing.assert_never(self._auth_details)
355
362
 
356
363
  def _build_http_request(
@@ -13,5 +13,10 @@ class AuthDetailsOAuth:
13
13
  scope: str = "unc.rnd"
14
14
 
15
15
 
16
+ @dataclass(kw_only=True)
17
+ class AuthDetailsBearerToken:
18
+ token: str
19
+
20
+
16
21
  AuthDetails = AuthDetailsApiKey # Legacy Mapping
17
- AuthDetailsAll = AuthDetailsApiKey | AuthDetailsOAuth
22
+ AuthDetailsAll = AuthDetailsApiKey | AuthDetailsOAuth | AuthDetailsBearerToken
@@ -89,6 +89,8 @@ def register_cancel_queued_job_parser(
89
89
  print(
90
90
  "Job successfully cancelled. The integration server will restart."
91
91
  )
92
+ case CommandCancelJobStatus.CANCELLED_QUEUED:
93
+ print("Queued job successfully cancelled.")
92
94
  case CommandCancelJobStatus.NO_JOB_FOUND:
93
95
  print("Job not found.")
94
96
  case CommandCancelJobStatus.JOB_ALREADY_COMPLETED:
@@ -10,7 +10,6 @@ from pkgs.argument_parser import CachedParser
10
10
  from pkgs.serialization_util import serialize_for_api
11
11
  from uncountable.core.async_batch import AsyncBatchProcessor
12
12
  from uncountable.core.client import Client
13
- from uncountable.core.environment import get_local_admin_server_port
14
13
  from uncountable.core.file_upload import FileUpload
15
14
  from uncountable.core.types import AuthDetailsOAuth
16
15
  from uncountable.integration.http_server import (
@@ -18,12 +17,7 @@ from uncountable.integration.http_server import (
18
17
  GenericHttpResponse,
19
18
  HttpException,
20
19
  )
21
- from uncountable.integration.queue_runner.command_server.command_client import (
22
- send_job_queue_message,
23
- )
24
- from uncountable.integration.queue_runner.command_server.types import (
25
- CommandServerException,
26
- )
20
+ from uncountable.integration.job_queue import JobQueue
27
21
  from uncountable.integration.request_context import extract_request_context
28
22
  from uncountable.integration.secret_retrieval import retrieve_secret
29
23
  from uncountable.integration.telemetry import JobLogger
@@ -111,11 +105,7 @@ class _RequestValidatorClient(Client):
111
105
  return self._oauth_bearer_token
112
106
 
113
107
 
114
- class CustomHttpJob(Job[GenericHttpRequest]):
115
- @property
116
- def payload_type(self) -> type[GenericHttpRequest]:
117
- return GenericHttpRequest
118
-
108
+ class HttpJob(ABC):
119
109
  @staticmethod
120
110
  @abstractmethod
121
111
  def validate_request(
@@ -130,6 +120,22 @@ class CustomHttpJob(Job[GenericHttpRequest]):
130
120
  """
131
121
  ...
132
122
 
123
+ @abstractmethod
124
+ def respond_to_request(
125
+ self,
126
+ *,
127
+ request: GenericHttpRequest,
128
+ job_definition: HttpJobDefinitionBase,
129
+ profile_meta: ProfileMetadata,
130
+ job_queue: JobQueue,
131
+ ) -> GenericHttpResponse: ...
132
+
133
+
134
+ class CustomHttpJob(Job[GenericHttpRequest], HttpJob):
135
+ @property
136
+ def payload_type(self) -> type[GenericHttpRequest]:
137
+ return GenericHttpRequest
138
+
133
139
  @staticmethod
134
140
  def get_validated_oauth_request_user_id(
135
141
  *, profile_metadata: ProfileMetadata, request: GenericHttpRequest
@@ -162,6 +168,19 @@ class CustomHttpJob(Job[GenericHttpRequest]):
162
168
  """
163
169
  ...
164
170
 
171
+ @typing.override
172
+ def respond_to_request(
173
+ self,
174
+ *,
175
+ request: GenericHttpRequest,
176
+ job_definition: HttpJobDefinitionBase,
177
+ profile_meta: ProfileMetadata,
178
+ job_queue: JobQueue,
179
+ ) -> GenericHttpResponse:
180
+ return self.handle_request(
181
+ request=request, job_definition=job_definition, profile_meta=profile_meta
182
+ )
183
+
165
184
  def run_outer(self, args: JobArguments) -> JobResult:
166
185
  args.logger.log_warning(
167
186
  message=f"Unexpected call to run_outer for CustomHttpJob: {args.job_definition.id}"
@@ -189,7 +208,7 @@ def _resolve_webhook_signature_key(
189
208
  )
190
209
 
191
210
 
192
- class WebhookJob[WPT](Job[webhook_job_t.WebhookEventPayload]):
211
+ class WebhookJob[WPT](Job[webhook_job_t.WebhookEventPayload], HttpJob):
193
212
  @property
194
213
  def payload_type(self) -> type[webhook_job_t.WebhookEventPayload]:
195
214
  return webhook_job_t.WebhookEventPayload
@@ -219,12 +238,14 @@ class WebhookJob[WPT](Job[webhook_job_t.WebhookEventPayload]):
219
238
  if not hmac.compare_digest(request_body_signature, passed_signature):
220
239
  raise HttpException.payload_failed_signature()
221
240
 
222
- @staticmethod
223
- def handle_request(
241
+ @typing.override
242
+ def respond_to_request(
243
+ self,
224
244
  *,
225
245
  request: GenericHttpRequest,
226
- job_definition: job_definition_t.HttpJobDefinitionBase,
227
- profile_meta: ProfileMetadata, # noqa: ARG004
246
+ job_definition: HttpJobDefinitionBase,
247
+ profile_meta: ProfileMetadata,
248
+ job_queue: JobQueue,
228
249
  ) -> GenericHttpResponse:
229
250
  try:
230
251
  request_body = simplejson.loads(request.body_text)
@@ -234,19 +255,15 @@ class WebhookJob[WPT](Job[webhook_job_t.WebhookEventPayload]):
234
255
 
235
256
  request_context = extract_request_context(headers=request.headers)
236
257
 
237
- try:
238
- send_job_queue_message(
239
- job_ref_name=job_definition.id,
240
- payload=queued_job_t.QueuedJobPayload(
241
- invocation_context=queued_job_t.InvocationContextWebhook(
242
- webhook_payload=webhook_payload,
243
- request_context=request_context,
244
- )
245
- ),
246
- port=get_local_admin_server_port(),
247
- )
248
- except CommandServerException as e:
249
- raise HttpException.unknown_error() from e
258
+ job_queue.enqueue(
259
+ job_ref_name=job_definition.id,
260
+ payload=queued_job_t.QueuedJobPayload(
261
+ invocation_context=queued_job_t.InvocationContextWebhook(
262
+ webhook_payload=webhook_payload,
263
+ request_context=request_context,
264
+ )
265
+ ),
266
+ )
250
267
 
251
268
  return GenericHttpResponse(
252
269
  response=simplejson.dumps(serialize_for_api(WebhookResponse())),
@@ -0,0 +1,14 @@
1
+ from uncountable.integration.queue_runner.datastore import Datastore
2
+ from uncountable.types import queued_job_t
3
+
4
+
5
+ class JobQueue:
6
+ def __init__(self, datastore: Datastore) -> None:
7
+ self._datastore = datastore
8
+
9
+ def enqueue(
10
+ self, *, job_ref_name: str, payload: queued_job_t.QueuedJobPayload
11
+ ) -> str:
12
+ return self._datastore.add_job_to_queue(
13
+ job_payload=payload, job_ref_name=job_ref_name
14
+ ).queued_job_uuid
@@ -0,0 +1,77 @@
1
+ import time
2
+ from collections.abc import Callable, Generator
3
+ from contextlib import contextmanager
4
+ from enum import StrEnum
5
+
6
+ from opentelemetry.trace import get_current_span
7
+ from sqlalchemy import Connection, text
8
+ from sqlalchemy.engine import Engine
9
+
10
+ from uncountable.integration.telemetry import Logger
11
+
12
+ OWNERSHIP_ADVISORY_LOCK_KEY = 0x756E635F696E7467
13
+ OWNERSHIP_LOCK_POLL_INTERVAL_SECS = 1
14
+
15
+
16
+ class OwnershipOutcome(StrEnum):
17
+ ACQUIRED = "acquired"
18
+ SHUTDOWN_REQUESTED = "shutdown_requested"
19
+
20
+
21
+ def _try_acquire_advisory_lock(connection: Connection) -> bool:
22
+ return bool(
23
+ connection.execute(
24
+ text("select pg_try_advisory_lock(:key)"),
25
+ {"key": OWNERSHIP_ADVISORY_LOCK_KEY},
26
+ ).scalar_one()
27
+ )
28
+
29
+
30
+ def _release_advisory_lock(connection: Connection) -> None:
31
+ connection.execute(
32
+ text("select pg_advisory_unlock(:key)"),
33
+ {"key": OWNERSHIP_ADVISORY_LOCK_KEY},
34
+ )
35
+
36
+
37
+ def _wait_for_advisory_lock(
38
+ *, connection: Connection, is_shutdown_requested: Callable[[], bool]
39
+ ) -> OwnershipOutcome:
40
+ logger = Logger(get_current_span())
41
+ if is_shutdown_requested():
42
+ return OwnershipOutcome.SHUTDOWN_REQUESTED
43
+ if _try_acquire_advisory_lock(connection):
44
+ return OwnershipOutcome.ACQUIRED
45
+ logger.log_info("waiting for the integration ownership lock held by another pod")
46
+ while not is_shutdown_requested():
47
+ time.sleep(OWNERSHIP_LOCK_POLL_INTERVAL_SECS)
48
+ if is_shutdown_requested():
49
+ return OwnershipOutcome.SHUTDOWN_REQUESTED
50
+ if _try_acquire_advisory_lock(connection):
51
+ logger.log_info("acquired the integration ownership lock")
52
+ return OwnershipOutcome.ACQUIRED
53
+ return OwnershipOutcome.SHUTDOWN_REQUESTED
54
+
55
+
56
+ @contextmanager
57
+ def hold_integration_ownership(
58
+ *, engine: Engine, is_shutdown_requested: Callable[[], bool]
59
+ ) -> Generator[OwnershipOutcome]:
60
+ dialect_name = engine.dialect.name
61
+ match dialect_name:
62
+ case "sqlite":
63
+ yield OwnershipOutcome.ACQUIRED
64
+ case "postgresql":
65
+ with engine.connect().execution_options(
66
+ isolation_level="AUTOCOMMIT"
67
+ ) as connection:
68
+ outcome = _wait_for_advisory_lock(
69
+ connection=connection, is_shutdown_requested=is_shutdown_requested
70
+ )
71
+ try:
72
+ yield outcome
73
+ finally:
74
+ if outcome == OwnershipOutcome.ACQUIRED:
75
+ _release_advisory_lock(connection)
76
+ case _:
77
+ raise ValueError(f"unsupported database dialect: {dialect_name!r}")
@@ -85,6 +85,8 @@ def send_job_cancellation_message(
85
85
  return CommandCancelJobStatus.NO_JOB_FOUND
86
86
  case CancelJobStatus.CANCELLED_WITH_RESTART:
87
87
  return CommandCancelJobStatus.CANCELLED_WITH_RESTART
88
+ case CancelJobStatus.CANCELLED_QUEUED:
89
+ return CommandCancelJobStatus.CANCELLED_QUEUED
88
90
  case CancelJobStatus.JOB_ALREADY_COMPLETED:
89
91
  return CommandCancelJobStatus.JOB_ALREADY_COMPLETED
90
92
  case _:
@@ -94,6 +94,8 @@ async def serve(command_queue: CommandQueue, datastore: Datastore) -> None:
94
94
  proto_status = CancelJobStatus.NO_JOB_FOUND
95
95
  case CommandCancelJobStatus.CANCELLED_WITH_RESTART:
96
96
  proto_status = CancelJobStatus.CANCELLED_WITH_RESTART
97
+ case CommandCancelJobStatus.CANCELLED_QUEUED:
98
+ proto_status = CancelJobStatus.CANCELLED_QUEUED
97
99
  case CommandCancelJobStatus.JOB_ALREADY_COMPLETED:
98
100
  proto_status = CancelJobStatus.JOB_ALREADY_COMPLETED
99
101
  case _:
@@ -71,6 +71,7 @@ enum CancelJobStatus {
71
71
  CANCELLED_WITH_RESTART = 0;
72
72
  NO_JOB_FOUND = 1;
73
73
  JOB_ALREADY_COMPLETED = 2;
74
+ CANCELLED_QUEUED = 3;
74
75
  }
75
76
 
76
77
  message CancelJobResult {
@@ -29,7 +29,7 @@ from google.protobuf import timestamp_pb2 as google_dot_protobuf_dot_timestamp__
29
29
 
30
30
 
31
31
  DESCRIPTOR = _descriptor_pool.Default().AddSerializedFile(
32
- b'\nQuncountable/integration/queue_runner/command_server/protocol/command_server.proto\x1a\x1fgoogle/protobuf/timestamp.proto"E\n\x11\x45nqueueJobRequest\x12\x14\n\x0cjob_ref_name\x18\x01 \x01(\t\x12\x1a\n\x12serialized_payload\x18\x02 \x01(\t"H\n\x10\x45nqueueJobResult\x12\x1b\n\x13successfully_queued\x18\x01 \x01(\x08\x12\x17\n\x0fqueued_job_uuid\x18\x02 \x01(\t"\x1f\n\x0fRetryJobRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t"F\n\x0eRetryJobResult\x12\x1b\n\x13successfully_queued\x18\x01 \x01(\x08\x12\x17\n\x0fqueued_job_uuid\x18\x02 \x01(\t"\x1a\n\x18VaccuumQueuedJobsRequest"\x19\n\x17VaccuumQueuedJobsResult"\x14\n\x12\x43heckHealthRequest"$\n\x11\x43heckHealthResult\x12\x0f\n\x07success\x18\x01 \x01(\x08"\xc2\x01\n\x15ListQueuedJobsRequest\x12\x0e\n\x06offset\x18\x01 \x01(\r\x12\r\n\x05limit\x18\x02 \x01(\r\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x14\n\x0cjob_ref_name\x18\x04 \x01(\t\x12\x32\n\x0esubmitted_from\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0csubmitted_to\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xf4\x01\n\x14ListQueuedJobsResult\x12\x43\n\x0bqueued_jobs\x18\x01 \x03(\x0b\x32..ListQueuedJobsResult.ListQueuedJobsResultItem\x1a\x96\x01\n\x18ListQueuedJobsResultItem\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x14\n\x0cjob_ref_name\x18\x02 \x01(\t\x12\x14\n\x0cnum_attempts\x18\x03 \x01(\x03\x12\x30\n\x0csubmitted_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06status\x18\x05 \x01(\t"$\n\x10\x43\x61ncelJobRequest\x12\x10\n\x08job_uuid\x18\x01 \x01(\t"3\n\x0f\x43\x61ncelJobResult\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.CancelJobStatus")\n\x17ProvisionWebhookRequest\x12\x0e\n\x06job_id\x18\x01 \x01(\t".\n\x16ProvisionWebhookResult\x12\x14\n\x0cprofile_name\x18\x01 \x01(\t*Z\n\x0f\x43\x61ncelJobStatus\x12\x1a\n\x16\x43\x41NCELLED_WITH_RESTART\x10\x00\x12\x10\n\x0cNO_JOB_FOUND\x10\x01\x12\x19\n\x15JOB_ALREADY_COMPLETED\x10\x02\x32\xbd\x03\n\rCommandServer\x12\x35\n\nEnqueueJob\x12\x12.EnqueueJobRequest\x1a\x11.EnqueueJobResult"\x00\x12/\n\x08RetryJob\x12\x10.RetryJobRequest\x1a\x0f.RetryJobResult"\x00\x12\x38\n\x0b\x43heckHealth\x12\x13.CheckHealthRequest\x1a\x12.CheckHealthResult"\x00\x12\x41\n\x0eListQueuedJobs\x12\x16.ListQueuedJobsRequest\x1a\x15.ListQueuedJobsResult"\x00\x12J\n\x11VaccuumQueuedJobs\x12\x19.VaccuumQueuedJobsRequest\x1a\x18.VaccuumQueuedJobsResult"\x00\x12\x32\n\tCancelJob\x12\x11.CancelJobRequest\x1a\x10.CancelJobResult"\x00\x12G\n\x10ProvisionWebhook\x12\x18.ProvisionWebhookRequest\x1a\x17.ProvisionWebhookResult"\x00\x62\x06proto3'
32
+ b'\nQuncountable/integration/queue_runner/command_server/protocol/command_server.proto\x1a\x1fgoogle/protobuf/timestamp.proto"E\n\x11\x45nqueueJobRequest\x12\x14\n\x0cjob_ref_name\x18\x01 \x01(\t\x12\x1a\n\x12serialized_payload\x18\x02 \x01(\t"H\n\x10\x45nqueueJobResult\x12\x1b\n\x13successfully_queued\x18\x01 \x01(\x08\x12\x17\n\x0fqueued_job_uuid\x18\x02 \x01(\t"\x1f\n\x0fRetryJobRequest\x12\x0c\n\x04uuid\x18\x01 \x01(\t"F\n\x0eRetryJobResult\x12\x1b\n\x13successfully_queued\x18\x01 \x01(\x08\x12\x17\n\x0fqueued_job_uuid\x18\x02 \x01(\t"\x1a\n\x18VaccuumQueuedJobsRequest"\x19\n\x17VaccuumQueuedJobsResult"\x14\n\x12\x43heckHealthRequest"$\n\x11\x43heckHealthResult\x12\x0f\n\x07success\x18\x01 \x01(\x08"\xc2\x01\n\x15ListQueuedJobsRequest\x12\x0e\n\x06offset\x18\x01 \x01(\r\x12\r\n\x05limit\x18\x02 \x01(\r\x12\x0e\n\x06status\x18\x03 \x01(\t\x12\x14\n\x0cjob_ref_name\x18\x04 \x01(\t\x12\x32\n\x0esubmitted_from\x18\x05 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x30\n\x0csubmitted_to\x18\x06 \x01(\x0b\x32\x1a.google.protobuf.Timestamp"\xf4\x01\n\x14ListQueuedJobsResult\x12\x43\n\x0bqueued_jobs\x18\x01 \x03(\x0b\x32..ListQueuedJobsResult.ListQueuedJobsResultItem\x1a\x96\x01\n\x18ListQueuedJobsResultItem\x12\x0c\n\x04uuid\x18\x01 \x01(\t\x12\x14\n\x0cjob_ref_name\x18\x02 \x01(\t\x12\x14\n\x0cnum_attempts\x18\x03 \x01(\x03\x12\x30\n\x0csubmitted_at\x18\x04 \x01(\x0b\x32\x1a.google.protobuf.Timestamp\x12\x0e\n\x06status\x18\x05 \x01(\t"$\n\x10\x43\x61ncelJobRequest\x12\x10\n\x08job_uuid\x18\x01 \x01(\t"3\n\x0f\x43\x61ncelJobResult\x12 \n\x06status\x18\x01 \x01(\x0e\x32\x10.CancelJobStatus")\n\x17ProvisionWebhookRequest\x12\x0e\n\x06job_id\x18\x01 \x01(\t".\n\x16ProvisionWebhookResult\x12\x14\n\x0cprofile_name\x18\x01 \x01(\t*p\n\x0f\x43\x61ncelJobStatus\x12\x1a\n\x16\x43\x41NCELLED_WITH_RESTART\x10\x00\x12\x10\n\x0cNO_JOB_FOUND\x10\x01\x12\x19\n\x15JOB_ALREADY_COMPLETED\x10\x02\x12\x14\n\x10\x43\x41NCELLED_QUEUED\x10\x03\x32\xbd\x03\n\rCommandServer\x12\x35\n\nEnqueueJob\x12\x12.EnqueueJobRequest\x1a\x11.EnqueueJobResult"\x00\x12/\n\x08RetryJob\x12\x10.RetryJobRequest\x1a\x0f.RetryJobResult"\x00\x12\x38\n\x0b\x43heckHealth\x12\x13.CheckHealthRequest\x1a\x12.CheckHealthResult"\x00\x12\x41\n\x0eListQueuedJobs\x12\x16.ListQueuedJobsRequest\x1a\x15.ListQueuedJobsResult"\x00\x12J\n\x11VaccuumQueuedJobs\x12\x19.VaccuumQueuedJobsRequest\x1a\x18.VaccuumQueuedJobsResult"\x00\x12\x32\n\tCancelJob\x12\x11.CancelJobRequest\x1a\x10.CancelJobResult"\x00\x12G\n\x10ProvisionWebhook\x12\x18.ProvisionWebhookRequest\x1a\x17.ProvisionWebhookResult"\x00\x62\x06proto3'
33
33
  )
34
34
 
35
35
  _globals = globals()
@@ -42,7 +42,7 @@ _builder.BuildTopDescriptorsAndMessages(
42
42
  if not _descriptor._USE_C_DESCRIPTORS:
43
43
  DESCRIPTOR._loaded_options = None
44
44
  _globals["_CANCELJOBSTATUS"]._serialized_start = 1109
45
- _globals["_CANCELJOBSTATUS"]._serialized_end = 1199
45
+ _globals["_CANCELJOBSTATUS"]._serialized_end = 1221
46
46
  _globals["_ENQUEUEJOBREQUEST"]._serialized_start = 118
47
47
  _globals["_ENQUEUEJOBREQUEST"]._serialized_end = 187
48
48
  _globals["_ENQUEUEJOBRESULT"]._serialized_start = 189
@@ -73,6 +73,6 @@ if not _descriptor._USE_C_DESCRIPTORS:
73
73
  _globals["_PROVISIONWEBHOOKREQUEST"]._serialized_end = 1059
74
74
  _globals["_PROVISIONWEBHOOKRESULT"]._serialized_start = 1061
75
75
  _globals["_PROVISIONWEBHOOKRESULT"]._serialized_end = 1107
76
- _globals["_COMMANDSERVER"]._serialized_start = 1202
77
- _globals["_COMMANDSERVER"]._serialized_end = 1647
76
+ _globals["_COMMANDSERVER"]._serialized_start = 1224
77
+ _globals["_COMMANDSERVER"]._serialized_end = 1669
78
78
  # @@protoc_insertion_point(module_scope)
@@ -16,10 +16,12 @@ class CancelJobStatus(int, metaclass=_enum_type_wrapper.EnumTypeWrapper):
16
16
  CANCELLED_WITH_RESTART: _ClassVar[CancelJobStatus]
17
17
  NO_JOB_FOUND: _ClassVar[CancelJobStatus]
18
18
  JOB_ALREADY_COMPLETED: _ClassVar[CancelJobStatus]
19
+ CANCELLED_QUEUED: _ClassVar[CancelJobStatus]
19
20
 
20
21
  CANCELLED_WITH_RESTART: CancelJobStatus
21
22
  NO_JOB_FOUND: CancelJobStatus
22
23
  JOB_ALREADY_COMPLETED: CancelJobStatus
24
+ CANCELLED_QUEUED: CancelJobStatus
23
25
 
24
26
  class EnqueueJobRequest(_message.Message):
25
27
  __slots__ = ("job_ref_name", "serialized_payload")
@@ -8,6 +8,7 @@ from uncountable.types import queued_job_t
8
8
 
9
9
  class CommandCancelJobStatus(StrEnum):
10
10
  CANCELLED_WITH_RESTART = "cancelled_with_restart"
11
+ CANCELLED_QUEUED = "cancelled_queued"
11
12
  NO_JOB_FOUND = "no_job_found"
12
13
  JOB_ALREADY_COMPLETED = "job_already_completed"
13
14
 
@@ -204,7 +204,19 @@ class DatastoreSqlBase(Datastore):
204
204
 
205
205
  return None
206
206
 
207
- def load_job_queue(self) -> list[queued_job_t.QueuedJob]:
207
+ def list_queued_job_uuids(self) -> list[str]:
208
+ with self.session_maker() as session:
209
+ select_stmt = select(QueuedJob.id).filter(
210
+ or_(
211
+ QueuedJob.status == queued_job_t.JobStatus.QUEUED,
212
+ QueuedJob.status.is_(None),
213
+ )
214
+ )
215
+ return [row.id for row in session.execute(select_stmt)]
216
+
217
+ def load_queued_jobs(
218
+ self, *, queued_job_uuids: list[str]
219
+ ) -> list[queued_job_t.QueuedJob]:
208
220
  with self.session_maker() as session:
209
221
  select_stmt = (
210
222
  select(
@@ -215,12 +227,7 @@ class DatastoreSqlBase(Datastore):
215
227
  QueuedJob.status,
216
228
  QueuedJob.submitted_at,
217
229
  )
218
- .filter(
219
- or_(
220
- QueuedJob.status == queued_job_t.JobStatus.QUEUED,
221
- QueuedJob.status.is_(None),
222
- )
223
- )
230
+ .filter(QueuedJob.id.in_(queued_job_uuids))
224
231
  .order_by(QueuedJob.submitted_at)
225
232
  )
226
233
 
@@ -31,7 +31,12 @@ class Datastore(ABC):
31
31
  def increment_num_attempts(self, queued_job_uuid: str) -> int: ...
32
32
 
33
33
  @abstractmethod
34
- def load_job_queue(self) -> list[queued_job_t.QueuedJob]: ...
34
+ def list_queued_job_uuids(self) -> list[str]: ...
35
+
36
+ @abstractmethod
37
+ def load_queued_jobs(
38
+ self, *, queued_job_uuids: list[str]
39
+ ) -> list[queued_job_t.QueuedJob]: ...
35
40
 
36
41
  @abstractmethod
37
42
  def get_next_queued_job_for_ref_name(