UncountablePythonSDK 0.0.68__tar.gz → 0.0.69__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 (271) hide show
  1. uncountablepythonsdk-0.0.69/Dockerfile.testing +19 -0
  2. {uncountablepythonsdk-0.0.68/UncountablePythonSDK.egg-info → uncountablepythonsdk-0.0.69}/PKG-INFO +1 -1
  3. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69/UncountablePythonSDK.egg-info}/PKG-INFO +1 -1
  4. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/UncountablePythonSDK.egg-info/SOURCES.txt +8 -0
  5. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/requirements.txt +1 -1
  6. uncountablepythonsdk-0.0.69/examples/integration-server/jobs/materials_auto/example_cron.py +18 -0
  7. uncountablepythonsdk-0.0.69/examples/integration-server/jobs/materials_auto/profile.yaml +19 -0
  8. uncountablepythonsdk-0.0.69/examples/integration-server/pyproject.toml +224 -0
  9. uncountablepythonsdk-0.0.69/examples/set_recipe_metadata_file.py +40 -0
  10. uncountablepythonsdk-0.0.69/examples/set_recipe_output_file_sdk.py +26 -0
  11. uncountablepythonsdk-0.0.69/uncountable/integration/scheduler.py +107 -0
  12. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/webhook_server/entrypoint.py +20 -16
  13. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/__init__.py +2 -0
  14. uncountablepythonsdk-0.0.69/uncountable/types/api/recipes/set_recipe_output_file.py +46 -0
  15. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/client_base.py +20 -0
  16. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/entity_t.py +2 -0
  17. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_metadata_t.py +1 -0
  18. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/.github/workflows/documentation.yml +0 -0
  19. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/.github/workflows/publish.yml +0 -0
  20. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/.gitignore +0 -0
  21. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/README.md +0 -0
  22. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/UncountablePythonSDK.egg-info/dependency_links.txt +0 -0
  23. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/UncountablePythonSDK.egg-info/requires.txt +0 -0
  24. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/UncountablePythonSDK.egg-info/top_level.txt +0 -0
  25. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/.gitignore +0 -0
  26. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/conf.py +0 -0
  27. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/index.md +0 -0
  28. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/justfile +0 -0
  29. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/quickstart.md +0 -0
  30. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/android-chrome-192x192.png +0 -0
  31. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/android-chrome-512x512.png +0 -0
  32. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/apple-touch-icon.png +0 -0
  33. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/browserconfig.xml +0 -0
  34. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/favicon-16x16.png +0 -0
  35. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/favicon-32x32.png +0 -0
  36. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/manifest.json +0 -0
  37. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/mstile-150x150.png +0 -0
  38. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/favicons/safari-pinned-tab.svg +0 -0
  39. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/docs/static/logo_blue.png +0 -0
  40. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/examples/async_batch.py +0 -0
  41. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/examples/create_entity.py +0 -0
  42. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/examples/edit_recipe_inputs.py +0 -0
  43. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/examples/invoke_uploader.py +0 -0
  44. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/examples/upload_files.py +0 -0
  45. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/__init__.py +0 -0
  46. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/argument_parser/__init__.py +0 -0
  47. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/argument_parser/_is_enum.py +0 -0
  48. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/argument_parser/_is_namedtuple.py +0 -0
  49. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/argument_parser/argument_parser.py +0 -0
  50. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/argument_parser/case_convert.py +0 -0
  51. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/filesystem_utils/__init__.py +0 -0
  52. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/filesystem_utils/_gdrive_session.py +0 -0
  53. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/filesystem_utils/_local_session.py +0 -0
  54. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/filesystem_utils/_s3_session.py +0 -0
  55. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/filesystem_utils/_sftp_session.py +0 -0
  56. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/filesystem_utils/file_type_utils.py +0 -0
  57. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/filesystem_utils/filesystem_session.py +0 -0
  58. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/py.typed +0 -0
  59. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization/__init__.py +0 -0
  60. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization/missing_sentry.py +0 -0
  61. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization/opaque_key.py +0 -0
  62. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization/serial_class.py +0 -0
  63. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization/serial_union.py +0 -0
  64. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization/yaml.py +0 -0
  65. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization_util/__init__.py +0 -0
  66. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization_util/_get_type_for_serialization.py +0 -0
  67. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization_util/convert_to_snakecase.py +0 -0
  68. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/serialization_util/serialization_helpers.py +0 -0
  69. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/strenum_compat/__init__.py +0 -0
  70. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/strenum_compat/strenum_compat.py +0 -0
  71. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/__init__.py +0 -0
  72. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/__main__.py +0 -0
  73. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/actions_registry/__init__.py +0 -0
  74. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/actions_registry/__main__.py +0 -0
  75. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/actions_registry/emit_typescript.py +0 -0
  76. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/builder.py +0 -0
  77. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/config.py +0 -0
  78. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/emit_io_ts.py +0 -0
  79. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/emit_open_api.py +0 -0
  80. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/emit_open_api_util.py +0 -0
  81. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/emit_python.py +0 -0
  82. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/emit_typescript.py +0 -0
  83. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/emit_typescript_util.py +0 -0
  84. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/load_types.py +0 -0
  85. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/open_api_util.py +0 -0
  86. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/parts/base.py.prepart +0 -0
  87. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/parts/base.ts.prepart +0 -0
  88. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/test.py +0 -0
  89. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/type_info/__main__.py +0 -0
  90. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/type_info/emit_type_info.py +0 -0
  91. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/util.py +0 -0
  92. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/value_spec/__init__.py +0 -0
  93. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/value_spec/__main__.py +0 -0
  94. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/value_spec/convert_type.py +0 -0
  95. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/value_spec/emit_python.py +0 -0
  96. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pkgs/type_spec/value_spec/types.py +0 -0
  97. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/pyproject.toml +0 -0
  98. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/setup.cfg +0 -0
  99. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/__init__.py +0 -0
  100. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/core/__init__.py +0 -0
  101. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/core/async_batch.py +0 -0
  102. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/core/client.py +0 -0
  103. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/core/environment.py +0 -0
  104. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/core/file_upload.py +0 -0
  105. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/core/types.py +0 -0
  106. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/__init__.py +0 -0
  107. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/cli.py +0 -0
  108. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/construct_client.py +0 -0
  109. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/cron.py +0 -0
  110. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/db/__init__.py +0 -0
  111. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/db/connect.py +0 -0
  112. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/entrypoint.py +0 -0
  113. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/executors/__init__.py +0 -0
  114. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/executors/executors.py +0 -0
  115. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/executors/generic_upload_executor.py +0 -0
  116. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/executors/script_executor.py +0 -0
  117. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/job.py +0 -0
  118. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/scan_profiles.py +0 -0
  119. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/secret_retrieval/__init__.py +0 -0
  120. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/secret_retrieval/retrieve_secret.py +0 -0
  121. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/server.py +0 -0
  122. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/integration/telemetry.py +0 -0
  123. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/py.typed +0 -0
  124. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/__init__.py +0 -0
  125. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/batch/__init__.py +0 -0
  126. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/batch/execute_batch.py +0 -0
  127. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/batch/execute_batch_load_async.py +0 -0
  128. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/chemical/__init__.py +0 -0
  129. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/chemical/convert_chemical_formats.py +0 -0
  130. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/__init__.py +0 -0
  131. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/create_entities.py +0 -0
  132. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/create_entity.py +0 -0
  133. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/get_entities_data.py +0 -0
  134. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/list_entities.py +0 -0
  135. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/lock_entity.py +0 -0
  136. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/resolve_entity_ids.py +0 -0
  137. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/set_values.py +0 -0
  138. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/transition_entity_phase.py +0 -0
  139. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/entity/unlock_entity.py +0 -0
  140. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/equipment/__init__.py +0 -0
  141. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/equipment/associate_equipment_input.py +0 -0
  142. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/field_options/__init__.py +0 -0
  143. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/field_options/upsert_field_options.py +0 -0
  144. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/id_source/__init__.py +0 -0
  145. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/id_source/list_id_source.py +0 -0
  146. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/id_source/match_id_source.py +0 -0
  147. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/input_groups/__init__.py +0 -0
  148. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/input_groups/get_input_group_names.py +0 -0
  149. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/__init__.py +0 -0
  150. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/create_inputs.py +0 -0
  151. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/get_input_data.py +0 -0
  152. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/get_input_names.py +0 -0
  153. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/get_inputs_data.py +0 -0
  154. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/set_input_attribute_values.py +0 -0
  155. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/set_input_category.py +0 -0
  156. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/set_input_subcategories.py +0 -0
  157. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/inputs/set_intermediate_type.py +0 -0
  158. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/material_families/__init__.py +0 -0
  159. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/material_families/update_entity_material_families.py +0 -0
  160. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/outputs/__init__.py +0 -0
  161. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/outputs/get_output_data.py +0 -0
  162. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/outputs/get_output_names.py +0 -0
  163. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/outputs/resolve_output_conditions.py +0 -0
  164. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/permissions/__init__.py +0 -0
  165. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/permissions/set_core_permissions.py +0 -0
  166. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/project/__init__.py +0 -0
  167. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/project/get_projects.py +0 -0
  168. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/project/get_projects_data.py +0 -0
  169. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipe_links/__init__.py +0 -0
  170. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipe_links/create_recipe_link.py +0 -0
  171. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipe_links/remove_recipe_link.py +0 -0
  172. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipe_metadata/__init__.py +0 -0
  173. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +0 -0
  174. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/__init__.py +0 -0
  175. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/add_recipe_to_project.py +0 -0
  176. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/archive_recipes.py +0 -0
  177. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/associate_recipe_as_input.py +0 -0
  178. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/associate_recipe_as_lot.py +0 -0
  179. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/clear_recipe_outputs.py +0 -0
  180. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/create_recipe.py +0 -0
  181. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/create_recipes.py +0 -0
  182. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/disassociate_recipe_as_input.py +0 -0
  183. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/edit_recipe_inputs.py +0 -0
  184. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/get_curve.py +0 -0
  185. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/get_recipe_calculations.py +0 -0
  186. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/get_recipe_links.py +0 -0
  187. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/get_recipe_names.py +0 -0
  188. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/get_recipe_output_metadata.py +0 -0
  189. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/get_recipes_data.py +0 -0
  190. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/lock_recipes.py +0 -0
  191. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/remove_recipe_from_project.py +0 -0
  192. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/set_recipe_inputs.py +0 -0
  193. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/set_recipe_metadata.py +0 -0
  194. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/set_recipe_output_annotations.py +0 -0
  195. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/set_recipe_outputs.py +0 -0
  196. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/set_recipe_tags.py +0 -0
  197. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/unarchive_recipes.py +0 -0
  198. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/recipes/unlock_recipes.py +0 -0
  199. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/triggers/__init__.py +0 -0
  200. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/triggers/run_trigger.py +0 -0
  201. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/uploader/__init__.py +0 -0
  202. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/api/uploader/invoke_uploader.py +0 -0
  203. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/async_batch.py +0 -0
  204. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/async_batch_processor.py +0 -0
  205. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/async_batch_t.py +0 -0
  206. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/base.py +0 -0
  207. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/base_t.py +0 -0
  208. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/calculations.py +0 -0
  209. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/calculations_t.py +0 -0
  210. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/chemical_structure.py +0 -0
  211. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/chemical_structure_t.py +0 -0
  212. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/client_config.py +0 -0
  213. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/client_config_t.py +0 -0
  214. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/curves.py +0 -0
  215. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/curves_t.py +0 -0
  216. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/entity.py +0 -0
  217. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/experiment_groups.py +0 -0
  218. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/experiment_groups_t.py +0 -0
  219. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/field_values.py +0 -0
  220. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/field_values_t.py +0 -0
  221. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/fields.py +0 -0
  222. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/fields_t.py +0 -0
  223. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/generic_upload.py +0 -0
  224. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/generic_upload_t.py +0 -0
  225. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/id_source.py +0 -0
  226. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/id_source_t.py +0 -0
  227. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/identifier.py +0 -0
  228. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/identifier_t.py +0 -0
  229. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/input_attributes.py +0 -0
  230. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/input_attributes_t.py +0 -0
  231. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/inputs.py +0 -0
  232. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/inputs_t.py +0 -0
  233. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/job_definition.py +0 -0
  234. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/job_definition_t.py +0 -0
  235. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/outputs.py +0 -0
  236. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/outputs_t.py +0 -0
  237. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/overrides.py +0 -0
  238. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/overrides_t.py +0 -0
  239. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/permissions.py +0 -0
  240. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/permissions_t.py +0 -0
  241. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/phases.py +0 -0
  242. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/phases_t.py +0 -0
  243. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/post_base.py +0 -0
  244. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/post_base_t.py +0 -0
  245. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_identifiers.py +0 -0
  246. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_identifiers_t.py +0 -0
  247. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_inputs.py +0 -0
  248. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_inputs_t.py +0 -0
  249. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_links.py +0 -0
  250. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_links_t.py +0 -0
  251. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_metadata.py +0 -0
  252. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_output_metadata.py +0 -0
  253. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_output_metadata_t.py +0 -0
  254. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_tags.py +0 -0
  255. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_tags_t.py +0 -0
  256. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_workflow_steps.py +0 -0
  257. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipe_workflow_steps_t.py +0 -0
  258. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipes.py +0 -0
  259. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/recipes_t.py +0 -0
  260. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/response.py +0 -0
  261. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/response_t.py +0 -0
  262. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/secret_retrieval.py +0 -0
  263. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/secret_retrieval_t.py +0 -0
  264. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/units.py +0 -0
  265. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/units_t.py +0 -0
  266. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/users.py +0 -0
  267. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/users_t.py +0 -0
  268. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/webhook_job.py +0 -0
  269. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/webhook_job_t.py +0 -0
  270. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/workflows.py +0 -0
  271. {uncountablepythonsdk-0.0.68 → uncountablepythonsdk-0.0.69}/uncountable/types/workflows_t.py +0 -0
