UncountablePythonSDK 0.0.164__tar.gz → 0.0.167__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 (410) hide show
  1. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/PKG-INFO +1 -1
  2. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/UncountablePythonSDK.egg-info/PKG-INFO +1 -1
  3. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/UncountablePythonSDK.egg-info/SOURCES.txt +2 -0
  4. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/argument_parser/argument_parser.py +5 -3
  5. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization_util/__init__.py +2 -0
  6. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization_util/serialization_helpers.py +25 -0
  7. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/type_info/emit_type_info.py +4 -5
  8. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/client.py +1 -1
  9. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/file_upload.py +1 -1
  10. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/query/builder.py +65 -51
  11. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/executors/executors.py +2 -2
  12. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/job_scheduler.py +4 -4
  13. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/worker.py +38 -2
  14. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/scheduler.py +7 -7
  15. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/telemetry.py +43 -2
  16. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/webhook_server/entrypoint.py +27 -3
  17. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/__init__.py +2 -0
  18. uncountablepythonsdk-0.0.167/uncountable/types/api/output_parameters/swap_output_condition_parameters.py +150 -0
  19. uncountablepythonsdk-0.0.167/uncountable/types/api/user/__init__.py +1 -0
  20. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/async_batch_processor.py +59 -16
  21. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/async_batch_t.py +1 -0
  22. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/client_base.py +105 -74
  23. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/entity_t.py +14 -2
  24. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/.github/workflows/documentation.yml +0 -0
  25. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/.github/workflows/publish.yml +0 -0
  26. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/.gitignore +0 -0
  27. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/.python-version +0 -0
  28. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/README.md +0 -0
  29. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/UncountablePythonSDK.egg-info/dependency_links.txt +0 -0
  30. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/UncountablePythonSDK.egg-info/requires.txt +0 -0
  31. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/UncountablePythonSDK.egg-info/top_level.txt +0 -0
  32. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/.gitignore +0 -0
  33. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/conf.py +0 -0
  34. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/index.md +0 -0
  35. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/integration_examples/add_file_to_folder.md +0 -0
  36. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/integration_examples/create_ingredient.md +0 -0
  37. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/integration_examples/create_output.md +0 -0
  38. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/integration_examples/index.md +0 -0
  39. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/integration_examples/upload_file.md +0 -0
  40. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/justfile +0 -0
  41. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/requirements.txt +0 -0
  42. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/android-chrome-192x192.png +0 -0
  43. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/android-chrome-512x512.png +0 -0
  44. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/apple-touch-icon.png +0 -0
  45. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/browserconfig.xml +0 -0
  46. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/favicon-16x16.png +0 -0
  47. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/favicon-32x32.png +0 -0
  48. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/manifest.json +0 -0
  49. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/mstile-150x150.png +0 -0
  50. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/favicons/safari-pinned-tab.svg +0 -0
  51. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/docs/static/logo_blue.png +0 -0
  52. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/async_batch.py +0 -0
  53. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/async_batch_large_parse.py +0 -0
  54. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/basic_auth.py +0 -0
  55. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/create_entity.py +0 -0
  56. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/create_ingredient_sdk.py +0 -0
  57. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/download_files.py +0 -0
  58. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/edit_recipe_inputs.py +0 -0
  59. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/concurrent_cron.py +0 -0
  60. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/example_cron.py +0 -0
  61. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/example_http.py +0 -0
  62. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/example_instrument.py +0 -0
  63. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/example_parse.py +0 -0
  64. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/example_predictions.py +0 -0
  65. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +0 -0
  66. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/example_wh.py +0 -0
  67. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/jobs/materials_auto/profile.yaml +0 -0
  68. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/integration-server/pyproject.toml +0 -0
  69. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/invoke_uploader.py +0 -0
  70. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/oauth.py +0 -0
  71. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/set_input_pdf_attribute.py +0 -0
  72. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/set_recipe_metadata_file.py +0 -0
  73. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/set_recipe_output_file_sdk.py +0 -0
  74. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/examples/upload_files.py +0 -0
  75. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/__init__.py +0 -0
  76. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/argument_parser/__init__.py +0 -0
  77. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/argument_parser/_is_enum.py +0 -0
  78. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/argument_parser/_is_namedtuple.py +0 -0
  79. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/argument_parser/case_convert.py +0 -0
  80. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/argument_parser/parser_error.py +0 -0
  81. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/__init__.py +0 -0
  82. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/_blob_session.py +0 -0
  83. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/_file_share_session.py +0 -0
  84. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/_gdrive_session.py +0 -0
  85. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/_local_session.py +0 -0
  86. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/_s3_session.py +0 -0
  87. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/_sftp_session.py +0 -0
  88. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/file_type_utils.py +0 -0
  89. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/filesystem_utils/filesystem_session.py +0 -0
  90. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/py.typed +0 -0
  91. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/__init__.py +0 -0
  92. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/annotation.py +0 -0
  93. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/missing_sentry.py +0 -0
  94. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/opaque_key.py +0 -0
  95. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/serial_alias.py +0 -0
  96. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/serial_class.py +0 -0
  97. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/serial_generic.py +0 -0
  98. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/serial_union.py +0 -0
  99. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/unknown.py +0 -0
  100. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization/yaml.py +0 -0
  101. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization_util/_get_type_for_serialization.py +0 -0
  102. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization_util/convert_to_snakecase.py +0 -0
  103. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/serialization_util/dataclasses.py +0 -0
  104. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/strenum_compat/__init__.py +0 -0
  105. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/strenum_compat/strenum_compat.py +0 -0
  106. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/__init__.py +0 -0
  107. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/__main__.py +0 -0
  108. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/actions_registry/__init__.py +0 -0
  109. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/actions_registry/__main__.py +0 -0
  110. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/actions_registry/emit_typescript.py +0 -0
  111. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/builder.py +0 -0
  112. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/builder_types.py +0 -0
  113. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/config.py +0 -0
  114. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/cross_output_links.py +0 -0
  115. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/emit_io_ts.py +0 -0
  116. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/emit_open_api.py +0 -0
  117. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/emit_open_api_util.py +0 -0
  118. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/emit_python.py +0 -0
  119. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/emit_typescript.py +0 -0
  120. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/emit_typescript_util.py +0 -0
  121. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/load_types.py +0 -0
  122. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/non_discriminated_union_exceptions.py +0 -0
  123. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/open_api_util.py +0 -0
  124. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/parts/base.py.prepart +0 -0
  125. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/parts/base.ts.prepart +0 -0
  126. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/test.py +0 -0
  127. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/type_info/__main__.py +0 -0
  128. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/ui_entry_actions/__init__.py +0 -0
  129. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +0 -0
  130. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/util.py +0 -0
  131. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/value_spec/__init__.py +0 -0
  132. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/value_spec/__main__.py +0 -0
  133. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/value_spec/convert_type.py +0 -0
  134. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/value_spec/emit_python.py +0 -0
  135. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pkgs/type_spec/value_spec/types.py +0 -0
  136. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/pyproject.toml +0 -0
  137. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/setup.cfg +0 -0
  138. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/__init__.py +0 -0
  139. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/__init__.py +0 -0
  140. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/async_batch.py +0 -0
  141. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/environment.py +0 -0
  142. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/query/__init__.py +0 -0
  143. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/query/column.py +0 -0
  144. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/query/row.py +0 -0
  145. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/query/types.py +0 -0
  146. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/core/types.py +0 -0
  147. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/__init__.py +0 -0
  148. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/cli.py +0 -0
  149. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/construct_client.py +0 -0
  150. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/cron.py +0 -0
  151. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/db/__init__.py +0 -0
  152. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/db/connect.py +0 -0
  153. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/db/session.py +0 -0
  154. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/entrypoint.py +0 -0
  155. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/executors/__init__.py +0 -0
  156. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/executors/generic_upload_executor.py +0 -0
  157. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/executors/script_executor.py +0 -0
  158. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/http_server/__init__.py +0 -0
  159. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/http_server/types.py +0 -0
  160. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/job.py +0 -0
  161. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/__init__.py +0 -0
  162. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/__init__.py +0 -0
  163. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/command_client.py +0 -0
  164. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/command_server.py +0 -0
  165. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/constants.py +0 -0
  166. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/protocol/__init__.py +0 -0
  167. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/protocol/command_server.proto +0 -0
  168. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +0 -0
  169. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +0 -0
  170. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +0 -0
  171. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/command_server/types.py +0 -0
  172. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/datastore/__init__.py +0 -0
  173. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/datastore/datastore_sqlite.py +0 -0
  174. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/datastore/interface.py +0 -0
  175. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/datastore/model.py +0 -0
  176. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/queue_runner.py +0 -0
  177. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/queue_runner/types.py +0 -0
  178. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/request_context.py +0 -0
  179. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/scan_profiles.py +0 -0
  180. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/secret_retrieval/__init__.py +0 -0
  181. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/secret_retrieval/retrieve_secret.py +0 -0
  182. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/integration/server.py +0 -0
  183. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/py.typed +0 -0
  184. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/__init__.py +0 -0
  185. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/batch/__init__.py +0 -0
  186. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/batch/execute_batch.py +0 -0
  187. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/batch/execute_batch_load_async.py +0 -0
  188. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/chemical/__init__.py +0 -0
  189. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/chemical/convert_chemical_formats.py +0 -0
  190. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/condition_parameters/__init__.py +0 -0
  191. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/condition_parameters/upsert_condition_match.py +0 -0
  192. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/__init__.py +0 -0
  193. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/create_entities.py +0 -0
  194. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/create_entity.py +0 -0
  195. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/create_or_update_entity.py +0 -0
  196. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/export_entities.py +0 -0
  197. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/get_entities_data.py +0 -0
  198. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/grant_entity_permissions.py +0 -0
  199. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/list_aggregate.py +0 -0
  200. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/list_entities.py +0 -0
  201. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/lock_entity.py +0 -0
  202. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/lookup_entity.py +0 -0
  203. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/resolve_entity_ids.py +0 -0
  204. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/set_barcode.py +0 -0
  205. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/set_entity_field_values.py +0 -0
  206. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/set_values.py +0 -0
  207. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/transition_entity_phase.py +0 -0
  208. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/entity/unlock_entity.py +0 -0
  209. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/equipment/__init__.py +0 -0
  210. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/equipment/associate_equipment_input.py +0 -0
  211. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/field_options/__init__.py +0 -0
  212. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/field_options/upsert_field_options.py +0 -0
  213. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/file_folders/__init__.py +0 -0
  214. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/file_folders/add_file_to_folder.py +0 -0
  215. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/file_folders/modify_file_system.py +0 -0
  216. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/files/__init__.py +0 -0
  217. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/files/download_file.py +0 -0
  218. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/id_source/__init__.py +0 -0
  219. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/id_source/list_id_source.py +0 -0
  220. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/id_source/match_id_source.py +0 -0
  221. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/input_groups/__init__.py +0 -0
  222. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/input_groups/get_input_group_names.py +0 -0
  223. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/__init__.py +0 -0
  224. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/create_inputs.py +0 -0
  225. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/get_input_data.py +0 -0
  226. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/get_input_names.py +0 -0
  227. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/get_inputs_data.py +0 -0
  228. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/set_input_attribute_values.py +0 -0
  229. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/set_input_category.py +0 -0
  230. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/set_input_subcategories.py +0 -0
  231. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/inputs/set_intermediate_type.py +0 -0
  232. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/integrations/__init__.py +0 -0
  233. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/integrations/publish_realtime_data.py +0 -0
  234. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/integrations/push_notification.py +0 -0
  235. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/integrations/register_sockets_token.py +0 -0
  236. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/listing/__init__.py +0 -0
  237. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/listing/export_listing.py +0 -0
  238. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/listing/fetch_listing.py +0 -0
  239. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/material_families/__init__.py +0 -0
  240. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/material_families/update_entity_material_families.py +0 -0
  241. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/notebooks/__init__.py +0 -0
  242. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/notebooks/add_notebook_content.py +0 -0
  243. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/notebooks/get_notebook_content.py +0 -0
  244. {uncountablepythonsdk-0.0.164/uncountable/types/api/outputs → uncountablepythonsdk-0.0.167/uncountable/types/api/output_parameters}/__init__.py +0 -0
  245. {uncountablepythonsdk-0.0.164/uncountable/types/api/permissions → uncountablepythonsdk-0.0.167/uncountable/types/api/outputs}/__init__.py +0 -0
  246. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/outputs/get_output_data.py +0 -0
  247. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/outputs/get_output_names.py +0 -0
  248. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/outputs/get_output_organization.py +0 -0
  249. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/outputs/resolve_output_conditions.py +0 -0
  250. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/outputs/update_output_condition_parameter.py +0 -0
  251. {uncountablepythonsdk-0.0.164/uncountable/types/api/project → uncountablepythonsdk-0.0.167/uncountable/types/api/permissions}/__init__.py +0 -0
  252. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/permissions/set_core_permissions.py +0 -0
  253. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/permissions/set_entity_permission.py +0 -0
  254. {uncountablepythonsdk-0.0.164/uncountable/types/api/recipe_links → uncountablepythonsdk-0.0.167/uncountable/types/api/project}/__init__.py +0 -0
  255. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/project/get_projects.py +0 -0
  256. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/project/get_projects_data.py +0 -0
  257. {uncountablepythonsdk-0.0.164/uncountable/types/api/recipe_metadata → uncountablepythonsdk-0.0.167/uncountable/types/api/recipe_links}/__init__.py +0 -0
  258. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipe_links/create_recipe_link.py +0 -0
  259. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipe_links/remove_recipe_link.py +0 -0
  260. {uncountablepythonsdk-0.0.164/uncountable/types/api/recipes → uncountablepythonsdk-0.0.167/uncountable/types/api/recipe_metadata}/__init__.py +0 -0
  261. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +0 -0
  262. {uncountablepythonsdk-0.0.164/uncountable/types/api/runsheet → uncountablepythonsdk-0.0.167/uncountable/types/api/recipes}/__init__.py +0 -0
  263. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/add_recipe_to_project.py +0 -0
  264. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/add_time_series_data.py +0 -0
  265. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/archive_recipes.py +0 -0
  266. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/associate_recipe_as_input.py +0 -0
  267. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/associate_recipe_as_lot.py +0 -0
  268. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/clear_recipe_outputs.py +0 -0
  269. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/create_mix_order.py +0 -0
  270. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/create_recipe.py +0 -0
  271. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/create_recipes.py +0 -0
  272. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/disassociate_recipe_as_input.py +0 -0
  273. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/edit_recipe_inputs.py +0 -0
  274. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/get_column_calculation_values.py +0 -0
  275. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/get_curve.py +0 -0
  276. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/get_recipe_calculations.py +0 -0
  277. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/get_recipe_links.py +0 -0
  278. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/get_recipe_names.py +0 -0
  279. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/get_recipe_output_metadata.py +0 -0
  280. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/get_recipes_data.py +0 -0
  281. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/lock_recipes.py +0 -0
  282. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/remove_recipe_from_project.py +0 -0
  283. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/set_recipe_inputs.py +0 -0
  284. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/set_recipe_metadata.py +0 -0
  285. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/set_recipe_output_annotations.py +0 -0
  286. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/set_recipe_output_file.py +0 -0
  287. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/set_recipe_outputs.py +0 -0
  288. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/set_recipe_tags.py +0 -0
  289. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/set_recipe_total.py +0 -0
  290. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/unarchive_recipes.py +0 -0
  291. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/unlock_recipes.py +0 -0
  292. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/upsert_recipe_workflow_step.py +0 -0
  293. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/recipes/upsert_step_relationships.py +0 -0
  294. {uncountablepythonsdk-0.0.164/uncountable/types/api/triggers → uncountablepythonsdk-0.0.167/uncountable/types/api/runsheet}/__init__.py +0 -0
  295. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/runsheet/complete_async_upload.py +0 -0
  296. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/runsheet/export_default_runsheet.py +0 -0
  297. {uncountablepythonsdk-0.0.164/uncountable/types/api/uploader → uncountablepythonsdk-0.0.167/uncountable/types/api/triggers}/__init__.py +0 -0
  298. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/triggers/run_trigger.py +0 -0
  299. {uncountablepythonsdk-0.0.164/uncountable/types/api/user → uncountablepythonsdk-0.0.167/uncountable/types/api/uploader}/__init__.py +0 -0
  300. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/uploader/complete_async_parse.py +0 -0
  301. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/uploader/invoke_uploader.py +0 -0
  302. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/api/user/get_current_user_info.py +0 -0
  303. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/async_batch.py +0 -0
  304. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/async_jobs.py +0 -0
  305. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/async_jobs_t.py +0 -0
  306. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/auth_retrieval.py +0 -0
  307. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/auth_retrieval_t.py +0 -0
  308. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/base.py +0 -0
  309. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/base_t.py +0 -0
  310. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/calculations.py +0 -0
  311. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/calculations_t.py +0 -0
  312. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/chemical_structure.py +0 -0
  313. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/chemical_structure_t.py +0 -0
  314. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/client_config.py +0 -0
  315. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/client_config_t.py +0 -0
  316. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/curves.py +0 -0
  317. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/curves_t.py +0 -0
  318. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/data.py +0 -0
  319. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/data_t.py +0 -0
  320. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/entity.py +0 -0
  321. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/experiment_groups.py +0 -0
  322. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/experiment_groups_t.py +0 -0
  323. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/exports.py +0 -0
  324. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/exports_t.py +0 -0
  325. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/field_values.py +0 -0
  326. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/field_values_t.py +0 -0
  327. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/fields.py +0 -0
  328. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/fields_t.py +0 -0
  329. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/generic_upload.py +0 -0
  330. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/generic_upload_t.py +0 -0
  331. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/id_source.py +0 -0
  332. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/id_source_t.py +0 -0
  333. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/identifier.py +0 -0
  334. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/identifier_t.py +0 -0
  335. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/input_attributes.py +0 -0
  336. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/input_attributes_t.py +0 -0
  337. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/inputs.py +0 -0
  338. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/inputs_t.py +0 -0
  339. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/integration_server.py +0 -0
  340. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/integration_server_t.py +0 -0
  341. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/integration_session.py +0 -0
  342. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/integration_session_t.py +0 -0
  343. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/integrations.py +0 -0
  344. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/integrations_t.py +0 -0
  345. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/job_definition.py +0 -0
  346. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/job_definition_t.py +0 -0
  347. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/listing.py +0 -0
  348. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/listing_t.py +0 -0
  349. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/notices.py +0 -0
  350. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/notices_t.py +0 -0
  351. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/notifications.py +0 -0
  352. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/notifications_t.py +0 -0
  353. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/outputs.py +0 -0
  354. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/outputs_t.py +0 -0
  355. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/overrides.py +0 -0
  356. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/overrides_t.py +0 -0
  357. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/permissions.py +0 -0
  358. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/permissions_t.py +0 -0
  359. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/phases.py +0 -0
  360. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/phases_t.py +0 -0
  361. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/post_base.py +0 -0
  362. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/post_base_t.py +0 -0
  363. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/queued_job.py +0 -0
  364. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/queued_job_t.py +0 -0
  365. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_identifiers.py +0 -0
  366. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_identifiers_t.py +0 -0
  367. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_inputs.py +0 -0
  368. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_inputs_t.py +0 -0
  369. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_links.py +0 -0
  370. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_links_t.py +0 -0
  371. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_metadata.py +0 -0
  372. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_metadata_t.py +0 -0
  373. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_output_metadata.py +0 -0
  374. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_output_metadata_t.py +0 -0
  375. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_step_relationships.py +0 -0
  376. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_step_relationships_t.py +0 -0
  377. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_tags.py +0 -0
  378. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_tags_t.py +0 -0
  379. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_workflow_step_types.py +0 -0
  380. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_workflow_step_types_t.py +0 -0
  381. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_workflow_steps.py +0 -0
  382. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipe_workflow_steps_t.py +0 -0
  383. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipes.py +0 -0
  384. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/recipes_t.py +0 -0
  385. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/request_headers.py +0 -0
  386. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/request_headers_t.py +0 -0
  387. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/response.py +0 -0
  388. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/response_t.py +0 -0
  389. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/runsheet.py +0 -0
  390. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/runsheet_format.py +0 -0
  391. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/runsheet_format_t.py +0 -0
  392. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/runsheet_t.py +0 -0
  393. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/secret_retrieval.py +0 -0
  394. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/secret_retrieval_t.py +0 -0
  395. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/sockets.py +0 -0
  396. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/sockets_t.py +0 -0
  397. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/specs.py +0 -0
  398. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/specs_t.py +0 -0
  399. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/step_relationships.py +0 -0
  400. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/step_relationships_t.py +0 -0
  401. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/units.py +0 -0
  402. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/units_t.py +0 -0
  403. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/uploader.py +0 -0
  404. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/uploader_t.py +0 -0
  405. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/users.py +0 -0
  406. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/users_t.py +0 -0
  407. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/webhook_job.py +0 -0
  408. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/webhook_job_t.py +0 -0
  409. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/uncountable/types/workflows.py +0 -0
  410. {uncountablepythonsdk-0.0.164 → uncountablepythonsdk-0.0.167}/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.164
