UncountablePythonSDK 0.0.49__tar.gz → 0.0.51__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.
Potentially problematic release.
This version of UncountablePythonSDK might be problematic. Click here for more details.
- {uncountablepythonsdk-0.0.49/UncountablePythonSDK.egg-info → uncountablepythonsdk-0.0.51}/PKG-INFO +5 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51/UncountablePythonSDK.egg-info}/PKG-INFO +5 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/UncountablePythonSDK.egg-info/SOURCES.txt +2 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/UncountablePythonSDK.egg-info/requires.txt +4 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/requirements.txt +1 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pyproject.toml +4 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/core/client.py +14 -9
- uncountablepythonsdk-0.0.51/uncountable/core/version.py +11 -0
- uncountablepythonsdk-0.0.51/uncountable/integration/construct_client.py +51 -0
- uncountablepythonsdk-0.0.51/uncountable/integration/cron.py +55 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/executors/generic_upload_executor.py +2 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/job.py +1 -15
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/secret_retrieval/retrieve_secret.py +32 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/server.py +9 -0
- uncountablepythonsdk-0.0.51/uncountable/integration/telemetry.py +130 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/create_entities.py +1 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/create_entity.py +1 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/uploader/invoke_uploader.py +1 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/async_batch_processor.py +2 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/client_base.py +4 -2
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/job_definition.py +2 -1
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/job_definition_t.py +22 -6
- uncountablepythonsdk-0.0.49/uncountable/integration/construct_client.py +0 -47
- uncountablepythonsdk-0.0.49/uncountable/integration/cron.py +0 -47
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/.github/workflows/documentation.yml +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/.github/workflows/publish.yml +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/.gitignore +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/README.md +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/UncountablePythonSDK.egg-info/dependency_links.txt +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/UncountablePythonSDK.egg-info/top_level.txt +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/.gitignore +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/conf.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/index.md +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/justfile +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/quickstart.md +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/android-chrome-192x192.png +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/android-chrome-512x512.png +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/apple-touch-icon.png +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/browserconfig.xml +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/favicon-16x16.png +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/favicon-32x32.png +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/manifest.json +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/mstile-150x150.png +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/favicons/safari-pinned-tab.svg +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/docs/static/logo_blue.png +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/examples/async_batch.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/examples/create_entity.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/examples/edit_recipe_inputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/examples/invoke_uploader.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/examples/upload_files.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/argument_parser/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/argument_parser/_is_enum.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/argument_parser/_is_namedtuple.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/argument_parser/argument_parser.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/argument_parser/case_convert.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/filesystem_utils/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/filesystem_utils/_gdrive_session.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/filesystem_utils/_local_session.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/filesystem_utils/_s3_session.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/filesystem_utils/_sftp_session.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/filesystem_utils/file_type_utils.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/filesystem_utils/filesystem_session.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization/missing_sentry.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization/opaque_key.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization/serial_class.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization/serial_union.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization/yaml.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization_util/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization_util/_get_type_for_serialization.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization_util/convert_to_snakecase.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/serialization_util/serialization_helpers.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/strenum_compat/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/strenum_compat/strenum_compat.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/__main__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/actions_registry/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/actions_registry/__main__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/actions_registry/emit_typescript.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/builder.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/config.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/emit_io_ts.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/emit_open_api.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/emit_open_api_util.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/emit_python.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/emit_typescript.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/emit_typescript_util.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/load_types.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/open_api_util.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/parts/base.py.prepart +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/parts/base.ts.prepart +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/test.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/type_info/__main__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/type_info/emit_type_info.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/util.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/value_spec/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/value_spec/__main__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/value_spec/convert_type.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/value_spec/emit_python.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/pkgs/type_spec/value_spec/types.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/setup.cfg +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/core/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/core/async_batch.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/core/file_upload.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/core/types.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/db/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/db/connect.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/entrypoint.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/executors/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/executors/executors.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/executors/script_executor.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/secret_retrieval/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/py.typed +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/batch/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/batch/execute_batch.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/batch/execute_batch_load_async.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/chemical/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/chemical/convert_chemical_formats.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/get_entities_data.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/list_entities.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/lock_entity.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/resolve_entity_ids.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/set_values.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/transition_entity_phase.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/entity/unlock_entity.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/equipment/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/equipment/associate_equipment_input.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/field_options/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/field_options/upsert_field_options.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/id_source/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/id_source/list_id_source.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/id_source/match_id_source.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/input_groups/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/input_groups/get_input_group_names.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/create_inputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/get_input_data.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/get_input_names.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/get_inputs_data.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/set_input_attribute_values.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/set_input_category.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/set_input_subcategories.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/inputs/set_intermediate_type.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/material_families/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/material_families/update_entity_material_families.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/outputs/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/outputs/get_output_data.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/outputs/get_output_names.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/outputs/resolve_output_conditions.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/permissions/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/permissions/set_core_permissions.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/project/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/project/get_projects.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/project/get_projects_data.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipe_links/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipe_links/create_recipe_link.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipe_links/remove_recipe_link.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipe_metadata/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/add_recipe_to_project.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/archive_recipes.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/associate_recipe_as_input.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/associate_recipe_as_lot.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/create_recipe.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/create_recipes.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/disassociate_recipe_as_input.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/edit_recipe_inputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/get_curve.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/get_recipe_calculations.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/get_recipe_links.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/get_recipe_names.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/get_recipe_output_metadata.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/get_recipes_data.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/lock_recipes.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/remove_recipe_from_project.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/set_recipe_inputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/set_recipe_metadata.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/set_recipe_output_annotations.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/set_recipe_outputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/set_recipe_tags.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/unarchive_recipes.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/recipes/unlock_recipes.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/triggers/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/triggers/run_trigger.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/api/uploader/__init__.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/async_batch.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/async_batch_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/base.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/base_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/calculations.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/calculations_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/chemical_structure.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/chemical_structure_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/client_config.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/client_config_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/curves.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/curves_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/entity.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/entity_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/experiment_groups.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/experiment_groups_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/field_values.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/field_values_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/fields.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/fields_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/generic_upload.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/generic_upload_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/id_source.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/id_source_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/identifier.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/identifier_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/input_attributes.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/input_attributes_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/inputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/inputs_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/outputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/outputs_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/permissions.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/permissions_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/phases.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/phases_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/post_base.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/post_base_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_identifiers.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_identifiers_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_inputs.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_inputs_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_links.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_links_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_metadata.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_metadata_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_output_metadata.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_output_metadata_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_tags.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_tags_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_workflow_steps.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipe_workflow_steps_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipes.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/recipes_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/response.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/response_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/secret_retrieval.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/secret_retrieval_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/units.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/units_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/users.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/users_t.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/workflows.py +0 -0
- {uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/workflows_t.py +0 -0
{uncountablepythonsdk-0.0.49/UncountablePythonSDK.egg-info → uncountablepythonsdk-0.0.51}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.51
|
|
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
|
|
@@ -27,6 +27,10 @@ Requires-Dist: PyYAML==6.*
|
|
|
27
27
|
Requires-Dist: google-api-python-client==2.*
|
|
28
28
|
Requires-Dist: tqdm==4.*
|
|
29
29
|
Requires-Dist: pysftp==0.*
|
|
30
|
+
Requires-Dist: opentelemetry-api==1.*
|
|
31
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.*
|
|
32
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.*
|
|
33
|
+
Requires-Dist: opentelemetry-sdk==1.*
|
|
30
34
|
Requires-Dist: paramiko==3.*
|
|
31
35
|
Requires-Dist: boto3==1.*
|
|
32
36
|
Provides-Extra: test
|
{uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51/UncountablePythonSDK.egg-info}/PKG-INFO
RENAMED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: UncountablePythonSDK
|
|
3
|
-
Version: 0.0.
|
|
3
|
+
Version: 0.0.51
|
|
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
|
|
@@ -27,6 +27,10 @@ Requires-Dist: PyYAML==6.*
|
|
|
27
27
|
Requires-Dist: google-api-python-client==2.*
|
|
28
28
|
Requires-Dist: tqdm==4.*
|
|
29
29
|
Requires-Dist: pysftp==0.*
|
|
30
|
+
Requires-Dist: opentelemetry-api==1.*
|
|
31
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-common==1.*
|
|
32
|
+
Requires-Dist: opentelemetry-exporter-otlp-proto-http==1.*
|
|
33
|
+
Requires-Dist: opentelemetry-sdk==1.*
|
|
30
34
|
Requires-Dist: paramiko==3.*
|
|
31
35
|
Requires-Dist: boto3==1.*
|
|
32
36
|
Provides-Extra: test
|
|
@@ -87,12 +87,14 @@ uncountable/core/async_batch.py
|
|
|
87
87
|
uncountable/core/client.py
|
|
88
88
|
uncountable/core/file_upload.py
|
|
89
89
|
uncountable/core/types.py
|
|
90
|
+
uncountable/core/version.py
|
|
90
91
|
uncountable/integration/__init__.py
|
|
91
92
|
uncountable/integration/construct_client.py
|
|
92
93
|
uncountable/integration/cron.py
|
|
93
94
|
uncountable/integration/entrypoint.py
|
|
94
95
|
uncountable/integration/job.py
|
|
95
96
|
uncountable/integration/server.py
|
|
97
|
+
uncountable/integration/telemetry.py
|
|
96
98
|
uncountable/integration/db/__init__.py
|
|
97
99
|
uncountable/integration/db/connect.py
|
|
98
100
|
uncountable/integration/executors/__init__.py
|
|
@@ -59,6 +59,10 @@ dependencies = [
|
|
|
59
59
|
"google-api-python-client == 2.*",
|
|
60
60
|
"tqdm == 4.*",
|
|
61
61
|
"pysftp == 0.*",
|
|
62
|
+
"opentelemetry-api==1.*",
|
|
63
|
+
"opentelemetry-exporter-otlp-proto-common==1.*",
|
|
64
|
+
"opentelemetry-exporter-otlp-proto-http==1.*",
|
|
65
|
+
"opentelemetry-sdk==1.*",
|
|
62
66
|
"paramiko == 3.*",
|
|
63
67
|
"boto3 == 1.*"
|
|
64
68
|
]
|
|
@@ -4,16 +4,18 @@ import typing
|
|
|
4
4
|
from dataclasses import dataclass
|
|
5
5
|
from datetime import datetime, timedelta
|
|
6
6
|
from enum import StrEnum
|
|
7
|
-
from importlib.metadata import PackageNotFoundError, version
|
|
8
7
|
from urllib.parse import urljoin
|
|
9
8
|
from uuid import uuid4
|
|
10
9
|
|
|
11
10
|
import requests
|
|
11
|
+
from opentelemetry.sdk.resources import Attributes
|
|
12
12
|
from requests.exceptions import JSONDecodeError
|
|
13
13
|
|
|
14
14
|
from pkgs.argument_parser import CachedParser
|
|
15
15
|
from pkgs.serialization_util import serialize_for_api
|
|
16
16
|
from pkgs.serialization_util.serialization_helpers import JsonValue
|
|
17
|
+
from uncountable.core.version import get_version
|
|
18
|
+
from uncountable.integration.telemetry import JobLogger
|
|
17
19
|
from uncountable.types.client_base import APIRequest, ClientMethods
|
|
18
20
|
from uncountable.types.client_config import ClientConfigOptions
|
|
19
21
|
|
|
@@ -25,12 +27,6 @@ UNC_REQUEST_ID_HEADER = "X-UNC-REQUEST-ID"
|
|
|
25
27
|
UNC_SDK_VERSION_HEADER = "X-UNC-SDK-VERSION"
|
|
26
28
|
|
|
27
29
|
|
|
28
|
-
try:
|
|
29
|
-
__version__ = version("UncountablePythonSDK")
|
|
30
|
-
except PackageNotFoundError:
|
|
31
|
-
__version__ = "unknown"
|
|
32
|
-
|
|
33
|
-
|
|
34
30
|
class EndpointMethod(StrEnum):
|
|
35
31
|
POST = "POST"
|
|
36
32
|
GET = "GET"
|
|
@@ -61,6 +57,7 @@ HTTPRequest = HTTPPostRequest | HTTPGetRequest
|
|
|
61
57
|
@dataclass(kw_only=True)
|
|
62
58
|
class ClientConfig(ClientConfigOptions):
|
|
63
59
|
transform_request: typing.Callable[[requests.Request], requests.Request] | None = None
|
|
60
|
+
job_logger: typing.Optional[JobLogger] = None
|
|
64
61
|
|
|
65
62
|
|
|
66
63
|
OAUTH_REFRESH_WINDOW_SECONDS = 60 * 5
|
|
@@ -204,7 +201,15 @@ class Client(ClientMethods):
|
|
|
204
201
|
case _:
|
|
205
202
|
typing.assert_never(http_request)
|
|
206
203
|
request.headers = http_request.headers
|
|
207
|
-
|
|
204
|
+
if self._cfg.job_logger is not None:
|
|
205
|
+
attributes: Attributes = {
|
|
206
|
+
"method": http_request.method,
|
|
207
|
+
"endpoint": api_request.endpoint,
|
|
208
|
+
}
|
|
209
|
+
with self._cfg.job_logger.push_scope("api_call", attributes=attributes):
|
|
210
|
+
response = self._send_request(request)
|
|
211
|
+
else:
|
|
212
|
+
response = self._send_request(request)
|
|
208
213
|
response_data = self._get_response_json(response, request_id=request_id)
|
|
209
214
|
cached_parser = self._get_cached_parser(return_type)
|
|
210
215
|
try:
|
|
@@ -260,7 +265,7 @@ class Client(ClientMethods):
|
|
|
260
265
|
) -> HTTPRequest:
|
|
261
266
|
headers = self._build_auth_headers()
|
|
262
267
|
headers[UNC_REQUEST_ID_HEADER] = request_id
|
|
263
|
-
headers[UNC_SDK_VERSION_HEADER] =
|
|
268
|
+
headers[UNC_SDK_VERSION_HEADER] = get_version()
|
|
264
269
|
method = api_request.method.lower()
|
|
265
270
|
data = {"data": json.dumps(serialize_for_api(api_request.args))}
|
|
266
271
|
match method:
|
|
@@ -0,0 +1,11 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
from importlib.metadata import PackageNotFoundError, version
|
|
3
|
+
|
|
4
|
+
|
|
5
|
+
@functools.cache
|
|
6
|
+
def get_version() -> str:
|
|
7
|
+
try:
|
|
8
|
+
version_str = version("UncountablePythonSDK")
|
|
9
|
+
except PackageNotFoundError:
|
|
10
|
+
version_str = "unknown"
|
|
11
|
+
return version_str
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
from uncountable.core import AuthDetailsApiKey, Client
|
|
2
|
+
from uncountable.core.client import ClientConfig
|
|
3
|
+
from uncountable.core.types import AuthDetailsAll, AuthDetailsOAuth
|
|
4
|
+
from uncountable.integration.secret_retrieval.retrieve_secret import retrieve_secret
|
|
5
|
+
from uncountable.integration.telemetry import JobLogger
|
|
6
|
+
from uncountable.types.job_definition_t import (
|
|
7
|
+
AuthRetrievalBasic,
|
|
8
|
+
AuthRetrievalOAuth,
|
|
9
|
+
ProfileMetadata,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
def _construct_auth_details(profile_meta: ProfileMetadata) -> AuthDetailsAll:
|
|
14
|
+
match profile_meta.auth_retrieval:
|
|
15
|
+
case AuthRetrievalOAuth():
|
|
16
|
+
refresh_token = retrieve_secret(
|
|
17
|
+
profile_meta.auth_retrieval.refresh_token_secret,
|
|
18
|
+
profile_metadata=profile_meta,
|
|
19
|
+
)
|
|
20
|
+
return AuthDetailsOAuth(refresh_token=refresh_token)
|
|
21
|
+
case AuthRetrievalBasic():
|
|
22
|
+
api_id = retrieve_secret(
|
|
23
|
+
profile_meta.auth_retrieval.api_id_secret, profile_metadata=profile_meta
|
|
24
|
+
)
|
|
25
|
+
api_key = retrieve_secret(
|
|
26
|
+
profile_meta.auth_retrieval.api_key_secret, profile_metadata=profile_meta
|
|
27
|
+
)
|
|
28
|
+
|
|
29
|
+
return AuthDetailsApiKey(api_id=api_id, api_secret_key=api_key)
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def _construct_client_config(
|
|
33
|
+
profile_meta: ProfileMetadata, job_logger: JobLogger
|
|
34
|
+
) -> ClientConfig | None:
|
|
35
|
+
if profile_meta.client_options is None:
|
|
36
|
+
return None
|
|
37
|
+
return ClientConfig(
|
|
38
|
+
allow_insecure_tls=profile_meta.client_options.allow_insecure_tls,
|
|
39
|
+
extra_headers=profile_meta.client_options.extra_headers,
|
|
40
|
+
job_logger=job_logger,
|
|
41
|
+
)
|
|
42
|
+
|
|
43
|
+
|
|
44
|
+
def construct_uncountable_client(
|
|
45
|
+
profile_meta: ProfileMetadata, job_logger: JobLogger
|
|
46
|
+
) -> Client:
|
|
47
|
+
return Client(
|
|
48
|
+
base_url=profile_meta.base_url,
|
|
49
|
+
auth_details=_construct_auth_details(profile_meta),
|
|
50
|
+
config=_construct_client_config(profile_meta, job_logger),
|
|
51
|
+
)
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from pkgs.argument_parser import CachedParser
|
|
4
|
+
from uncountable.core.async_batch import AsyncBatchProcessor
|
|
5
|
+
from uncountable.integration.construct_client import construct_uncountable_client
|
|
6
|
+
from uncountable.integration.executors.executors import resolve_executor
|
|
7
|
+
from uncountable.integration.job import CronJobArguments
|
|
8
|
+
from uncountable.integration.telemetry import JobLogger
|
|
9
|
+
from uncountable.types.job_definition_t import JobDefinition, ProfileMetadata
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
@dataclass
|
|
13
|
+
class CronJobArgs:
|
|
14
|
+
definition: JobDefinition
|
|
15
|
+
profile_metadata: ProfileMetadata
|
|
16
|
+
|
|
17
|
+
|
|
18
|
+
cron_args_parser = CachedParser(CronJobArgs)
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
def cron_job_executor(**kwargs: dict) -> None:
|
|
22
|
+
args_passed = cron_args_parser.parse_storage(kwargs)
|
|
23
|
+
job_logger = JobLogger(
|
|
24
|
+
profile_metadata=args_passed.profile_metadata,
|
|
25
|
+
job_definition=args_passed.definition,
|
|
26
|
+
)
|
|
27
|
+
client = construct_uncountable_client(
|
|
28
|
+
profile_meta=args_passed.profile_metadata, job_logger=job_logger
|
|
29
|
+
)
|
|
30
|
+
batch_processor = AsyncBatchProcessor(client=client)
|
|
31
|
+
args = CronJobArguments(
|
|
32
|
+
job_definition=args_passed.definition,
|
|
33
|
+
client=client,
|
|
34
|
+
batch_processor=batch_processor,
|
|
35
|
+
profile_metadata=args_passed.profile_metadata,
|
|
36
|
+
logger=job_logger,
|
|
37
|
+
)
|
|
38
|
+
|
|
39
|
+
with job_logger.push_scope(args_passed.definition.name) as job_logger:
|
|
40
|
+
job = resolve_executor(
|
|
41
|
+
args_passed.definition.executor, args_passed.profile_metadata
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
job_logger.log_info("running job")
|
|
45
|
+
|
|
46
|
+
job.run(args=args)
|
|
47
|
+
|
|
48
|
+
if batch_processor.current_queue_size() != 0:
|
|
49
|
+
batch_processor.send()
|
|
50
|
+
|
|
51
|
+
submitted_batch_job_ids = batch_processor.get_submitted_job_ids()
|
|
52
|
+
job_logger.log_info(
|
|
53
|
+
"completed job",
|
|
54
|
+
attributes={"submitted_batch_job_ids": submitted_batch_job_ids},
|
|
55
|
+
)
|
|
@@ -17,8 +17,9 @@ from pkgs.filesystem_utils import (
|
|
|
17
17
|
)
|
|
18
18
|
from pkgs.filesystem_utils.filesystem_session import FileSystemSession
|
|
19
19
|
from uncountable.core.file_upload import DataFileUpload, FileUpload
|
|
20
|
-
from uncountable.integration.job import Job, JobArguments
|
|
20
|
+
from uncountable.integration.job import Job, JobArguments
|
|
21
21
|
from uncountable.integration.secret_retrieval import retrieve_secret
|
|
22
|
+
from uncountable.integration.telemetry import JobLogger
|
|
22
23
|
from uncountable.types.generic_upload_t import (
|
|
23
24
|
GenericRemoteDirectoryScope,
|
|
24
25
|
GenericUploadStrategy,
|
|
@@ -3,24 +3,10 @@ from dataclasses import dataclass
|
|
|
3
3
|
|
|
4
4
|
from uncountable.core.async_batch import AsyncBatchProcessor
|
|
5
5
|
from uncountable.core.client import Client
|
|
6
|
+
from uncountable.integration.telemetry import JobLogger
|
|
6
7
|
from uncountable.types.job_definition_t import JobDefinition, JobResult, ProfileMetadata
|
|
7
8
|
|
|
8
9
|
|
|
9
|
-
class JobLogger:
|
|
10
|
-
def __init__(
|
|
11
|
-
self, *, profile_metadata: ProfileMetadata, job_definition: JobDefinition
|
|
12
|
-
) -> None:
|
|
13
|
-
self.profile_metadata = profile_metadata
|
|
14
|
-
self.job_definition = job_definition
|
|
15
|
-
|
|
16
|
-
def log_info(self, *log_objects: object) -> None:
|
|
17
|
-
# IMPROVE: log a json message with context that can be parsed by OT
|
|
18
|
-
print(
|
|
19
|
-
f"[{self.job_definition.id}] in profile ({self.profile_metadata.name}): ",
|
|
20
|
-
*log_objects,
|
|
21
|
-
)
|
|
22
|
-
|
|
23
|
-
|
|
24
10
|
@dataclass
|
|
25
11
|
class JobArgumentsBase:
|
|
26
12
|
job_definition: JobDefinition
|
|
@@ -1,5 +1,10 @@
|
|
|
1
|
+
import base64
|
|
2
|
+
import functools
|
|
3
|
+
import json
|
|
1
4
|
import os
|
|
2
5
|
|
|
6
|
+
import boto3
|
|
7
|
+
|
|
3
8
|
from uncountable.types.job_definition_t import ProfileMetadata
|
|
4
9
|
from uncountable.types.secret_retrieval_t import (
|
|
5
10
|
SecretRetrieval,
|
|
@@ -22,6 +27,25 @@ class SecretRetrievalError(BaseException):
|
|
|
22
27
|
return f"{self.secret_retrieval.type} secret retrieval failed{append_message}"
|
|
23
28
|
|
|
24
29
|
|
|
30
|
+
@functools.cache
|
|
31
|
+
def _get_aws_secret(*, secret_name: str, region_name: str, sub_key: str | None) -> str:
|
|
32
|
+
client = boto3.client("secretsmanager", region_name=region_name)
|
|
33
|
+
response = client.get_secret_value(SecretId=secret_name)
|
|
34
|
+
|
|
35
|
+
if "SecretString" in response:
|
|
36
|
+
secret = response["SecretString"]
|
|
37
|
+
else:
|
|
38
|
+
secret = base64.b64decode(response["SecretBinary"])
|
|
39
|
+
|
|
40
|
+
value = json.loads(secret)
|
|
41
|
+
|
|
42
|
+
if sub_key is not None:
|
|
43
|
+
assert isinstance(value, dict)
|
|
44
|
+
return str(value[sub_key])
|
|
45
|
+
else:
|
|
46
|
+
return str(value)
|
|
47
|
+
|
|
48
|
+
|
|
25
49
|
def retrieve_secret(
|
|
26
50
|
secret_retrieval: SecretRetrieval, profile_metadata: ProfileMetadata
|
|
27
51
|
) -> str:
|
|
@@ -37,4 +61,11 @@ def retrieve_secret(
|
|
|
37
61
|
)
|
|
38
62
|
return secret
|
|
39
63
|
case SecretRetrievalAWS():
|
|
40
|
-
|
|
64
|
+
try:
|
|
65
|
+
return _get_aws_secret(
|
|
66
|
+
secret_name=secret_retrieval.secret_name,
|
|
67
|
+
region_name=secret_retrieval.region,
|
|
68
|
+
sub_key=secret_retrieval.sub_key,
|
|
69
|
+
)
|
|
70
|
+
except Exception as e:
|
|
71
|
+
raise SecretRetrievalError(secret_retrieval) from e
|
{uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/integration/server.py
RENAMED
|
@@ -11,6 +11,7 @@ from apscheduler.triggers.cron import CronTrigger
|
|
|
11
11
|
from sqlalchemy.engine.base import Engine
|
|
12
12
|
|
|
13
13
|
from uncountable.integration.cron import CronJobArgs, cron_job_executor
|
|
14
|
+
from uncountable.types import base_t
|
|
14
15
|
from uncountable.types.client_config_t import ClientConfigOptions
|
|
15
16
|
from uncountable.types.job_definition_t import (
|
|
16
17
|
AuthRetrieval,
|
|
@@ -67,7 +68,14 @@ class IntegrationServer:
|
|
|
67
68
|
existing_job.reschedule(
|
|
68
69
|
CronTrigger.from_crontab(job_defn.cron_spec)
|
|
69
70
|
)
|
|
71
|
+
if not job_defn.enabled:
|
|
72
|
+
existing_job.pause()
|
|
73
|
+
else:
|
|
74
|
+
existing_job.resume()
|
|
70
75
|
else:
|
|
76
|
+
job_opts: dict[str, base_t.JsonValue] = {}
|
|
77
|
+
if not job_defn.enabled:
|
|
78
|
+
job_opts["next_run_time"] = None
|
|
71
79
|
self._scheduler.add_job(
|
|
72
80
|
cron_job_executor,
|
|
73
81
|
# IMPROVE: reconsider these defaults
|
|
@@ -77,6 +85,7 @@ class IntegrationServer:
|
|
|
77
85
|
name=job_defn.name,
|
|
78
86
|
id=job_defn.id,
|
|
79
87
|
kwargs=job_kwargs,
|
|
88
|
+
**job_opts,
|
|
80
89
|
)
|
|
81
90
|
case _:
|
|
82
91
|
assert_never(job_defn.trigger)
|
|
@@ -0,0 +1,130 @@
|
|
|
1
|
+
import functools
|
|
2
|
+
import os
|
|
3
|
+
import sys
|
|
4
|
+
import time
|
|
5
|
+
from contextlib import contextmanager
|
|
6
|
+
from enum import StrEnum
|
|
7
|
+
from typing import Generator, TextIO, assert_never, cast
|
|
8
|
+
|
|
9
|
+
from opentelemetry import trace
|
|
10
|
+
from opentelemetry.exporter.otlp.proto.http.trace_exporter import OTLPSpanExporter
|
|
11
|
+
from opentelemetry.sdk._logs import LogRecord
|
|
12
|
+
from opentelemetry.sdk.resources import Attributes, Resource
|
|
13
|
+
from opentelemetry.sdk.trace import TracerProvider
|
|
14
|
+
from opentelemetry.sdk.trace.export import (
|
|
15
|
+
SimpleSpanProcessor,
|
|
16
|
+
)
|
|
17
|
+
from opentelemetry.trace import Tracer
|
|
18
|
+
|
|
19
|
+
from uncountable.core.version import get_version
|
|
20
|
+
from uncountable.types import base_t, job_definition_t
|
|
21
|
+
|
|
22
|
+
|
|
23
|
+
def _cast_attributes(attributes: dict[str, base_t.JsonValue]) -> Attributes:
|
|
24
|
+
return cast(Attributes, attributes)
|
|
25
|
+
|
|
26
|
+
|
|
27
|
+
@functools.cache
|
|
28
|
+
def get_tracer() -> Tracer:
|
|
29
|
+
attributes: dict[str, base_t.JsonValue] = {
|
|
30
|
+
"service.name": "integration-server",
|
|
31
|
+
"sdk.version": get_version(),
|
|
32
|
+
}
|
|
33
|
+
unc_version = os.environ.get("UNC_VERSION")
|
|
34
|
+
if unc_version is not None:
|
|
35
|
+
attributes["service.version"] = unc_version
|
|
36
|
+
unc_env = os.environ.get("UNC_INTEGRATION_ENV")
|
|
37
|
+
if unc_env is not None:
|
|
38
|
+
attributes["deployment.environment"] = unc_env
|
|
39
|
+
resource = Resource.create(attributes=_cast_attributes(attributes))
|
|
40
|
+
provider = TracerProvider(resource=resource)
|
|
41
|
+
provider.add_span_processor(SimpleSpanProcessor(OTLPSpanExporter()))
|
|
42
|
+
trace.set_tracer_provider(provider)
|
|
43
|
+
return provider.get_tracer("integration.telemetry")
|
|
44
|
+
|
|
45
|
+
|
|
46
|
+
class LogSeverity(StrEnum):
|
|
47
|
+
INFO = "Info"
|
|
48
|
+
WARN = "Warn"
|
|
49
|
+
ERROR = "Error"
|
|
50
|
+
|
|
51
|
+
|
|
52
|
+
class JobLogger:
|
|
53
|
+
current_span_id: int | None = None
|
|
54
|
+
current_trace_id: int | None = None
|
|
55
|
+
|
|
56
|
+
def __init__(
|
|
57
|
+
self,
|
|
58
|
+
*,
|
|
59
|
+
profile_metadata: job_definition_t.ProfileMetadata,
|
|
60
|
+
job_definition: job_definition_t.JobDefinition,
|
|
61
|
+
) -> None:
|
|
62
|
+
self.profile_metadata = profile_metadata
|
|
63
|
+
self.job_definition = job_definition
|
|
64
|
+
|
|
65
|
+
def _patch_attributes(self, attributes: Attributes | None) -> Attributes:
|
|
66
|
+
patched_attributes: dict[str, base_t.JsonValue] = {
|
|
67
|
+
**(attributes if attributes is not None else {})
|
|
68
|
+
}
|
|
69
|
+
patched_attributes["profile.name"] = self.profile_metadata.name
|
|
70
|
+
patched_attributes["profile.base_url"] = self.profile_metadata.base_url
|
|
71
|
+
patched_attributes["job.name"] = self.job_definition.name
|
|
72
|
+
patched_attributes["job.id"] = self.job_definition.id
|
|
73
|
+
patched_attributes["job.definition_type"] = self.job_definition.type
|
|
74
|
+
match self.job_definition:
|
|
75
|
+
case job_definition_t.CronJobDefinition():
|
|
76
|
+
patched_attributes["job.definition.cron_spec"] = (
|
|
77
|
+
self.job_definition.cron_spec
|
|
78
|
+
)
|
|
79
|
+
case _:
|
|
80
|
+
assert_never(self.job_definition)
|
|
81
|
+
patched_attributes["job.definition.executor.type"] = (
|
|
82
|
+
self.job_definition.executor.type
|
|
83
|
+
)
|
|
84
|
+
match self.job_definition.executor:
|
|
85
|
+
case job_definition_t.JobExecutorScript():
|
|
86
|
+
patched_attributes["job.definition.executor.import_path"] = (
|
|
87
|
+
self.job_definition.executor.import_path
|
|
88
|
+
)
|
|
89
|
+
case job_definition_t.JobExecutorGenericUpload():
|
|
90
|
+
patched_attributes["job.definition.executor.data_source.type"] = (
|
|
91
|
+
self.job_definition.executor.data_source.type
|
|
92
|
+
)
|
|
93
|
+
case _:
|
|
94
|
+
assert_never(self.job_definition.executor)
|
|
95
|
+
return _cast_attributes(patched_attributes)
|
|
96
|
+
|
|
97
|
+
@contextmanager
|
|
98
|
+
def push_scope(
|
|
99
|
+
self, scope_name: str, *, attributes: Attributes | None = None
|
|
100
|
+
) -> Generator["JobLogger", None, None]:
|
|
101
|
+
with get_tracer().start_as_current_span(
|
|
102
|
+
scope_name, attributes=self._patch_attributes(attributes)
|
|
103
|
+
) as span:
|
|
104
|
+
self.current_span_id = span.get_span_context().span_id
|
|
105
|
+
self.current_trace_id = span.get_span_context().trace_id
|
|
106
|
+
yield self
|
|
107
|
+
|
|
108
|
+
def _emit_log(
|
|
109
|
+
self, message: str, *, severity: LogSeverity, attributes: Attributes | None
|
|
110
|
+
) -> None:
|
|
111
|
+
log_record = LogRecord(
|
|
112
|
+
body=message,
|
|
113
|
+
severity_text=severity,
|
|
114
|
+
timestamp=time.time_ns(),
|
|
115
|
+
attributes=self._patch_attributes(attributes),
|
|
116
|
+
span_id=self.current_span_id,
|
|
117
|
+
trace_id=self.current_trace_id,
|
|
118
|
+
)
|
|
119
|
+
log_file: TextIO = sys.stderr if severity == LogSeverity.ERROR else sys.stdout
|
|
120
|
+
log_file.write(log_record.to_json())
|
|
121
|
+
log_file.flush()
|
|
122
|
+
|
|
123
|
+
def log_info(self, message: str, *, attributes: Attributes | None = None) -> None:
|
|
124
|
+
self._emit_log(message=message, severity=LogSeverity.INFO, attributes=attributes)
|
|
125
|
+
|
|
126
|
+
def log_warning(self, message: str, *, attributes: Attributes | None = None) -> None:
|
|
127
|
+
self._emit_log(message=message, severity=LogSeverity.WARN, attributes=attributes)
|
|
128
|
+
|
|
129
|
+
def log_error(self, message: str, *, attributes: Attributes | None = None) -> None:
|
|
130
|
+
self._emit_log(message=message, severity=LogSeverity.ERROR, attributes=attributes)
|
|
@@ -34,7 +34,7 @@ class EntityToCreate:
|
|
|
34
34
|
@dataclasses.dataclass(kw_only=True)
|
|
35
35
|
class Arguments:
|
|
36
36
|
definition_id: base_t.ObjectId
|
|
37
|
-
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS]]
|
|
37
|
+
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS], typing.Literal[entity_t.EntityType.GOAL]]
|
|
38
38
|
entities_to_create: list[EntityToCreate]
|
|
39
39
|
|
|
40
40
|
|
|
@@ -40,7 +40,7 @@ class EntityFieldInitialValue:
|
|
|
40
40
|
@dataclasses.dataclass(kw_only=True)
|
|
41
41
|
class Arguments:
|
|
42
42
|
definition_id: base_t.ObjectId
|
|
43
|
-
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS]]
|
|
43
|
+
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS], typing.Literal[entity_t.EntityType.GOAL]]
|
|
44
44
|
field_values: typing.Optional[typing.Optional[list[field_values_t.FieldRefNameValue]]] = None
|
|
45
45
|
|
|
46
46
|
|
|
@@ -29,6 +29,7 @@ class Arguments:
|
|
|
29
29
|
file_id: base_t.ObjectId
|
|
30
30
|
uploader_key: identifier_t.IdentifierKey
|
|
31
31
|
material_family_key: identifier_t.IdentifierKey
|
|
32
|
+
recipe_key: typing.Optional[identifier_t.IdentifierKey] = None
|
|
32
33
|
|
|
33
34
|
|
|
34
35
|
# DO NOT MODIFY -- This file is generated by type_spec
|
|
@@ -163,6 +163,7 @@ class AsyncBatchProcessorBase(ABC):
|
|
|
163
163
|
file_id: base_t.ObjectId,
|
|
164
164
|
uploader_key: identifier_t.IdentifierKey,
|
|
165
165
|
material_family_key: identifier_t.IdentifierKey,
|
|
166
|
+
recipe_key: typing.Optional[identifier_t.IdentifierKey] = None,
|
|
166
167
|
depends_on: typing.Optional[list[str]] = None,
|
|
167
168
|
) -> async_batch_t.QueuedAsyncBatchRequest:
|
|
168
169
|
"""Runs a file through an uploader.
|
|
@@ -173,6 +174,7 @@ class AsyncBatchProcessorBase(ABC):
|
|
|
173
174
|
file_id=file_id,
|
|
174
175
|
uploader_key=uploader_key,
|
|
175
176
|
material_family_key=material_family_key,
|
|
177
|
+
recipe_key=recipe_key,
|
|
176
178
|
)
|
|
177
179
|
json_data = serialize_for_api(args)
|
|
178
180
|
|
{uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/client_base.py
RENAMED
|
@@ -235,7 +235,7 @@ class ClientMethods(ABC):
|
|
|
235
235
|
self,
|
|
236
236
|
*,
|
|
237
237
|
definition_id: base_t.ObjectId,
|
|
238
|
-
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS]],
|
|
238
|
+
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS], typing.Literal[entity_t.EntityType.GOAL]],
|
|
239
239
|
entities_to_create: list[create_entities_t.EntityToCreate],
|
|
240
240
|
) -> create_entities_t.Data:
|
|
241
241
|
"""Creates new Uncountable entities
|
|
@@ -260,7 +260,7 @@ class ClientMethods(ABC):
|
|
|
260
260
|
self,
|
|
261
261
|
*,
|
|
262
262
|
definition_id: base_t.ObjectId,
|
|
263
|
-
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS]],
|
|
263
|
+
entity_type: typing.Union[typing.Literal[entity_t.EntityType.LAB_REQUEST], typing.Literal[entity_t.EntityType.APPROVAL], typing.Literal[entity_t.EntityType.CUSTOM_ENTITY], typing.Literal[entity_t.EntityType.INVENTORY_AMOUNT], typing.Literal[entity_t.EntityType.TASK], typing.Literal[entity_t.EntityType.PROJECT], typing.Literal[entity_t.EntityType.EQUIPMENT], typing.Literal[entity_t.EntityType.INV_LOCAL_LOCATIONS], typing.Literal[entity_t.EntityType.FIELD_OPTION_SET], typing.Literal[entity_t.EntityType.WEBHOOK], typing.Literal[entity_t.EntityType.SPECS], typing.Literal[entity_t.EntityType.GOAL]],
|
|
264
264
|
field_values: typing.Optional[typing.Optional[list[field_values_t.FieldRefNameValue]]] = None,
|
|
265
265
|
) -> create_entity_t.Data:
|
|
266
266
|
"""Creates a new Uncountable entity
|
|
@@ -857,6 +857,7 @@ class ClientMethods(ABC):
|
|
|
857
857
|
file_id: base_t.ObjectId,
|
|
858
858
|
uploader_key: identifier_t.IdentifierKey,
|
|
859
859
|
material_family_key: identifier_t.IdentifierKey,
|
|
860
|
+
recipe_key: typing.Optional[identifier_t.IdentifierKey] = None,
|
|
860
861
|
) -> invoke_uploader_t.Data:
|
|
861
862
|
"""Runs a file through an uploader.
|
|
862
863
|
|
|
@@ -865,6 +866,7 @@ class ClientMethods(ABC):
|
|
|
865
866
|
file_id=file_id,
|
|
866
867
|
uploader_key=uploader_key,
|
|
867
868
|
material_family_key=material_family_key,
|
|
869
|
+
recipe_key=recipe_key,
|
|
868
870
|
)
|
|
869
871
|
api_request = APIRequest(
|
|
870
872
|
method=invoke_uploader_t.ENDPOINT_METHOD,
|
{uncountablepythonsdk-0.0.49 → uncountablepythonsdk-0.0.51}/uncountable/types/job_definition.py
RENAMED
|
@@ -21,7 +21,8 @@ from .job_definition_t import JobDefinitionBase as JobDefinitionBase
|
|
|
21
21
|
from .job_definition_t import CronJobDefinition as CronJobDefinition
|
|
22
22
|
from .job_definition_t import JobDefinition as JobDefinition
|
|
23
23
|
from .job_definition_t import AuthRetrievalBase as AuthRetrievalBase
|
|
24
|
-
from .job_definition_t import
|
|
24
|
+
from .job_definition_t import AuthRetrievalOAuth as AuthRetrievalOAuth
|
|
25
|
+
from .job_definition_t import AuthRetrievalBasic as AuthRetrievalBasic
|
|
25
26
|
from .job_definition_t import AuthRetrieval as AuthRetrieval
|
|
26
27
|
from .job_definition_t import ProfileDefinition as ProfileDefinition
|
|
27
28
|
from .job_definition_t import ProfileMetadata as ProfileMetadata
|