@@ -0,0 +1,19 @@
1
+ ARG BASE_IMAGE_TAG
2
+
3
+ FROM 502071203139.dkr.ecr.us-west-2.amazonaws.com/uncountable/integrations/integration-server-base:$BASE_IMAGE_TAG
4
+
5
+ ENV SETUPTOOLS_SCM_PRETEND_VERSION_FOR_UNCOUNTABLEPYTHONSDK=0
6
+
7
+ RUN mkdir sdk_local
8
+ COPY ./pyproject.toml sdk_local/
9
+ RUN python -m pip install sdk_local/
10
+
11
+ COPY ./examples/integration-server/pyproject.toml .
12
+ RUN python -m pip install .
13
+
14
+ ADD ./examples/integration-server/ .
15
+
16
+ COPY ./uncountable uncountable
17
+
18
+ ENV UNC_PROFILES_MODULE=jobs
19
+ ENV UNC_SQLITE_URI=sqlite:////data/sqlite.db
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.68
3
+ Version: 0.0.69
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.1
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.68
3
+ Version: 0.0.69
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,4 +1,5 @@
1
1
  .gitignore
2
+ Dockerfile.testing
2
3
  README.md
3
4
  pyproject.toml
4
5
  .github/workflows/documentation.yml
@@ -28,7 +29,12 @@ examples/async_batch.py
28
29
  examples/create_entity.py
