UncountablePythonSDK 0.0.163__tar.gz → 0.0.166__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.163 → uncountablepythonsdk-0.0.166}/.github/workflows/documentation.yml +1 -1
  2. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/.github/workflows/publish.yml +1 -1
  3. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/PKG-INFO +1 -1
  4. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/UncountablePythonSDK.egg-info/PKG-INFO +1 -1
  5. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/UncountablePythonSDK.egg-info/SOURCES.txt +4 -0
  6. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/pyproject.toml +1 -1
  7. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/argument_parser/__init__.py +1 -0
  8. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/argument_parser/argument_parser.py +22 -2
  9. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/argument_parser/parser_error.py +37 -2
  10. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization_util/__init__.py +2 -0
  11. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization_util/serialization_helpers.py +25 -0
  12. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/type_info/emit_type_info.py +4 -5
  13. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/client.py +3 -4
  14. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/construct_client.py +13 -19
  15. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/worker.py +50 -3
  16. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/telemetry.py +32 -1
  17. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/webhook_server/entrypoint.py +27 -3
  18. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/__init__.py +4 -0
  19. uncountablepythonsdk-0.0.166/uncountable/types/api/output_parameters/swap_output_condition_parameters.py +150 -0
  20. uncountablepythonsdk-0.0.166/uncountable/types/api/user/__init__.py +1 -0
  21. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/async_batch_processor.py +67 -24
  22. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/async_batch_t.py +1 -0
  23. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/client_base.py +121 -90
  24. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/entity_t.py +22 -2
  25. uncountablepythonsdk-0.0.166/uncountable/types/request_headers.py +9 -0
  26. uncountablepythonsdk-0.0.166/uncountable/types/request_headers_t.py +33 -0
  27. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/.gitignore +0 -0
  28. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/.python-version +0 -0
  29. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/README.md +0 -0
  30. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/UncountablePythonSDK.egg-info/dependency_links.txt +0 -0
  31. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/UncountablePythonSDK.egg-info/requires.txt +0 -0
  32. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/UncountablePythonSDK.egg-info/top_level.txt +0 -0
  33. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/.gitignore +0 -0
  34. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/conf.py +0 -0
  35. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/index.md +0 -0
  36. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/integration_examples/add_file_to_folder.md +0 -0
  37. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/integration_examples/create_ingredient.md +0 -0
  38. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/integration_examples/create_output.md +0 -0
  39. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/integration_examples/index.md +0 -0
  40. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/integration_examples/upload_file.md +0 -0
  41. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/justfile +0 -0
  42. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/requirements.txt +0 -0
  43. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/android-chrome-192x192.png +0 -0
  44. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/android-chrome-512x512.png +0 -0
  45. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/apple-touch-icon.png +0 -0
  46. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/browserconfig.xml +0 -0
  47. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/favicon-16x16.png +0 -0
  48. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/favicon-32x32.png +0 -0
  49. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/manifest.json +0 -0
  50. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/mstile-150x150.png +0 -0
  51. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/favicons/safari-pinned-tab.svg +0 -0
  52. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/docs/static/logo_blue.png +0 -0
  53. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/async_batch.py +0 -0
  54. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/async_batch_large_parse.py +0 -0
  55. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/basic_auth.py +0 -0
  56. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/create_entity.py +0 -0
  57. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/create_ingredient_sdk.py +0 -0
  58. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/download_files.py +0 -0
  59. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/edit_recipe_inputs.py +0 -0
  60. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/concurrent_cron.py +0 -0
  61. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/example_cron.py +0 -0
  62. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/example_http.py +0 -0
  63. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/example_instrument.py +0 -0
  64. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/example_parse.py +0 -0
  65. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/example_predictions.py +0 -0
  66. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +0 -0
  67. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/example_wh.py +0 -0
  68. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/integration-server/jobs/materials_auto/profile.yaml +0 -0
  69. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/invoke_uploader.py +0 -0
  70. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/oauth.py +0 -0
  71. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/set_input_pdf_attribute.py +0 -0
  72. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/set_recipe_metadata_file.py +0 -0
  73. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/set_recipe_output_file_sdk.py +0 -0
  74. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/examples/upload_files.py +0 -0
  75. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/__init__.py +0 -0
  76. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/argument_parser/_is_enum.py +0 -0
  77. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/argument_parser/_is_namedtuple.py +0 -0
  78. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/argument_parser/case_convert.py +0 -0
  79. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/__init__.py +0 -0
  80. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/_blob_session.py +0 -0
  81. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/_file_share_session.py +0 -0
  82. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/_gdrive_session.py +0 -0
  83. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/_local_session.py +0 -0
  84. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/_s3_session.py +0 -0
  85. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/_sftp_session.py +0 -0
  86. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/file_type_utils.py +0 -0
  87. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/filesystem_utils/filesystem_session.py +0 -0
  88. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/py.typed +0 -0
  89. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/__init__.py +0 -0
  90. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/annotation.py +0 -0
  91. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/missing_sentry.py +0 -0
  92. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/opaque_key.py +0 -0
  93. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/serial_alias.py +0 -0
  94. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/serial_class.py +0 -0
  95. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/serial_generic.py +0 -0
  96. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/serial_union.py +0 -0
  97. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/unknown.py +0 -0
  98. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization/yaml.py +0 -0
  99. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization_util/_get_type_for_serialization.py +0 -0
  100. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization_util/convert_to_snakecase.py +0 -0
  101. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/serialization_util/dataclasses.py +0 -0
  102. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/strenum_compat/__init__.py +0 -0
  103. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/strenum_compat/strenum_compat.py +0 -0
  104. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/__init__.py +0 -0
  105. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/__main__.py +0 -0
  106. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/actions_registry/__init__.py +0 -0
  107. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/actions_registry/__main__.py +0 -0
  108. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/actions_registry/emit_typescript.py +0 -0
  109. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/builder.py +0 -0
  110. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/builder_types.py +0 -0
  111. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/config.py +0 -0
  112. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/cross_output_links.py +0 -0
  113. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/emit_io_ts.py +0 -0
  114. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/emit_open_api.py +0 -0
  115. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/emit_open_api_util.py +0 -0
  116. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/emit_python.py +0 -0
  117. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/emit_typescript.py +0 -0
  118. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/emit_typescript_util.py +0 -0
  119. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/load_types.py +0 -0
  120. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/non_discriminated_union_exceptions.py +0 -0
  121. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/open_api_util.py +0 -0
  122. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/parts/base.py.prepart +0 -0
  123. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/parts/base.ts.prepart +0 -0
  124. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/test.py +0 -0
  125. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/type_info/__main__.py +0 -0
  126. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/ui_entry_actions/__init__.py +0 -0
  127. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +0 -0
  128. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/util.py +0 -0
  129. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/value_spec/__init__.py +0 -0
  130. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/value_spec/__main__.py +0 -0
  131. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/value_spec/convert_type.py +0 -0
  132. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/value_spec/emit_python.py +0 -0
  133. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pkgs/type_spec/value_spec/types.py +0 -0
  134. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/pyproject.toml +0 -0
  135. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/setup.cfg +0 -0
  136. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/__init__.py +0 -0
  137. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/__init__.py +0 -0
  138. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/async_batch.py +0 -0
  139. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/environment.py +0 -0
  140. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/file_upload.py +0 -0
  141. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/query/__init__.py +0 -0
  142. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/query/builder.py +0 -0
  143. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/query/column.py +0 -0
  144. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/query/row.py +0 -0
  145. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/query/types.py +0 -0
  146. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/core/types.py +0 -0
  147. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/__init__.py +0 -0
  148. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/cli.py +0 -0
  149. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/cron.py +0 -0
  150. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/db/__init__.py +0 -0
  151. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/db/connect.py +0 -0
  152. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/db/session.py +0 -0
  153. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/entrypoint.py +0 -0
  154. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/executors/__init__.py +0 -0
  155. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/executors/executors.py +0 -0
  156. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/executors/generic_upload_executor.py +0 -0
  157. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/executors/script_executor.py +0 -0
  158. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/http_server/__init__.py +0 -0
  159. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/http_server/types.py +0 -0
  160. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/job.py +0 -0
  161. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/__init__.py +0 -0
  162. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/__init__.py +0 -0
  163. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/command_client.py +0 -0
  164. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/command_server.py +0 -0
  165. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/constants.py +0 -0
  166. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/protocol/__init__.py +0 -0
  167. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/protocol/command_server.proto +0 -0
  168. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +0 -0
  169. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +0 -0
  170. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +0 -0
  171. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/command_server/types.py +0 -0
  172. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/datastore/__init__.py +0 -0
  173. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/datastore/datastore_sqlite.py +0 -0
  174. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/datastore/interface.py +0 -0
  175. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/datastore/model.py +0 -0
  176. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/job_scheduler.py +0 -0
  177. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/queue_runner.py +0 -0
  178. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/queue_runner/types.py +0 -0
  179. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/request_context.py +0 -0
  180. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/scan_profiles.py +0 -0
  181. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/scheduler.py +0 -0
  182. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/secret_retrieval/__init__.py +0 -0
  183. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/secret_retrieval/retrieve_secret.py +0 -0
  184. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/integration/server.py +0 -0
  185. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/py.typed +0 -0
  186. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/__init__.py +0 -0
  187. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/batch/__init__.py +0 -0
  188. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/batch/execute_batch.py +0 -0
  189. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/batch/execute_batch_load_async.py +0 -0
  190. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/chemical/__init__.py +0 -0
  191. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/chemical/convert_chemical_formats.py +0 -0
  192. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/condition_parameters/__init__.py +0 -0
  193. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/condition_parameters/upsert_condition_match.py +0 -0
  194. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/__init__.py +0 -0
  195. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/create_entities.py +0 -0
  196. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/create_entity.py +0 -0
  197. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/create_or_update_entity.py +0 -0
  198. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/export_entities.py +0 -0
  199. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/get_entities_data.py +0 -0
  200. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/grant_entity_permissions.py +0 -0
  201. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/list_aggregate.py +0 -0
  202. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/list_entities.py +0 -0
  203. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/lock_entity.py +0 -0
  204. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/lookup_entity.py +0 -0
  205. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/resolve_entity_ids.py +0 -0
  206. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/set_barcode.py +0 -0
  207. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/set_entity_field_values.py +0 -0
  208. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/set_values.py +0 -0
  209. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/transition_entity_phase.py +0 -0
  210. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/entity/unlock_entity.py +0 -0
  211. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/equipment/__init__.py +0 -0
  212. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/equipment/associate_equipment_input.py +0 -0
  213. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/field_options/__init__.py +0 -0
  214. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/field_options/upsert_field_options.py +0 -0
  215. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/file_folders/__init__.py +0 -0
  216. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/file_folders/add_file_to_folder.py +0 -0
  217. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/file_folders/modify_file_system.py +0 -0
  218. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/files/__init__.py +0 -0
  219. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/files/download_file.py +0 -0
  220. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/id_source/__init__.py +0 -0
  221. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/id_source/list_id_source.py +0 -0
  222. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/id_source/match_id_source.py +0 -0
  223. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/input_groups/__init__.py +0 -0
  224. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/input_groups/get_input_group_names.py +0 -0
  225. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/__init__.py +0 -0
  226. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/create_inputs.py +0 -0
  227. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/get_input_data.py +0 -0
  228. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/get_input_names.py +0 -0
  229. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/get_inputs_data.py +0 -0
  230. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/set_input_attribute_values.py +0 -0
  231. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/set_input_category.py +0 -0
  232. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/set_input_subcategories.py +0 -0
  233. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/inputs/set_intermediate_type.py +0 -0
  234. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/integrations/__init__.py +0 -0
  235. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/integrations/publish_realtime_data.py +0 -0
  236. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/integrations/push_notification.py +0 -0
  237. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/integrations/register_sockets_token.py +0 -0
  238. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/listing/__init__.py +0 -0
  239. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/listing/export_listing.py +0 -0
  240. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/listing/fetch_listing.py +0 -0
  241. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/material_families/__init__.py +0 -0
  242. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/material_families/update_entity_material_families.py +0 -0
  243. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/notebooks/__init__.py +0 -0
  244. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/notebooks/add_notebook_content.py +0 -0
  245. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/notebooks/get_notebook_content.py +0 -0
  246. {uncountablepythonsdk-0.0.163/uncountable/types/api/outputs → uncountablepythonsdk-0.0.166/uncountable/types/api/output_parameters}/__init__.py +0 -0
  247. {uncountablepythonsdk-0.0.163/uncountable/types/api/permissions → uncountablepythonsdk-0.0.166/uncountable/types/api/outputs}/__init__.py +0 -0
  248. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/outputs/get_output_data.py +0 -0
  249. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/outputs/get_output_names.py +0 -0
  250. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/outputs/get_output_organization.py +0 -0
  251. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/outputs/resolve_output_conditions.py +0 -0
  252. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/outputs/update_output_condition_parameter.py +0 -0
  253. {uncountablepythonsdk-0.0.163/uncountable/types/api/project → uncountablepythonsdk-0.0.166/uncountable/types/api/permissions}/__init__.py +0 -0
  254. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/permissions/set_core_permissions.py +0 -0
  255. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/permissions/set_entity_permission.py +0 -0
  256. {uncountablepythonsdk-0.0.163/uncountable/types/api/recipe_links → uncountablepythonsdk-0.0.166/uncountable/types/api/project}/__init__.py +0 -0
  257. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/project/get_projects.py +0 -0
  258. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/project/get_projects_data.py +0 -0
  259. {uncountablepythonsdk-0.0.163/uncountable/types/api/recipe_metadata → uncountablepythonsdk-0.0.166/uncountable/types/api/recipe_links}/__init__.py +0 -0
  260. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipe_links/create_recipe_link.py +0 -0
  261. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipe_links/remove_recipe_link.py +0 -0
  262. {uncountablepythonsdk-0.0.163/uncountable/types/api/recipes → uncountablepythonsdk-0.0.166/uncountable/types/api/recipe_metadata}/__init__.py +0 -0
  263. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +0 -0
  264. {uncountablepythonsdk-0.0.163/uncountable/types/api/runsheet → uncountablepythonsdk-0.0.166/uncountable/types/api/recipes}/__init__.py +0 -0
  265. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/add_recipe_to_project.py +0 -0
  266. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/add_time_series_data.py +0 -0
  267. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/archive_recipes.py +0 -0
  268. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/associate_recipe_as_input.py +0 -0
  269. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/associate_recipe_as_lot.py +0 -0
  270. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/clear_recipe_outputs.py +0 -0
  271. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/create_mix_order.py +0 -0
  272. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/create_recipe.py +0 -0
  273. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/create_recipes.py +0 -0
  274. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/disassociate_recipe_as_input.py +0 -0
  275. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/edit_recipe_inputs.py +0 -0
  276. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/get_column_calculation_values.py +0 -0
  277. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/get_curve.py +0 -0
  278. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/get_recipe_calculations.py +0 -0
  279. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/get_recipe_links.py +0 -0
  280. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/get_recipe_names.py +0 -0
  281. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/get_recipe_output_metadata.py +0 -0
  282. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/get_recipes_data.py +0 -0
  283. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/lock_recipes.py +0 -0
  284. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/remove_recipe_from_project.py +0 -0
  285. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/set_recipe_inputs.py +0 -0
  286. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/set_recipe_metadata.py +0 -0
  287. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/set_recipe_output_annotations.py +0 -0
  288. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/set_recipe_output_file.py +0 -0
  289. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/set_recipe_outputs.py +0 -0
  290. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/set_recipe_tags.py +0 -0
  291. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/set_recipe_total.py +0 -0
  292. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/unarchive_recipes.py +0 -0
  293. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/unlock_recipes.py +0 -0
  294. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/upsert_recipe_workflow_step.py +0 -0
  295. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/recipes/upsert_step_relationships.py +0 -0
  296. {uncountablepythonsdk-0.0.163/uncountable/types/api/triggers → uncountablepythonsdk-0.0.166/uncountable/types/api/runsheet}/__init__.py +0 -0
  297. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/runsheet/complete_async_upload.py +0 -0
  298. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/runsheet/export_default_runsheet.py +0 -0
  299. {uncountablepythonsdk-0.0.163/uncountable/types/api/uploader → uncountablepythonsdk-0.0.166/uncountable/types/api/triggers}/__init__.py +0 -0
  300. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/triggers/run_trigger.py +0 -0
  301. {uncountablepythonsdk-0.0.163/uncountable/types/api/user → uncountablepythonsdk-0.0.166/uncountable/types/api/uploader}/__init__.py +0 -0
  302. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/uploader/complete_async_parse.py +0 -0
  303. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/uploader/invoke_uploader.py +0 -0
  304. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/api/user/get_current_user_info.py +0 -0
  305. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/async_batch.py +0 -0
  306. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/async_jobs.py +0 -0
  307. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/async_jobs_t.py +0 -0
  308. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/auth_retrieval.py +0 -0
  309. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/auth_retrieval_t.py +0 -0
  310. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/base.py +0 -0
  311. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/base_t.py +0 -0
  312. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/calculations.py +0 -0
  313. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/calculations_t.py +0 -0
  314. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/chemical_structure.py +0 -0
  315. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/chemical_structure_t.py +0 -0
  316. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/client_config.py +0 -0
  317. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/client_config_t.py +0 -0
  318. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/curves.py +0 -0
  319. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/curves_t.py +0 -0
  320. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/data.py +0 -0
  321. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/data_t.py +0 -0
  322. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/entity.py +0 -0
  323. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/experiment_groups.py +0 -0
  324. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/experiment_groups_t.py +0 -0
  325. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/exports.py +0 -0
  326. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/exports_t.py +0 -0
  327. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/field_values.py +0 -0
  328. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/field_values_t.py +0 -0
  329. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/fields.py +0 -0
  330. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/fields_t.py +0 -0
  331. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/generic_upload.py +0 -0
  332. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/generic_upload_t.py +0 -0
  333. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/id_source.py +0 -0
  334. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/id_source_t.py +0 -0
  335. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/identifier.py +0 -0
  336. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/identifier_t.py +0 -0
  337. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/input_attributes.py +0 -0
  338. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/input_attributes_t.py +0 -0
  339. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/inputs.py +0 -0
  340. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/inputs_t.py +0 -0
  341. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/integration_server.py +0 -0
  342. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/integration_server_t.py +0 -0
  343. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/integration_session.py +0 -0
  344. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/integration_session_t.py +0 -0
  345. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/integrations.py +0 -0
  346. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/integrations_t.py +0 -0
  347. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/job_definition.py +0 -0
  348. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/job_definition_t.py +0 -0
  349. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/listing.py +0 -0
  350. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/listing_t.py +0 -0
  351. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/notices.py +0 -0
  352. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/notices_t.py +0 -0
  353. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/notifications.py +0 -0
  354. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/notifications_t.py +0 -0
  355. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/outputs.py +0 -0
  356. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/outputs_t.py +0 -0
  357. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/overrides.py +0 -0
  358. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/overrides_t.py +0 -0
  359. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/permissions.py +0 -0
  360. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/permissions_t.py +0 -0
  361. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/phases.py +0 -0
  362. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/phases_t.py +0 -0
  363. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/post_base.py +0 -0
  364. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/post_base_t.py +0 -0
  365. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/queued_job.py +0 -0
  366. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/queued_job_t.py +0 -0
  367. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_identifiers.py +0 -0
  368. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_identifiers_t.py +0 -0
  369. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_inputs.py +0 -0
  370. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_inputs_t.py +0 -0
  371. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_links.py +0 -0
  372. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_links_t.py +0 -0
  373. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_metadata.py +0 -0
  374. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_metadata_t.py +0 -0
  375. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_output_metadata.py +0 -0
  376. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_output_metadata_t.py +0 -0
  377. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_step_relationships.py +0 -0
  378. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_step_relationships_t.py +0 -0
  379. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_tags.py +0 -0
  380. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_tags_t.py +0 -0
  381. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_workflow_step_types.py +0 -0
  382. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_workflow_step_types_t.py +0 -0
  383. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_workflow_steps.py +0 -0
  384. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipe_workflow_steps_t.py +0 -0
  385. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipes.py +0 -0
  386. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/recipes_t.py +0 -0
  387. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/response.py +0 -0
  388. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/response_t.py +0 -0
  389. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/runsheet.py +0 -0
  390. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/runsheet_format.py +0 -0
  391. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/runsheet_format_t.py +0 -0
  392. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/runsheet_t.py +0 -0
  393. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/secret_retrieval.py +0 -0
  394. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/secret_retrieval_t.py +0 -0
  395. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/sockets.py +0 -0
  396. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/sockets_t.py +0 -0
  397. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/specs.py +0 -0
  398. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/specs_t.py +0 -0
  399. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/step_relationships.py +0 -0
  400. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/step_relationships_t.py +0 -0
  401. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/units.py +0 -0
  402. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/units_t.py +0 -0
  403. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/uploader.py +0 -0
  404. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/uploader_t.py +0 -0
  405. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/users.py +0 -0
  406. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/users_t.py +0 -0
  407. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/webhook_job.py +0 -0
  408. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/webhook_job_t.py +0 -0
  409. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/workflows.py +0 -0
  410. {uncountablepythonsdk-0.0.163 → uncountablepythonsdk-0.0.166}/uncountable/types/workflows_t.py +0 -0