3
+ Version: 0.0.167
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
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.164
3
+ Version: 0.0.167
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
@@ -345,6 +345,8 @@ uncountable/types/api/material_families/update_entity_material_families.py
345
345
  uncountable/types/api/notebooks/__init__.py
346
346
  uncountable/types/api/notebooks/add_notebook_content.py
347
347
  uncountable/types/api/notebooks/get_notebook_content.py
348
+ uncountable/types/api/output_parameters/__init__.py
349
+ uncountable/types/api/output_parameters/swap_output_condition_parameters.py
348
350
  uncountable/types/api/outputs/__init__.py
349
351
  uncountable/types/api/outputs/get_output_data.py
350
352
  uncountable/types/api/outputs/get_output_names.py
@@ -426,9 +426,11 @@ def _build_parser_inner(
426
426
  return inner
427
427
 
428
428
  v_parser = _build_parser_inner(args[1], context, type_var_map)
429
- return lambda value: origin(
430
- (key_parser(k), v_parser(v)) for k, v in value.items()
431
- )
429
+
430
+ def parse_dict(value: typing.Any) -> typing.Any:
431
+ return origin((key_parser(k), v_parser(v)) for k, v in value.items())
432
+
433
+ return parse_dict
432
434
 
433
435
  if origin == typing.Literal:
434
436
  valid_values: set[T] = set(typing.get_args(parsed_type))
@@ -3,12 +3,14 @@ from .dataclasses import dict_fields as dict_fields
3
3
  from .dataclasses import iterate_fields as iterate_fields
4
4
  from .serialization_helpers import (
5
5
  JsonValue,
6
+ convert_decimals_to_strings,
6
7
  serialize_for_api,
7
8
  serialize_for_storage,
8
9
  serialize_for_storage_dict,
9
10
  )
10
11
 
11
12
  __all__: list[str] = [
13
+ "convert_decimals_to_strings",
12
14
  "convert_dict_to_snake_case",
13
15
  "serialize_for_api",
14
16
  "serialize_for_storage",
@@ -14,6 +14,7 @@ from typing import (
14
14
  Protocol,
15
15
  TypeVar,
16
16
  Union,
17
+ assert_never,
17
18
  overload,
18
19
  )
19
20
 
@@ -37,6 +38,30 @@ else:
37
38
  T = TypeVar("T")
38
39
 
39
40
 
41
+ # IMPROVE: this match should be exhaustive over JsonValue, but mypy can't verify
42
+ # that Mapping()/Sequence() fully narrow the TYPE_CHECKING definition of JsonValue.
43
+ def convert_decimals_to_strings(obj: JsonValue) -> JsonValue:
44
+ match obj:
45
+ case Decimal():
46
+ return str(obj)
47
+ case (
48
+ str()
49
+ | int()
50
+ | float()
51
+ | bool()
52
+ | None
53
+ | datetime.datetime()
54
+ | datetime.date()
55
+ ):
56
+ return obj
57
+ case Mapping():
58
+ return {k: convert_decimals_to_strings(v) for k, v in obj.items()}
59
+ case Sequence():
60
+ return [convert_decimals_to_strings(v) for v in obj]
61
+ case _ as unreachable:
62
+ assert_never(unreachable)
63
+
64
+
40
65
  class Dataclass(Protocol):
41
66
  __dataclass_fields__: ClassVar[dict] # type: ignore[type-arg,unused-ignore]
42
67
 
@@ -144,11 +144,10 @@ def asdict_for_yaml_dump(dataclass_instance: Any) -> Any:
144
144
  def emit_type_info_python(build: builder.SpecBuilder, output: str) -> None:
145
145
  type_map = _build_map_all(build, python=True)
146
146
 
147
- stripped = _dict_null_strip(asdict_for_yaml_dump(type_map))
148
- serialized = serialize_for_storage(stripped)
149
-
150
- yaml_content = yaml.dump(serialized, default_flow_style=False, sort_keys=True)
151
- util.rewrite_file(f"{output}/type_map.yaml", yaml_content)
147
+ for namespace, data in type_map.namespaces.items():
148
+ serial = serialize_for_storage(asdict_for_yaml_dump(data))
149
+ yaml_content = yaml.dump(serial, default_flow_style=False, sort_keys=True)
150
+ util.rewrite_file(f"{output}/namespace_{namespace}.yaml", yaml_content)
152
151
 
153
152
 
154
153
  @dataclasses.dataclass
@@ -264,7 +264,7 @@ class Client(ClientMethods):
264
264
  }
265
265
  with push_scope_optional(self._cfg.logger, "api_call", attributes=attributes):
266
266
  if self._cfg.logger is not None:
267
- self._cfg.logger.log_info(api_request.endpoint, attributes=attributes)
267
+ self._cfg.logger.log_debug(api_request.endpoint, attributes=attributes)
268
268
  timeout = (
269
269
  api_request.request_options.timeout_secs
270
270
  if api_request.request_options is not None
@@ -142,7 +142,7 @@ class FileUploader:
142
142
  self._logger, "upload_file", attributes=attributes
143
143
  ):
144
144
  if self._logger is not None:
145
- self._logger.log_info("Uploading file", attributes=attributes)
145
+ self._logger.log_debug("Uploading file", attributes=attributes)
146
146
  with file_upload_data(file_upload) as file_bytes:
147
147
  if file_bytes.bytes_data.read(1) == b"":
148
148
  raise UploadFailed(
@@ -1,11 +1,10 @@
1
1
  from __future__ import annotations
2
2
 
3
3
  import json
4
- import time
5
4
  from copy import copy
6
5
  from dataclasses import make_dataclass
7
6
  from decimal import Decimal
8
- from typing import Self
7
+ from typing import Callable, Self
9
8
 
10
9
  from pkgs.argument_parser import CachedParser
11
10
  from pkgs.serialization.serial_class import serial_class
@@ -29,8 +28,7 @@ from uncountable.types import (
29
28
  from uncountable.types.api.entity import list_entities as list_entities_t
30
29
  from uncountable.types.api.files.download_file import FileDownloadQueryEntityField
31
30
 
32
- _ASYNC_EXPORT_TIMEOUT_SECONDS = 60 * 10
33
- _ASYNC_EXPORT_POLL_INTERVAL_SECONDS = 1
31
+ _FETCH_ROW_LIMIT = 100
34
32
 
35
33
 
36
34
  class _AsyncExportJob(QueryRow):
@@ -99,7 +97,9 @@ class QueryBuilder[QueryRowT: QueryRow]:
99
97
  )
100
98
  return branch
101
99
 
102
- def _fetch(self, limit: int = 100, offset: int = 0) -> list[QueryRowT]:
100
+ def _fetch(self, limit: int, offset: int = 0) -> list[QueryRowT]:
101
+ if limit > _FETCH_ROW_LIMIT:
102
+ raise ValueError(f"Fetch row limit cannot exceed {_FETCH_ROW_LIMIT}")
103
103
  rows = self._client.fetch_listing(
104
104
  entity_type=self._base_type,
105
105
  columns=list(self._column_identifiers),
@@ -107,7 +107,6 @@ class QueryBuilder[QueryRowT: QueryRow]:
107
107
  limit=limit,
108
108
  offset=offset,
109
109
  ).results
110
-
111
110
  return [self._parse_row(row.column_values) for row in rows]
112
111
 
113
112
  def _hook_after_parse_row(self, row: QueryRowT) -> None:
@@ -124,13 +123,13 @@ class QueryBuilder[QueryRowT: QueryRow]:
124
123
  return parsed_model
125
124
 
126
125
  def one(self) -> QueryRowT:
127
- results = self._fetch()
126
+ results = self._fetch(limit=2)
128
127
  if len(results) != 1:
129
128
  raise ValueError(f"Expected one result, received {len(results)}")
130
129
  return results[0]
131
130
 
132
131
  def one_or_none(self) -> QueryRowT | None:
133
- results = self._fetch()
132
+ results = self._fetch(limit=2)
134
133
  if len(results) > 1:
135
134
  raise ValueError(f"Expected one result, received {len(results)}")
136
135
  if len(results) == 0:
@@ -142,59 +141,74 @@ class QueryBuilder[QueryRowT: QueryRow]:
142
141
  return None if len(results) == 0 else results[0]
143
142
 
144
143
  def all(self) -> list[QueryRowT]:
145
- results = self._fetch()
146
- if len(results) < 100:
144
+ results = self._fetch(limit=_FETCH_ROW_LIMIT)
145
+ if len(results) < _FETCH_ROW_LIMIT:
147
146
  return results
148
- return self._await_async_export()
149
147
 
150
- def _await_async_export(self) -> list[QueryRowT]:
148
+ # Generate an async listing export if the number of results >= 100
149
+ poll_for_async_export_results = self._submit_async_export()
150
+
151
+ # Resolve exponentially increasing pagination batches until all rows are fetched or the async job completes
152
+ iteration_count: int = 0
153
+ while True:
154
+ for _ in range(2**iteration_count):
155
+ rows = self._fetch(limit=_FETCH_ROW_LIMIT, offset=len(results))
156
+ results.extend(rows)
157
+ if len(rows) < _FETCH_ROW_LIMIT:
158
+ return results
159
+
160
+ if export_results := poll_for_async_export_results():
161
+ return export_results
162
+ iteration_count += 1
163
+
164
+ def _submit_async_export(self) -> Callable[[], list[QueryRowT] | None]:
165
+ """
166
+ Requests an async export of the query results. Returns a closure for polling the results of the export.
167
+ """
151
168
  async_job_entity = self._client.export_listing(
152
169
  entity_type=self._base_type,
153
170
  columns=list(self._column_identifiers),
154
171
  filters=listing_t.FilterNodeColumnAnd(filters=tuple(self._filters)),
155
172
  ).entity
156
173
  if async_job_entity is None:
157
- raise ValueError("Listing export failed to create async job")
158
-
159
- status_query = QueryBuilder(client=self._client, model=_AsyncExportJob)
160
-
161
- start_time = time.time()
162
- while time.time() - start_time < _ASYNC_EXPORT_TIMEOUT_SECONDS:
163
- match (
164
- status_query
174
+ raise ValueError("async listing export generation failed")
175
+ async_job_status: async_jobs_t.AsyncJobStatus | str | None = None
176
+
177
+ def poll_for_results() -> list[QueryRowT] | None:
178
+ nonlocal async_job_status
179
+ if async_job_status == async_jobs_t.AsyncJobStatus.ERROR:
180
+ return None
181
+ async_job_status = (
182
+ QueryBuilder(client=self._client, model=_AsyncExportJob)
165
183
  .filter(_AsyncExportJob.id == async_job_entity.id)
166
184
  .one()
167
185
  .status
168
- ):
169
- case async_jobs_t.AsyncJobStatus.COMPLETED:
170
- export_file = self._client.download_files(
171
- file_query=FileDownloadQueryEntityField(
172
- entity=entity_t.EntityIdentifier(
173
- identifier_key=identifier_t.IdentifierKeyId(
174
- id=async_job_entity.id
175
- ),
176
- type=entity_t.EntityType.ASYNC_JOB,
177
- ),
178
- field_key=identifier_t.IdentifierKeyRefName(
179
- ref_name="unc_async_listing_export_file"
186
+ )
187
+ if async_job_status == async_jobs_t.AsyncJobStatus.COMPLETED:
188
+ export_file = self._client.download_files(
189
+ file_query=FileDownloadQueryEntityField(
190
+ entity=entity_t.EntityIdentifier(
191
+ identifier_key=identifier_t.IdentifierKeyId(
192
+ id=async_job_entity.id
180
193
  ),
194
+ type=entity_t.EntityType.ASYNC_JOB,
195
+ ),
196
+ field_key=identifier_t.IdentifierKeyRefName(
197
+ ref_name="unc_async_listing_export_file"
198
+ ),
199
+ )
200
+ )[0].data.read()
201
+ return [
202
+ self._parse_row(row.column_values)
203
+ for row in CachedParser(list_entities_t.Data)
204
+ .parse_api(
205
+ json.loads(
206
+ export_file,
207
+ parse_float=Decimal,
181
208
  )
182
- )[0].data.read()
183
-
184
- return [
185
- self._parse_row(row.column_values)
186
- for row in CachedParser(list_entities_t.Data)
187
- .parse_api(
188
- json.loads(
189
- export_file,
190
- parse_float=Decimal,
191
- )
192
- )
193
- .results
194
- ]
195
- case async_jobs_t.AsyncJobStatus.ERROR:
196
- raise ValueError("Listing export failed")
197
- time.sleep(_ASYNC_EXPORT_POLL_INTERVAL_SECONDS)
198
- raise TimeoutError(
199
- f"Async listing export timed out after {_ASYNC_EXPORT_TIMEOUT_SECONDS} seconds"
200
- )
209
+ )
210
+ .results
211
+ ]
212
+ return None
213
+
214
+ return poll_for_results
@@ -93,7 +93,7 @@ def execute_job(
93
93
  job = resolve_executor(job_definition.executor, profile_metadata)
94
94
  job_location = f"{job.__class__.__module__}.{job.__class__.__name__}"
95
95
 
96
- job_logger.log_info(f"Starting job: `{job_location}`")
96
+ job_logger.log_debug(f"Starting job: `{job_location}`")
97
97
 
98
98
  run_entity: entity_t.Entity | None = None
99
99
  try:
@@ -115,7 +115,7 @@ def execute_job(
115
115
  result = job_definition_t.JobResult(success=False)
116
116
 
117
117
  submitted_batch_job_ids = args.batch_processor.get_submitted_job_ids()
118
- job_logger.log_info(
118
+ job_logger.log_debug(
119
119
  f"Completed job: `{job_location}` (success={result.success})",
120
120
  attributes={
121
121
  "submitted_batch_job_ids": submitted_batch_job_ids,
@@ -136,7 +136,7 @@ async def start_scheduler(
136
136
  job_payload=payload,
137
137
  job_ref_name=job_ref_name,
138
138
  )
139
- logger.log_info(
139
+ logger.log_debug(
140
140
  "Job submitted successfully.",
141
141
  attributes={"job.queued_job_uuid": queued_job.queued_job_uuid},
142
142
  )
@@ -168,7 +168,7 @@ async def start_scheduler(
168
168
  )
169
169
  )
170
170
 
171
- logger.log_info(
171
+ logger.log_debug(
172
172
  "Job cancelled successfully.",
173
173
  attributes={"job.queued_job_uuid": command.queued_job_uuid},
174
174
  )
@@ -201,10 +201,10 @@ async def start_scheduler(
201
201
  def _handle_vaccuum_queued_jobs_command(
202
202
  command: CommandVaccuumQueuedJobs,
203
203
  ) -> None:
204
- logger.log_info("Vaccuuming queued jobs...")
204
+ logger.log_debug("Vaccuuming queued jobs...")
205
205
  deleted_uuids = datastore.vaccuum_queued_jobs()
206
206
 
207
- logger.log_info(
207
+ logger.log_debug(
208
208
  "Queued jobs vacuumed successfully.",
209
209
  attributes={"job.queued_job_uuids": deleted_uuids},
210
210
  )
@@ -1,4 +1,6 @@
1
1
  import asyncio
2
+ import logging
3
+ import pathlib
2
4
  import sys
3
5
  import typing
4
6
  from concurrent.futures import ProcessPoolExecutor
@@ -105,14 +107,48 @@ def _resolve_queued_job_request_context(
105
107
  return None
106
108
 
107
109
 
110
+ _CGROUP_V2_MEMORY_MAX = pathlib.Path("/sys/fs/cgroup/memory.max")
111
+ _CGROUP_V1_MEMORY_LIMIT = pathlib.Path("/sys/fs/cgroup/memory/memory.limit_in_bytes")
112
+
113
+ _MEMORY_LIMIT_FRACTION_CGROUP = 0.75
114
+ _MEMORY_LIMIT_FRACTION_HOST = 0.9
115
+
116
+ _logger = logging.getLogger(__name__)
117
+
118
+
119
+ def _get_cgroup_memory_limit_bytes() -> int | None:
120
+ for cgroup_path in (_CGROUP_V2_MEMORY_MAX, _CGROUP_V1_MEMORY_LIMIT):
121
+ if not cgroup_path.exists():
122
+ continue
123
+ raw = cgroup_path.read_text().strip()
124
+ if raw == "max":
125
+ # cgroups v2 "max" means no limit is set
126
+ return None
127
+ value = int(raw)
128
+ # cgroups v1 uses a very large sentinel for "no limit"
129
+ if value >= 2**63 - 1:
130
+ return None
131
+ return value
132
+ return None
133
+
134
+
108
135
  def run_queued_job(
109
136
  queued_job: queued_job_t.QueuedJob,
110
137
  ) -> job_definition_t.JobResult:
111
138
  with get_otel_tracer().start_as_current_span(name="run_queued_job") as span:
112
139
  if resource is not None:
113
- total_mem = psutil.virtual_memory().total
114
- limit_bytes = int(total_mem * 0.9)
140
+ cgroup_limit = _get_cgroup_memory_limit_bytes()
141
+ if cgroup_limit is not None:
142
+ limit_bytes = int(cgroup_limit * _MEMORY_LIMIT_FRACTION_CGROUP)
143
+ else:
144
+ total_mem = psutil.virtual_memory().total
145
+ limit_bytes = int(total_mem * _MEMORY_LIMIT_FRACTION_HOST)
115
146
  resource.setrlimit(resource.RLIMIT_AS, (limit_bytes, limit_bytes))
147
+ _logger.info(
148
+ "RLIMIT_AS set to %.2f GiB (source: %s)",
149
+ limit_bytes / (1024**3),
150
+ "cgroup" if cgroup_limit is not None else "host",
151
+ )
116
152
 
117
153
  job_details = get_registered_job_details(queued_job.job_ref_name)
118
154
  job_logger = JobLogger(
@@ -71,7 +71,7 @@ ProcessAlarm = ProcessAlarmRestart | ProcessAlarmShutdownAll
71
71
 
72
72
 
73
73
  def handle_shutdown(logger: Logger, processes: dict[ProcessName, ProcessInfo]) -> None:
74
- logger.log_info("received shutdown command, shutting down sub-processes")
74
+ logger.log_debug("received shutdown command, shutting down sub-processes")
75
75
  for proc_info in processes.values():
76
76
  if proc_info.is_alive:
77
77
  proc_info.process.terminate()
@@ -83,7 +83,7 @@ def handle_shutdown(logger: Logger, processes: dict[ProcessName, ProcessInfo]) -
83
83
  and len(still_living_processes) > 0
84
84
  ):
85
85
  current_loop_processes = [*still_living_processes]
86
- logger.log_info(
86
+ logger.log_debug(
87
87
  "waiting for sub-processes to shut down",
88
88
  attributes={
89
89
  "still_living_processes": [
@@ -94,7 +94,7 @@ def handle_shutdown(logger: Logger, processes: dict[ProcessName, ProcessInfo]) -
94
94
  still_living_processes = []
95
95
  for proc_info in current_loop_processes:
96
96
  if not proc_info.is_alive:
97
- logger.log_info(f"{proc_info.name} shut down successfully")
97
+ logger.log_debug(f"{proc_info.name} shut down successfully")
98
98
  else:
99
99
  still_living_processes.append(proc_info)
100
100
  time.sleep(1)
@@ -121,7 +121,7 @@ def restart_process(
121
121
  processes[ProcessName.QUEUE_RUNNER] = new_info
122
122
  try:
123
123
  _wait_queue_runner_online()
124
- logger.log_info("queue runner restarted successfully")
124
+ logger.log_debug("queue runner restarted successfully")
125
125
  except Exception as e:
126
126
  logger.log_exception(e)
127
127
  logger.log_error(
@@ -135,13 +135,13 @@ def restart_process(
135
135
  cron_proc.start()
136
136
  new_info = ProcessInfo(name=ProcessName.CRON_SERVER, process=cron_proc)
137
137
  processes[ProcessName.CRON_SERVER] = new_info
138
- logger.log_info("cron server restarted successfully")
138
+ logger.log_debug("cron server restarted successfully")
139
139
 
140
140
  case ProcessName.UWSGI:
141
141
  uwsgi_proc: AnyProcess = subprocess.Popen(["uwsgi", "--die-on-term"])
142
142
  new_info = ProcessInfo(name=ProcessName.UWSGI, process=uwsgi_proc)
143
143
  processes[ProcessName.UWSGI] = new_info
144
- logger.log_info("uwsgi restarted successfully")
144
+ logger.log_debug("uwsgi restarted successfully")
145
145
 
146
146
 
147
147
  def check_process_alarms(
@@ -188,7 +188,7 @@ def main() -> None:
188
188
 
189
189
  def add_process(process: ProcessInfo) -> None:
190
190
  processes[process.name] = process
191
- logger.log_info(f"started process {process.name}")
191
+ logger.log_debug(f"started process {process.name}")
192
192
 
193
193
  def _start_queue_runner() -> None:
194
194
  runner_process = multiprocessing.Process(target=start_queue_runner)
@@ -94,6 +94,7 @@ def get_otel_logger() -> OTELLogger:
94
94
 
95
95
 
96
96
  class LogSeverity(StrEnum):
97
+ DEBUG = "Debug"
97
98
  INFO = "Info"
98
99
  WARN = "Warn"
99
100
  ERROR = "Error"
@@ -102,6 +103,8 @@ class LogSeverity(StrEnum):
102
103
  def _get_severity_number(severity: LogSeverity) -> _logs.SeverityNumber:
103
104
  """Map LogSeverity to OpenTelemetry SeverityNumber for Datadog."""
104
105
  match severity:
106
+ case LogSeverity.DEBUG:
107
+ return _logs.SeverityNumber.DEBUG
105
108
  case LogSeverity.INFO:
106
109
  return _logs.SeverityNumber.INFO
107
110
  case LogSeverity.WARN:
@@ -172,6 +175,13 @@ class Logger:
172
175
  def bind(self, *, attributes: Attributes) -> None:
173
176
  self._bound_attributes.update(attributes)
174
177
 
178
+ def log_debug(self, message: str, *, attributes: Attributes | None = None) -> None:
179
+ self._emit_log(
180
+ message=message, severity=LogSeverity.DEBUG, attributes=attributes
181
+ )
182
+
183
+ # Use log_info for user-facing job logs (e.g. example_* and custom executor output).
184
+ # SDK-internal instrumentation should use log_debug instead.
175
185
  def log_info(self, message: str, *, attributes: Attributes | None = None) -> None:
176
186
  self._emit_log(
177
187
  message=message, severity=LogSeverity.INFO, attributes=attributes
@@ -220,9 +230,15 @@ class Logger:
220
230
 
221
231
 
222
232
  class PerJobResourceTracker:
223
- def __init__(self, logger: "JobLogger", sample_interval: float = 0.5) -> None:
233
+ def __init__(
234
+ self,
235
+ logger: "JobLogger",
236
+ sample_interval: float = 0.5,
237
+ log_interval: float = 30.0,
238
+ ) -> None:
224
239
  self.logger = logger
225
240
  self.sample_interval = sample_interval
241
+ self.log_interval = log_interval
226
242
  self._process = psutil.Process(os.getpid())
227
243
  self._stop_event = threading.Event()
228
244
  self._thread: threading.Thread | None = None
@@ -233,15 +249,40 @@ class PerJobResourceTracker:
233
249
  self.start_wall_time: float | None = None
234
250
  self.end_wall_time: float | None = None
235
251
 
252
+ def _current_stats(self) -> Attributes:
253
+ assert self.start_cpu_times is not None
254
+ assert self.start_wall_time is not None
255
+ current_cpu_times = self._process.cpu_times()
256
+ cpu_user = current_cpu_times.user - self.start_cpu_times.user
257
+ cpu_sys = current_cpu_times.system - self.start_cpu_times.system
258
+ cpu_total = cpu_user + cpu_sys
259
+ elapsed = time.monotonic() - self.start_wall_time
260
+ return {
261
+ "cpu_user_s": round(cpu_user, 3),
262
+ "cpu_system_s": round(cpu_sys, 3),
263
+ "cpu_total_s": round(cpu_total, 3),
264
+ "wall_time_s": round(elapsed, 3),
265
+ "current_rss_mb": round(self._process.memory_info().rss / (1024 * 1024), 2),
266
+ "peak_rss_mb": round(self.max_rss / (1024 * 1024), 2),
267
+ }
268
+
236
269
  def start(self) -> None:
237
270
  self.start_cpu_times = self._process.cpu_times()
238
271
  self.start_wall_time = time.monotonic()
239
272
 
240
273
  def _monitor() -> None:
274
+ last_log_time = time.monotonic()
241
275
  try:
242
276
  while not self._stop_event.is_set():
243
277
  rss = self._process.memory_info().rss
244
278
  self.max_rss = max(self.max_rss, rss)
279
+ now = time.monotonic()
280
+ if now - last_log_time >= self.log_interval:
281
+ self.logger.log_debug(
282
+ "Job resource usage (periodic)",
283
+ attributes=self._current_stats(),
284
+ )
285
+ last_log_time = now
245
286
  time.sleep(self.sample_interval)
246
287
  except Exception:
247
288
  self._stop_event.set()
@@ -279,7 +320,7 @@ class PerJobResourceTracker:
279
320
  ),
280
321
  )
281
322
  return
282
- self.logger.log_info("Job resource usage summary", attributes=stats)
323
+ self.logger.log_debug("Job resource usage summary", attributes=stats)
283
324
  return
284
325
 
285
326
  def summary(self) -> Attributes:
@@ -24,8 +24,22 @@ def register_route(
24
24
  job: job_definition_t.HttpJobDefinitionBase,
25
25
  ) -> None:
26
26
  route = f"/{profile_meta.name}/{job.id}"
27
+ log_attributes = {
28
+ "profile.name": profile_meta.name,
29
+ "profile.base_url": profile_meta.base_url,
30
+ "job.name": job.name,
31
+ "job.id": job.id,
32
+ "http.route": route,
33
+ }
27
34
 
28
35
  def handle_request() -> ResponseReturnValue:
36
+ method = flask.request.method
37
+ url = flask.request.url
38
+ request_attributes = {
39
+ **log_attributes,
40
+ "http.method": method,
41
+ "http.url": url,
42
+ }
29
43
  with server_logger.push_scope(route):
30
44
  try:
31
45
  if not isinstance(job.executor, job_definition_t.JobExecutorScript):
@@ -56,10 +70,18 @@ def register_route(
56
70
  http_response.headers,
57
71
  )
58
72
  except HttpException as e:
59
- server_logger.log_exception(e)
73
+ server_logger.log_exception(
74
+ e,
75
+ message=f"HTTP error on {method} {url}",
76
+ attributes=request_attributes,
77
+ )
60
78
  return e.make_error_response()
61
79
  except Exception as e:
62
- server_logger.log_exception(e)
80
+ server_logger.log_exception(
81
+ e,
82
+ message=f"Unexpected error on {method} {url}",
83
+ attributes=request_attributes,
84
+ )
63
85
  return HttpException.unknown_error().make_error_response()
64
86
 
65
87
  app.add_url_rule(
@@ -69,7 +91,9 @@ def register_route(
69
91
  methods=["POST"],
70
92
  )
71
93
 
72
- server_logger.log_info(f"job {job.id} webhook registered at: {route}")
94
+ server_logger.log_debug(
95
+ f"job {job.id} webhook registered at: {route}", attributes=log_attributes
96
+ )
73
97
 
74
98
 
75
99
  def main() -> None:
@@ -135,6 +135,7 @@ from .api.entity import set_values as set_values_t
135
135
  from . import sockets_t as sockets_t
136
136
  from . import specs_t as specs_t
137
137
  from . import step_relationships_t as step_relationships_t
138
+ from .api.output_parameters import swap_output_condition_parameters as swap_output_condition_parameters_t
138
139
  from .api.entity import transition_entity_phase as transition_entity_phase_t
139
140
  from .api.recipes import unarchive_recipes as unarchive_recipes_t
140
141
  from . import units_t as units_t
@@ -286,6 +287,7 @@ __all__: list[str] = [
286
287
  "sockets_t",
287
288
  "specs_t",
288
289
  "step_relationships_t",
290
+ "swap_output_condition_parameters_t",
289
291
  "transition_entity_phase_t",
290
292
  "unarchive_recipes_t",
291
293
  "units_t",