29
30
  examples/edit_recipe_inputs.py
30
31
  examples/invoke_uploader.py
32
+ examples/set_recipe_metadata_file.py
33
+ examples/set_recipe_output_file_sdk.py
31
34
  examples/upload_files.py
35
+ examples/integration-server/pyproject.toml
36
+ examples/integration-server/jobs/materials_auto/example_cron.py
37
+ examples/integration-server/jobs/materials_auto/profile.yaml
32
38
  pkgs/__init__.py
33
39
  pkgs/py.typed
34
40
  pkgs/argument_parser/__init__.py
@@ -96,6 +102,7 @@ uncountable/integration/cron.py
96
102
  uncountable/integration/entrypoint.py
97
103
  uncountable/integration/job.py
98
104
  uncountable/integration/scan_profiles.py
105
+ uncountable/integration/scheduler.py
99
106
  uncountable/integration/server.py
100
107
  uncountable/integration/telemetry.py
101
108
  uncountable/integration/db/__init__.py
@@ -251,6 +258,7 @@ uncountable/types/api/recipes/remove_recipe_from_project.py
251
258
  uncountable/types/api/recipes/set_recipe_inputs.py
252
259
  uncountable/types/api/recipes/set_recipe_metadata.py
253
260
  uncountable/types/api/recipes/set_recipe_output_annotations.py