@@ -17,7 +17,7 @@ jobs:
17
17
  - name: Set up UV
18
18
  uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb
19
19
  with:
20
- version: "0.10.0"
20
+ version: "0.11.0"
21
21
  activate-environment: true
22
22
  enable-cache: true
23
23
  - name: Install dependencies
@@ -26,7 +26,7 @@ jobs:
26
26
  - name: Set up UV
27
27
  uses: astral-sh/setup-uv@f0ec1fc3b38f5e7cd731bb6ce540c5af426746bb
28
28
  with:
29
- version: "0.10.0"
29
+ version: "0.11.0"
30
30
  activate-environment: true
31
31
  enable-cache: true
32
32
  - name: Install build dependencies
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.163
3
+ Version: 0.0.166
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.163
3
+ Version: 0.0.166
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
@@ -259,6 +259,8 @@ uncountable/types/recipe_workflow_steps.py
259
259
  uncountable/types/recipe_workflow_steps_t.py
260
260
  uncountable/types/recipes.py
261
261
  uncountable/types/recipes_t.py
262
+ uncountable/types/request_headers.py
263
+ uncountable/types/request_headers_t.py
262
264
  uncountable/types/response.py
263
265
  uncountable/types/response_t.py
264
266
  uncountable/types/runsheet.py