261
+ uncountable/types/api/recipes/set_recipe_output_file.py
254
262
  uncountable/types/api/recipes/set_recipe_outputs.py
255
263
  uncountable/types/api/recipes/set_recipe_tags.py
256
264
  uncountable/types/api/recipes/unarchive_recipes.py
@@ -1,6 +1,6 @@
1
1
  furo==2024.8.6
2
2
  myst-parser==4.0.0
3
- sphinx-autoapi==3.2.0
3
+ sphinx-autoapi==3.3.0
4
4
  sphinx-copybutton==0.5.2
5
5
  Sphinx==8.0.0
6
6
  sphinx_design==0.6.1
@@ -0,0 +1,18 @@
1
+ from uncountable.integration.job import CronJob, CronJobArguments, register_job
2
+ from uncountable.types import entity_t
3
+ from uncountable.types.job_definition_t import JobResult
4
+
5
+
6
+ @register_job
7
+ class MyCronJob(CronJob):
8
+ def run(self, args: CronJobArguments) -> JobResult:
9
+ matfam = args.client.get_entities_data(
10
+ entity_ids=[1],
11
+ entity_type=entity_t.EntityType.MATERIAL_FAMILY,
12
+ ).entity_details[0]
13
+ name = None
14
+ for field_val in matfam.field_values:
15
+ if field_val.field_ref_name == "name":
16
+ name = field_val.value
17
+ args.logger.log_info(f"material family found with name: {name}")
18
+ return JobResult(success=True)
@@ -0,0 +1,19 @@
1
+ base_url: http://0.0.0.0:5000
2
+ auth_retrieval:
3
+ type: basic
4
+ api_id_secret:
5
+ type: env
6
+ env_key: API_ID
7
+ api_key_secret:
8
+ type: env
9
+ env_key: API_SECRET_KEY
10
+ jobs:
11
+ - id: example_cron
12
+ enabled: true
13
+ type: cron
14
+ name: MyCron - Example
15
+ cron_spec: "* * * * *"
16
+ executor:
17
+ type: script
18
+ import_path: example_cron
19
+
@@ -0,0 +1,224 @@
1
+ [project]
2
+ # begin_project_name
3
+ # DO NOT MODIFY
4
+ name = "integration-server-testing"
5
+ # end_project_name
6
+ dynamic = ["version"]
7
+ dependencies = [
8
+ "mypy == 1.*",
9
+ "ruff == 0.*",
10
+ "openpyxl == 3.*",
11
+ "more_itertools == 10.*",
12
+ "types-paramiko == 3.4.0.20240423",
13
+ "types-openpyxl == 3.*",
14
+ "types-pysftp == 0.*",
15
+ "types-pytz == 2024.*",
16
+ "types-requests == 2.*",
17
+ "types-simplejson == 3.*",
18
+ "pandas-stubs",
19
+ "xlrd == 2.*"
20
+ ]
21
+
22
+ [tool.mypy]
23
+ strict = true
24
+ show_error_codes = true
25
+ check_untyped_defs = true
26
+ disallow_any_generics = false
27
+ disallow_incomplete_defs = true
28
+ disallow_subclassing_any = false
29
+ disallow_untyped_calls = false
30
+ disallow_untyped_decorators = true
31
+ disallow_untyped_defs = true
32
+ implicit_reexport = true
33
+ no_implicit_optional = true
34
+ no_implicit_reexport = true
35
+ strict_equality = true
36
+ warn_redundant_casts = true
37
+ warn_unused_ignores = false
38
+ warn_no_return = true
39
+ warn_return_any = true
40
+ local_partial_types = true
41
+ warn_unreachable = false
42
+ warn_unused_configs = true
43
+ exclude = [
44
+ "env"
45
+ ]
46
+
47
+ [tool.ruff]
48
+ preview = true
49
+ lint.select = ['ALL']
50
+ lint.ignore = [
51
+ "A001", # Variable shadows python built-in. Nice to have
52
+ "A002", # Variable shadows python built-in. Nice to have
53
+ "A003", # Class attribute shadows python built-in. Nice to have
54
+ "ANN", # Missing type annotations. Skip in favor of mypy
55
+ "ARG", # Unused arguments. Skip
56
+ "B006", # Do not use mutable data structures for argument defaults. Priority.
57
+ "B023", # Function doesn't bind loop variable. Priority
58
+ "B904", # Exception handling raise from. Skip
59
+ "BLE", # Blind exception. Should Add
60
+ "C401", # Unecessary generator. Skip
61
+ "C403", # Unnecessary list comprehension. Skip
62
+ "C405", # Unnecessary list. rewrite as set. Skip
63
+ "C408", # Unnecessary dict call. Skip
64
+ "C416", # Unnecessary list comprehension. Skip
65
+ "C417", # Unnecessary use of map. Should Add
66
+ "COM812", # Trailing comma. Too opinionated. Skip
67
+ "CPY", # Copyright notices. Skip
68
+ "D", # Docstrings. Skip
69
+ "DOC", # Docstrings. Skip
70
+ "DTZ001", # Missing tzinfo. Should add
71
+ "DTZ002", # Use of today instead of now. Should add
72
+ "DTZ003", # Use of utcnow not allowed. Should add
73
+ "DTZ004", # Use of utcfrom timestamp not allowed. Should add
74
+ "DTZ005", # now without tz not allowed. Should add
75
+ "DTZ006", # use of from timestamp without tz not allowed. Should add
76
+ "DTZ007", # replace timezone after strptime. Should add
77
+ "DTZ011", # Use of today not allowed. Should add
78
+ "E501", # Line length. Skip
79
+ "EM101", # exception must not use a string literal. skip
80
+ "EM102", # exception must not use an f string. skip
81
+ "EM103", # exception must not use a format string. skip
82
+ "ERA", # Rules around commented code. Skip
83
+ "EXE002", # Executable files need shebang. Skip
84
+ "F841", # TEMPORARY DISABLE TO CLEAR UP BUILD. Unused variables. Prioritize.
85
+ "FBT001", # boolean positional args. Skip
86
+ "FBT002", # boolean default positional. Skip
87
+ "FBT003", # boolean positional. Skip
88
+ "FIX001", # Fixme comment. Skip
89
+ "FIX002", # todo comment. Skip
90
+ "FIX004", # hack comment. Skip
91
+ "FLY002", # Use F-String instead of join. Should Add
92
+ "FURB101", # replace read function. Skip
93
+ "FURB103", # opinionated file opening. Skip
94
+ "FURB113", # extend vs append. Skip
95
+ "FURB118", # opinionated rules about lambdas. skip
96
+ "FURB140", # starmap vs generator. Skip
97
+ "G004", # avoid f strings in log statements. Should add
98
+ "INP001", # implicit imports. use __init__. Skip
99
+ "ISC001", # rule conflicts with formatter. Skip
100
+ "ISC003", # Explicitly concatenated string should be implicitly concatenated. Skip
101
+ "N801", # class name case. Skip
102
+ "N802", # function name lower case. Skip
103
+ "N803", # argument name lower cas. Skip
104
+ "N804", # cls_ first variable. Should add
105
+ "N806", # lower case variable. Skip
106
+ "N812", # case consistency on import. Skip
107
+ "N815", # mix casing, skip
108
+ "N817", # don't use acronym. Should add
109
+ "N818", # exception override should be named with error. should add
110
+ "N999", # module naming. Should add
111
+ "PD002", # avoid inplace. Skip
112
+ "PD004", # .notna. Should add
113
+ "PD010", # .pivottable. Should add
114
+ "PD011", # use .to_numpy. Skip
115
+ "PD015", # use .merge. Should add
116
+ "PD901", # avoid generic df name. Skip
117
+ "PERF203", # avoid try except in loop. Skip
118
+ "PERF401", # use list comprehension. Skip
119
+ "PERF402", # use list.copy. Skip
120
+ "PERF403", # use dictionary comprehension. Skip
121
+ "S307", # avoid eval. Should add
122
+ "PGH003", # ignore specific rules. Skip
123
+ "PGH004", # ignore specific rules. Skip
124
+ "PLC0414", # import alias doesn't rename. Skip
125
+ "PLC0415", # import at top level. Skip
126
+ "PLC1901", # falsy empty string. Skip
127
+ "PLR0124", # self comparison. Skip
128
+ "PLR0402", # alias import. Skip
129
+ "PLR0911", # too many return statements. Skip
130
+ "PLR0912", # too many branches. Skip
131
+ "PLR0913", # too many arguments. Skip
132
+ "PLR0915", # too many statements. Skip
133
+ "PLR0916", # too many expressions. Skip
134
+ "PLR0917", # too many positional arguments. Skip
135
+ "PLR1714", # multiple comparisons. Skip
136
+ "PLR2004", # magic values. skip
137
+ "PLR5501", # use elif instead of else if. skip
138
+ "PLR6104", # use augmented assignment. confuses strings, wait for fix. skip
139
+ "PLR6201", # use a set literal for membership test. skip
140
+ "PLR6301", # method inference. skip
141
+ "PLW0108", # inline lambda. skip
142
+ "PLW0120", # else without break. skip
143
+ "PLW0602", # global withotu assignment. consider
144
+ "PLW0603", # discourage global. skip
145
+ "PLW1510", # subprocess run without check arg. skip
146
+ "PLW1514", # open without encoding. skip
147
+ "PLW2901", # for loop variable overwritten. skip
148
+ "PT001", # change ficture decorator. should add
149
+ "PT011", # use more specific raises decorator. should add
150
+ "PT018", # break down complex assertsions. skip
151
+ "PTH", # enforces new python path library usage. skip
152
+ "PYI030", # turn union of literals to just literal with multiple. should add
153
+ "PYI041", # use float instead of int | float. should remove floats
154
+ "RET", # enforces return semantics. break up and re-evaluate later
155
+ "RSE102", # unnecessary parens on exception. skip.
156
+ "RUF001", # ambiguous characters. skip
157
+ "RUF005", # prefer star to concatenation. skip
158
+ "RUF010", # use explicit conversion flag. skip
159
+ "RUF012", # type with class var. should add
160
+ "RUF015", # prefer next for single element. skip
161
+ "RUF100", # unused noqa. should add
162
+ "S", # should split up
163
+ "S101", # allow asserts. skip
164
+ "SIM102", # use single if instead of nested. skip
165
+ "SIM105", # use exception supress. skip
166
+ "SIM108", # use ternary. skip
167
+ "SIM110", # use any/all. should add
168
+ "SIM112", # case of env variable. skip
169
+ "SIM114", # combine if branches. skip
170
+ "SIM115", # use context handler for files. should add
171
+ "SIM117", # use single with. should add
172
+ "SLF001", # private member access. should add
173
+ "SLOT000", # subclass of string should define slot. should add
174
+ "T201", # print. skip
175
+ "T203", # pprint. skip
176
+ "TCH001", # move application import into type checking. skip
177
+ "TCH002", # move third party import into type checking. consider
178
+ "TCH003", # move library into type checking lbock. consider
179
+ "TD", # todo comments. skip
180
+ "TID252", # eliminate relative imports from parents. skip
181
+ "TRY002", # create your own exception. skip
182
+ "TRY003", # avoid long messages. skip
183
+ "TRY004", # prefer type error. should add
184
+ "TRY201", # raise without exception name. consider
185
+ "TRY300", # move statement to else block. consider
186
+ "TRY301", # move raise to inner function. skip
187
+ "UP007", # use union for type annotations. should add
188
+ "UP013", # eliminate typeddict. should add
189
+ "UP031", # use format specifiers. should add
190
+ "B905", # zip strict. we have a deprecated pattern here, consider
191
+ "UP036", # outdated version block, consider
192
+ "RUF007", # prefer itertools.pairwise over zip, consider
193
+ "RUF022", # __all__ is not sorted. skip due to isort complication
194
+ "UP017", # use datetime.UTC, TODO add back in
195
+ "UP035", # replacing List with list, TODO add back in
196
+ "UP038", # isinstance X | Y instead of (X, Y), TODO add back in
197
+ # ## FROM RUFF UPGRADE
198
+ "PLC2701", # private name imports. should add
199
+ "PLR1702", # too many nested blocks -- add with config. skip
200
+ "RUF025", # unnecessary dict comprehension. skip
201
+ "SIM113", # index variable should use enumerate. should add.
202
+ "PLR0914" # too many local variables. configure below. should add with config
203
+ ]
204
+ line-length = 90
205
+ target-version = "py311"
206
+
207
+ exclude = [
208
+ 'env'
209
+ ]
210
+ [tool.ruff.lint.per-file-ignores]
211
+ "__init__.py" = ["F401"]
212
+
213
+ [tool.ruff.lint.isort]
214
+ split-on-trailing-comma = true
215
+
216
+ [tool.ruff.lint.mccabe]
217
+ max-complexity = 130 # goal would be to bring this down to ~50 or so
218
+
219
+ [tool.ruff.lint.pylint]
220
+ max-locals=50
221
+
222
+ [tool.setuptools]
223
+ py-modules = []
224
+
@@ -0,0 +1,40 @@
1
+ import os
2
+
3
+ from uncountable.core import (
4
+ AsyncBatchProcessor,
5
+ AuthDetailsApiKey,
6
+ Client,
7
+ MediaFileUpload,
8
+ )
9
+ from uncountable.types import recipe_metadata_t
10
+ from uncountable.types.identifier_t import IdentifierKeyBatchReference
11
+
12
+ client = Client(
13
+ base_url="http://localhost:5000",
14
+ auth_details=AuthDetailsApiKey(
15
+ api_id=os.environ["UNC_API_ID"],
16
+ api_secret_key=os.environ["UNC_API_SECRET_KEY"],
17
+ ),
18
+ )
19
+ uploaded_file = client.upload_files(
20
+ file_uploads=[
21
+ MediaFileUpload(path="/home/logan/Downloads/my_file_to_upload.csv"),
22
+ ]
23
+ )[0]
24
+
25
+ batch_processor = AsyncBatchProcessor(client=client)
26
+
27
+ recipe_batch_identifier = batch_processor.create_recipe(
28
+ material_family_id=1, workflow_id=1
29
+ ).batch_reference
30
+
31
+ batch_processor.set_recipe_metadata(
32
+ recipe_key=IdentifierKeyBatchReference(reference=recipe_batch_identifier),
33
+ recipe_metadata=[
34
+ recipe_metadata_t.MetadataValue(
35
+ metadata_id=102, value_file_ids=[uploaded_file.file_id]
36
+ )
37
+ ],
38
+ )
39
+
40
+ batch_processor.send()
@@ -0,0 +1,26 @@
1
+ import os
2
+ from pathlib import Path
3
+
4
+ import uncountable.types.api.recipes.set_recipe_output_file as set_recipe_output_file_t
5
+ from uncountable.core import AuthDetailsApiKey, Client, MediaFileUpload
6
+
7
+ client = Client(
8
+ base_url="http://localhost:5000",
9
+ auth_details=AuthDetailsApiKey(
10
+ api_id=os.environ["UNC_API_ID"],
11
+ api_secret_key=os.environ["UNC_API_SECRET_KEY"],
12
+ ),
13
+ )
14
+ uploaded_file = client.upload_files(
15
+ file_uploads=[
16
+ MediaFileUpload(
17
+ path=str((Path.home() / "Downloads" / "my_file_to_upload.csv").absolute())
18
+ ),
19
+ ]
20
+ )[0]
21
+
22
+ client.set_recipe_output_file(
23
+ output_file_data=set_recipe_output_file_t.RecipeOutputFileValue(
24
+ recipe_id=58070, output_id=148, file_id=uploaded_file.file_id, experiment_num=1
25
+ )
26
+ )
@@ -0,0 +1,107 @@
1
+ import multiprocessing
2
+ import subprocess
3
+ import sys
4
+ import time
5
+ from dataclasses import dataclass
6
+
7
+ from opentelemetry.trace import get_current_span
8
+
9
+ from uncountable.integration.entrypoint import main as cron_target
10
+ from uncountable.integration.telemetry import Logger
11
+
12
+ SHUTDOWN_TIMEOUT_SECS = 30
13
+
14
+
15
+ @dataclass(kw_only=True)
16
+ class ProcessInfo:
17
+ name: str
18
+ process: multiprocessing.Process | subprocess.Popen[bytes]
19
+
20
+ @property
21
+ def is_alive(self) -> bool:
22
+ match self.process:
23
+ case multiprocessing.Process():
24
+ return self.process.is_alive()
25
+ case subprocess.Popen():
26
+ return self.process.poll() is None
27
+
28
+ @property
29
+ def pid(self) -> int | None:
30
+ return self.process.pid
31
+
32
+
33
+ def handle_shutdown(logger: Logger, processes: list[ProcessInfo]) -> None:
34
+ logger.log_info("received shutdown command, shutting down sub-processes")
35
+ for proc_info in processes:
36
+ if proc_info.is_alive:
37
+ proc_info.process.terminate()
38
+
39
+ shutdown_start = time.time()
40
+ still_living_processes = processes
41
+ while (
42
+ time.time() - shutdown_start < SHUTDOWN_TIMEOUT_SECS
43
+ and len(still_living_processes) > 0
44
+ ):
45
+ current_loop_processes = [*still_living_processes]
46
+ logger.log_info(
47
+ "waiting for sub-processes to shut down",
48
+ attributes={
49
+ "still_living_processes": [
50
+ proc_info.name for proc_info in still_living_processes
51
+ ]
52
+ },
53
+ )
54
+ still_living_processes = []
55
+ for proc_info in current_loop_processes:
56
+ if not proc_info.is_alive:
57
+ logger.log_info(f"{proc_info.name} shut down successfully")
58
+ else:
59
+ still_living_processes.append(proc_info)
60
+ time.sleep(1)
61
+
62
+ for proc_info in still_living_processes:
63
+ logger.log_warning(
64
+ f"{proc_info.name} failed to shut down after {SHUTDOWN_TIMEOUT_SECS} seconds, forcefully terminating"
65
+ )
66
+ proc_info.process.kill()
67
+
68
+
69
+ def check_process_health(logger: Logger, processes: list[ProcessInfo]) -> None:
70
+ for proc_info in processes:
71
+ if not proc_info.is_alive:
72
+ logger.log_error(
73
+ f"process {proc_info.name} shut down unexpectedly! shutting down scheduler"
74
+ )
75
+ handle_shutdown(logger, processes)
76
+ sys.exit(1)
77
+
78
+
79
+ def main() -> None:
80
+ logger = Logger(get_current_span())
81
+ processes: list[ProcessInfo] = []
82
+
83
+ def add_process(process: ProcessInfo) -> None:
84
+ processes.append(process)
85
+ logger.log_info(f"started process {process.name}")
86
+
87
+ cron_process = multiprocessing.Process(target=cron_target, args={"blocking": True})
88
+ cron_process.start()
89
+ add_process(ProcessInfo(name="cron server", process=cron_process))
90
+
91
+ uwsgi_process = subprocess.Popen([
92
+ "/app/env/bin/uwsgi",
93
+ "-H",
94
+ "/app/env",
95
+ "--die-on-term",
96
+ ])
97
+ add_process(ProcessInfo(name="uwsgi", process=uwsgi_process))
98
+
99
+ try:
100
+ while True:
101
+ check_process_health(logger, processes=processes)
102
+ time.sleep(1)
103
+ except KeyboardInterrupt:
104
+ handle_shutdown(logger, processes=processes)
105
+
106
+
107
+ main()
@@ -114,7 +114,7 @@ def register_route(
114
114
  "webhook_executor"
115
115
  ) as span:
116
116
  job_logger = JobLogger(
117
- profile_metadata=profile_metadata,
117
+ profile_metadata=profile_meta,
118
118
  job_definition=job,
119
119
  base_span=span,
120
120
  )
@@ -126,7 +126,7 @@ def register_route(
126
126
  profile_metadata=profile_meta,
127
127
  args=WebhookJobArguments(
128
128
  job_definition=job,
129
- profile_metadata=profile_metadata,
129
+ profile_metadata=profile_meta,
130
130
  client=client,
131
131
  batch_processor=AsyncBatchProcessor(client=client),
132
132
  logger=job_logger,
@@ -145,20 +145,24 @@ def register_route(
145
145
  server_logger.log_info(f"job {job.id} webhook registered at: {route}")
146
146
 
147
147
 
148
- profiles = load_profiles()
149
- for profile in profiles:
150
- server_logger = Logger(get_current_span())
151
- profile_metadata = job_definition_t.ProfileMetadata(
152
- name=profile.name,
153
- auth_retrieval=profile.definition.auth_retrieval,
154
- base_url=profile.definition.base_url,
155
- client_options=profile.definition.client_options,
156
- )
157
- for job in profile.definition.jobs:
158
- if isinstance(job, job_definition_t.WebhookJobDefinition):
159
- register_route(
160
- server_logger=server_logger, profile_meta=profile_metadata, job=job
161
- )
148
+ def main() -> None:
149
+ profiles = load_profiles()
150
+ for profile in profiles:
151
+ server_logger = Logger(get_current_span())
152
+ profile_metadata = job_definition_t.ProfileMetadata(
153
+ name=profile.name,
154
+ auth_retrieval=profile.definition.auth_retrieval,
155
+ base_url=profile.definition.base_url,
156
+ client_options=profile.definition.client_options,
157
+ )
158
+ for job in profile.definition.jobs:
159
+ if isinstance(job, job_definition_t.WebhookJobDefinition):
160
+ register_route(
161
+ server_logger=server_logger, profile_meta=profile_metadata, job=job
162
+ )
163
+
164
+
165
+ main()
162
166
 
163
167
 
164
168
  if __name__ == "__main__":
@@ -86,6 +86,7 @@ from .api.inputs import set_intermediate_type as set_intermediate_type_t
86
86
  from .api.recipes import set_recipe_inputs as set_recipe_inputs_t
87
87
  from .api.recipes import set_recipe_metadata as set_recipe_metadata_t
88
88
  from .api.recipes import set_recipe_output_annotations as set_recipe_output_annotations_t
89
+ from .api.recipes import set_recipe_output_file as set_recipe_output_file_t
89
90
  from .api.recipes import set_recipe_outputs as set_recipe_outputs_t
90
91
  from .api.recipes import set_recipe_tags as set_recipe_tags_t
91
92
  from .api.entity import set_values as set_values_t
@@ -185,6 +186,7 @@ __all__: list[str] = [
185
186
  "set_recipe_inputs_t",
186
187
  "set_recipe_metadata_t",
187
188
  "set_recipe_output_annotations_t",
189
+ "set_recipe_output_file_t",
188
190
  "set_recipe_outputs_t",
189
191
  "set_recipe_tags_t",
190
192
  "set_values_t",
@@ -0,0 +1,46 @@
1
+ # DO NOT MODIFY -- This file is generated by type_spec
2
+ # flake8: noqa: F821
3
+ # ruff: noqa: E402 Q003
4
+ # fmt: off
5
+ # isort: skip_file
6
+ from __future__ import annotations
7
+ import typing # noqa: F401
8
+ import datetime # noqa: F401
9
+ from decimal import Decimal # noqa: F401
10
+ import dataclasses
11
+ from ... import base_t
12
+ from ... import response_t
13
+
14
+ __all__: list[str] = [
15
+ "Arguments",
16
+ "Data",
17
+ "ENDPOINT_METHOD",
18
+ "ENDPOINT_PATH",
19
+ "RecipeOutputFileValue",
20
+ ]
21
+
22
+ ENDPOINT_METHOD = "POST"
23
+ ENDPOINT_PATH = "api/external/recipes/external_set_recipe_output_file"
24
+
25
+
26
+ # DO NOT MODIFY -- This file is generated by type_spec
27
+ @dataclasses.dataclass(kw_only=True)
28
+ class RecipeOutputFileValue:
29
+ recipe_id: base_t.ObjectId
30
+ output_id: base_t.ObjectId
31
+ experiment_num: int
32
+ condition_id: typing.Optional[base_t.ObjectId] = None
33
+ file_id: typing.Optional[base_t.ObjectId] = None
34
+
35
+
36
+ # DO NOT MODIFY -- This file is generated by type_spec
37
+ @dataclasses.dataclass(kw_only=True)
38
+ class Arguments:
39
+ output_file_data: RecipeOutputFileValue
40
+
41
+
42
+ # DO NOT MODIFY -- This file is generated by type_spec
43
+ @dataclasses.dataclass(kw_only=True)
44
+ class Data(response_t.Response):
45
+ pass
46
+ # DO NOT MODIFY -- This file is generated by type_spec
@@ -74,6 +74,7 @@ import uncountable.types.api.inputs.set_intermediate_type as set_intermediate_ty
74
74
  import uncountable.types.api.recipes.set_recipe_inputs as set_recipe_inputs_t
75
75
  import uncountable.types.api.recipes.set_recipe_metadata as set_recipe_metadata_t
76
76
  import uncountable.types.api.recipes.set_recipe_output_annotations as set_recipe_output_annotations_t
77
+ import uncountable.types.api.recipes.set_recipe_output_file as set_recipe_output_file_t
77
78
  import uncountable.types.api.recipes.set_recipe_outputs as set_recipe_outputs_t
78
79
  import uncountable.types.api.recipes.set_recipe_tags as set_recipe_tags_t
79
80
  import uncountable.types.api.entity.set_values as set_values_t
@@ -1321,6 +1322,25 @@ class ClientMethods(ABC):
1321
1322
  )
1322
1323
  return self.do_request(api_request=api_request, return_type=set_recipe_output_annotations_t.Data)
1323
1324
 
1325
+ def set_recipe_output_file(
1326
+ self,
1327
+ *,
1328
+ output_file_data: set_recipe_output_file_t.RecipeOutputFileValue,
1329
+ ) -> set_recipe_output_file_t.Data:
1330
+ """Sets output file value for an experiment. Include a single file as part of the FormData of the request with the filename as the key
1331
+
1332
+ :param output_file_data: The output file to set
1333
+ """
1334
+ args = set_recipe_output_file_t.Arguments(
1335
+ output_file_data=output_file_data,
1336
+ )
1337
+ api_request = APIRequest(
1338
+ method=set_recipe_output_file_t.ENDPOINT_METHOD,
1339
+ endpoint=set_recipe_output_file_t.ENDPOINT_PATH,
1340
+ args=args,
1341
+ )
1342
+ return self.do_request(api_request=api_request, return_type=set_recipe_output_file_t.Data)
1343
+
1324
1344
  def set_recipe_outputs(
1325
1345
  self,
1326
1346
  *,