@@ -343,6 +345,8 @@ uncountable/types/api/material_families/update_entity_material_families.py
343
345
  uncountable/types/api/notebooks/__init__.py
344
346
  uncountable/types/api/notebooks/add_notebook_content.py
345
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
346
350
  uncountable/types/api/outputs/__init__.py
347
351
  uncountable/types/api/outputs/get_output_data.py
348
352
  uncountable/types/api/outputs/get_output_names.py
@@ -9,7 +9,7 @@ dependencies = [
9
9
  "ruff == 0.*",
10
10
  "openpyxl == 3.*",
11
11
  "more_itertools == 10.*",
12
- "types-paramiko ==4.0.0.20250822",
12
+ "types-paramiko ==4.0.0.20260322",
13
13
  "types-openpyxl == 3.*",
14
14
  "types-pysftp == 0.*",
15
15
  "types-pytz ==2026.*",
@@ -11,6 +11,7 @@ from .argument_parser import is_union as is_union
11
11
  from .case_convert import camel_to_snake_case as camel_to_snake_case
12
12
  from .case_convert import kebab_to_pascal_case as kebab_to_pascal_case
13
13
  from .case_convert import snake_to_camel_case as snake_to_camel_case
14
+ from .parser_error import ParserEnumError as ParserEnumError
14
15
  from .parser_error import ParserError as ParserError
15
16
  from .parser_error import ParserExtraFieldsError as ParserExtraFieldsError
16
17
  from .parser_error import ParserTypeError as ParserTypeError
@@ -26,7 +26,12 @@ from pkgs.serialization import (
26
26
  from ._is_enum import is_string_enum_class
27
27
  from ._is_namedtuple import is_namedtuple_type
28
28
  from .case_convert import camel_to_snake_case, snake_to_camel_case
29
- from .parser_error import ParserError, ParserExtraFieldsError, ParserTypeError
29
+ from .parser_error import (
30
+ ParserEnumError,
31
+ ParserError,
32
+ ParserExtraFieldsError,
33
+ ParserTypeError,
34
+ )
30
35
 
31
36
  T = typing.TypeVar("T")
32
37
  ParserFunction = typing.Callable[[typing.Any], T]
@@ -500,9 +505,24 @@ def _build_parser_inner(
500
505
 
501
506
  return parse_as_numeric_type
502
507
 
503
- if parsed_type in (dict, bool) or is_string_enum_class(parsed_type):
508
+ if parsed_type in (dict, bool):
504
509
  return lambda value: parsed_type(value) # type: ignore
505
510
 
511
+ if is_string_enum_class(parsed_type):
512
+ assert issubclass(parsed_type, Enum)
513
+ enum_values: set[str] = set(member.value for member in parsed_type)
514
+
515
+ def parse_enum(value: typing.Any) -> T:
516
+ if not isinstance(value, str) or value not in enum_values:
517
+ raise ParserEnumError(
518
+ value=value,
519
+ enum_type=parsed_type,
520
+ valid_values=enum_values,
521
+ )
522
+ return parsed_type(value)
523
+
524
+ return parse_enum
525
+
506
526
  if parsed_type is MissingSentryType:
507
527
 
508
528
  def error(value: typing.Any) -> T:
@@ -1,8 +1,25 @@
1
1
  from __future__ import annotations
2
2
 
3
+ import reprlib
3
4
  import typing
4
5
 
5
6
  _UNSET = object()
7
+ _VALUE_REPR_MAX_LENGTH = 120
8
+
9
+
10
+ def _format_value(value: object) -> str:
11
+ value_repr = reprlib.Repr(
12
+ maxstring=_VALUE_REPR_MAX_LENGTH, maxother=_VALUE_REPR_MAX_LENGTH
13
+ ).repr(value)
14
+ if len(value_repr) <= _VALUE_REPR_MAX_LENGTH:
15
+ return value_repr
16
+ return f"{value_repr[: _VALUE_REPR_MAX_LENGTH - 3]}..."
17
+
18
+
19
+ def _format_message(message: str, value: object) -> str:
20
+ if value is _UNSET:
21
+ return message
22
+ return f"{message} (value: {_format_value(value)})"
6
23
 
7
24
 
8
25
  class ParserError(ValueError):
@@ -22,6 +39,9 @@ class ParserError(ValueError):
22
39
  self.field_name = field_name
23
40
  super().__init__(message)
24
41
 
42
+ def __str__(self) -> str:
43
+ return _format_message(self.error_message, self.value)
44
+
25
45
  def error_chain(self) -> list[ParserError]:
26
46
  errors: list[ParserError] = []
27
47
  current: BaseException | None = self
@@ -35,14 +55,14 @@ class ParserError(ValueError):
35
55
  current: BaseException | None = self
36
56
  while current is not None:
37
57
  if isinstance(current, ParserError):
38
- messages.append(current.error_message)
58
+ messages.append(_format_message(current.error_message, current.value))
39
59
  current = current.__cause__
40
60
  else:
41
61
  messages.append(str(current))
42
62
  break
43
63
 
44
64
  if len(messages) <= 1:
45
- return self.error_message
65
+ return _format_message(self.error_message, self.value)
46
66
 
47
67
  return " → ".join(messages)
48
68
 
@@ -57,4 +77,19 @@ class ParserExtraFieldsError(ParserError):
57
77
  )
58
78
 
59
79
 
80
+ class ParserEnumError(ParserError):
81
+ valid_values: set[str]
82
+
83
+ def __init__(
84
+ self,
85
+ *,
86
+ value: object,
87
+ enum_type: type,
88
+ valid_values: set[str],
89
+ ) -> None:
90
+ self.valid_values = valid_values
91
+ message = f"'{value}' is not a valid string enum of type {enum_type.__name__}."
92
+ super().__init__(message, value=value, expected_type=enum_type)
93
+
94
+
60
95
  class ParserTypeError(ParserError): ...
@@ -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
@@ -24,13 +24,12 @@ from uncountable.types import download_file_t
24
24
  from uncountable.types.client_base import APIRequest, ClientMethods
25
25
  from uncountable.types.client_config import ClientConfigOptions
26
26
  from uncountable.types.client_config_t import RequestContext
27
+ from uncountable.types.request_headers_t import InternalRequestHeaders, VersionHeaders
27
28
 
28
29
  from .file_upload import FileUpload, FileUploader, UploadedFile
29
30
  from .types import AuthDetailsAll, AuthDetailsApiKey, AuthDetailsOAuth
30
31
 
31
32
  DT = typing.TypeVar("DT")
32
- UNC_REQUEST_ID_HEADER = "X-UNC-REQUEST-ID"
33
- UNC_SDK_VERSION_HEADER = "X-UNC-SDK-VERSION"
34
33
 
35
34
 
36
35
  class EndpointMethod(StrEnum):
@@ -328,8 +327,8 @@ class Client(ClientMethods):
328
327
  self, *, api_request: APIRequest, request_id: str
329
328
  ) -> HTTPRequest:
330
329
  headers = self._build_auth_headers()
331
- headers[UNC_REQUEST_ID_HEADER] = request_id
332
- headers[UNC_SDK_VERSION_HEADER] = get_version()
330
+ headers[InternalRequestHeaders.REQUEST_ID] = request_id
331
+ headers[VersionHeaders.UNC_SDK_VERSION] = get_version()
333
332
  if self._cfg.request_context is not None:
334
333
  if self._cfg.request_context.user_locale is not None:
335
334
  headers["X-User-Locale"] = self._cfg.request_context.user_locale
@@ -30,34 +30,28 @@ def _construct_auth_details(profile_meta: ProfileMetadata) -> AuthDetailsAll:
30
30
  return AuthDetailsApiKey(api_id=api_id, api_secret_key=api_key)
31
31
 
32
32
 
33
- def _construct_client_config(
34
- *,
35
- profile_meta: ProfileMetadata,
36
- job_logger: JobLogger,
37
- request_context: RequestContext | None = None,
38
- ) -> ClientConfig:
39
- if profile_meta.client_options is None:
40
- return ClientConfig(logger=job_logger, request_context=request_context)
41
- return ClientConfig(
42
- allow_insecure_tls=profile_meta.client_options.allow_insecure_tls,
43
- extra_headers=profile_meta.client_options.extra_headers,
44
- logger=job_logger,
45
- request_context=request_context,
46
- )
47
-
48
-
49
33
  def construct_uncountable_client(
50
34
  profile_meta: ProfileMetadata,
51
35
  logger: JobLogger,
52
36
  *,
53
37
  request_context: RequestContext | None = None,
38
+ headers: dict[str, str] | None = None,
54
39
  ) -> Client:
40
+ extra_headers = {}
41
+ allow_insecure_tls = False
42
+ if profile_meta.client_options is not None:
43
+ extra_headers.update(profile_meta.client_options.extra_headers or {})
44
+ allow_insecure_tls = profile_meta.client_options.allow_insecure_tls
45
+
46
+ extra_headers.update(headers or {})
47
+
55
48
  return Client(
56
49
  base_url=profile_meta.base_url,
57
50
  auth_details=_construct_auth_details(profile_meta),
58
- config=_construct_client_config(
59
- profile_meta=profile_meta,
60
- job_logger=logger,
51
+ config=ClientConfig(
52
+ allow_insecure_tls=allow_insecure_tls,
53
+ extra_headers=extra_headers,
54
+ logger=logger,
61
55
  request_context=request_context,
62
56
  ),
63
57
  app_base_url=profile_meta.app_base_url,
@@ -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
@@ -23,7 +25,13 @@ from uncountable.integration.queue_runner.datastore.interface import Datastore
23
25
  from uncountable.integration.queue_runner.types import ListenQueue, ResultQueue
24
26
  from uncountable.integration.scan_profiles import load_profiles
25
27
  from uncountable.integration.telemetry import JobLogger, Logger, get_otel_tracer
26
- from uncountable.types import base_t, client_config_t, job_definition_t, queued_job_t
28
+ from uncountable.types import (
29
+ base_t,
30
+ client_config_t,
31
+ job_definition_t,
32
+ queued_job_t,
33
+ request_headers_t,
34
+ )
27
35
 
28
36
 
29
37
  class Worker:
@@ -99,14 +107,48 @@ def _resolve_queued_job_request_context(
99
107
  return None
100
108
 
101
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
+
102
135
  def run_queued_job(
103
136
  queued_job: queued_job_t.QueuedJob,
104
137
  ) -> job_definition_t.JobResult:
105
138
  with get_otel_tracer().start_as_current_span(name="run_queued_job") as span:
106
139
  if resource is not None:
107
- total_mem = psutil.virtual_memory().total
108
- 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)
109
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
+ )
110
152
 
111
153
  job_details = get_registered_job_details(queued_job.job_ref_name)
112
154
  job_logger = JobLogger(
@@ -123,6 +165,11 @@ def run_queued_job(
123
165
  profile_meta=job_details.profile_metadata,
124
166
  logger=job_logger,
125
167
  request_context=request_context,
168
+ headers={
169
+ request_headers_t.IntegrationServerHeaders.JOB_UUID: queued_job.queued_job_uuid,
170
+ request_headers_t.IntegrationServerHeaders.JOB_ID: job_details.job_definition.id,
171
+ request_headers_t.IntegrationServerHeaders.JOB_NAME: job_details.job_definition.name,
172
+ },
126
173
  )
127
174
  batch_processor = AsyncBatchProcessor(client=client)
128
175
 
@@ -220,9 +220,15 @@ class Logger:
220
220
 
221
221
 
222
222
  class PerJobResourceTracker:
223
- def __init__(self, logger: "JobLogger", sample_interval: float = 0.5) -> None:
223
+ def __init__(
224
+ self,
225
+ logger: "JobLogger",
226
+ sample_interval: float = 0.5,
227
+ log_interval: float = 30.0,
228
+ ) -> None:
224
229
  self.logger = logger
225
230
  self.sample_interval = sample_interval
231
+ self.log_interval = log_interval
226
232
  self._process = psutil.Process(os.getpid())
227
233
  self._stop_event = threading.Event()
228
234
  self._thread: threading.Thread | None = None
@@ -233,15 +239,40 @@ class PerJobResourceTracker:
233
239
  self.start_wall_time: float | None = None
234
240
  self.end_wall_time: float | None = None
235
241
 
242
+ def _current_stats(self) -> Attributes:
243
+ assert self.start_cpu_times is not None
244
+ assert self.start_wall_time is not None
245
+ current_cpu_times = self._process.cpu_times()
246
+ cpu_user = current_cpu_times.user - self.start_cpu_times.user
247
+ cpu_sys = current_cpu_times.system - self.start_cpu_times.system
248
+ cpu_total = cpu_user + cpu_sys
249
+ elapsed = time.monotonic() - self.start_wall_time
250
+ return {
251
+ "cpu_user_s": round(cpu_user, 3),
252
+ "cpu_system_s": round(cpu_sys, 3),
253
+ "cpu_total_s": round(cpu_total, 3),
254
+ "wall_time_s": round(elapsed, 3),
255
+ "current_rss_mb": round(self._process.memory_info().rss / (1024 * 1024), 2),
256
+ "peak_rss_mb": round(self.max_rss / (1024 * 1024), 2),
257
+ }
258
+
236
259
  def start(self) -> None:
237
260
  self.start_cpu_times = self._process.cpu_times()
238
261
  self.start_wall_time = time.monotonic()
239
262
 
240
263
  def _monitor() -> None:
264
+ last_log_time = time.monotonic()
241
265
  try:
242
266
  while not self._stop_event.is_set():
243
267
  rss = self._process.memory_info().rss
244
268
  self.max_rss = max(self.max_rss, rss)
269
+ now = time.monotonic()
270
+ if now - last_log_time >= self.log_interval:
271
+ self.logger.log_info(
272
+ "Job resource usage (periodic)",
273
+ attributes=self._current_stats(),
274
+ )
275
+ last_log_time = now
245
276
  time.sleep(self.sample_interval)
246
277
  except Exception:
247
278
  self._stop_event.set()
@@ -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_info(
95
+ f"job {job.id} webhook registered at: {route}", attributes=log_attributes
96
+ )
73
97
 
74
98
 
75
99
  def main() -> None:
@@ -108,6 +108,7 @@ from . import recipes_t as recipes_t
108
108
  from .api.integrations import register_sockets_token as register_sockets_token_t
109
109
  from .api.recipes import remove_recipe_from_project as remove_recipe_from_project_t
110
110
  from .api.recipe_links import remove_recipe_link as remove_recipe_link_t
111
+ from . import request_headers_t as request_headers_t
111
112
  from .api.entity import resolve_entity_ids as resolve_entity_ids_t
112
113
  from .api.outputs import resolve_output_conditions as resolve_output_conditions_t
113
114
  from . import response_t as response_t
@@ -134,6 +135,7 @@ from .api.entity import set_values as set_values_t
134
135
  from . import sockets_t as sockets_t
135
136
  from . import specs_t as specs_t
136
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
137
139
  from .api.entity import transition_entity_phase as transition_entity_phase_t
138
140
  from .api.recipes import unarchive_recipes as unarchive_recipes_t
139
141
  from . import units_t as units_t
@@ -258,6 +260,7 @@ __all__: list[str] = [
258
260
  "register_sockets_token_t",
259
261
  "remove_recipe_from_project_t",
260
262
  "remove_recipe_link_t",
263
+ "request_headers_t",
261
264
  "resolve_entity_ids_t",
262
265
  "resolve_output_conditions_t",
263
266
  "response_t",
@@ -284,6 +287,7 @@ __all__: list[str] = [
284
287
  "sockets_t",
285
288
  "specs_t",
286
289
  "step_relationships_t",
290
+ "swap_output_condition_parameters_t",
287
291
  "transition_entity_phase_t",
288
292
  "unarchive_recipes_t",
289
293
  "units_t",