UncountablePythonSDK 0.0.24__py3-none-any.whl → 0.0.131__py3-none-any.whl
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.
- docs/conf.py +60 -8
- docs/index.md +107 -4
- docs/integration_examples/create_ingredient.md +43 -0
- docs/integration_examples/create_output.md +56 -0
- docs/integration_examples/index.md +6 -0
- docs/justfile +2 -2
- docs/requirements.txt +7 -5
- examples/async_batch.py +5 -6
- examples/basic_auth.py +7 -0
- examples/create_entity.py +4 -6
- examples/create_ingredient_sdk.py +34 -0
- examples/download_files.py +26 -0
- examples/edit_recipe_inputs.py +50 -0
- examples/integration-server/jobs/materials_auto/concurrent_cron.py +11 -0
- examples/integration-server/jobs/materials_auto/example_cron.py +21 -0
- examples/integration-server/jobs/materials_auto/example_http.py +47 -0
- examples/integration-server/jobs/materials_auto/example_instrument.py +100 -0
- examples/integration-server/jobs/materials_auto/example_parse.py +140 -0
- examples/integration-server/jobs/materials_auto/example_predictions.py +61 -0
- examples/integration-server/jobs/materials_auto/example_runsheet_wh.py +39 -0
- examples/integration-server/jobs/materials_auto/example_wh.py +23 -0
- examples/integration-server/jobs/materials_auto/profile.yaml +104 -0
- examples/integration-server/pyproject.toml +224 -0
- examples/invoke_uploader.py +26 -0
- examples/oauth.py +7 -0
- examples/set_recipe_metadata_file.py +40 -0
- examples/set_recipe_output_file_sdk.py +26 -0
- examples/upload_files.py +2 -3
- pkgs/argument_parser/__init__.py +9 -0
- pkgs/argument_parser/_is_namedtuple.py +3 -0
- pkgs/argument_parser/argument_parser.py +295 -74
- pkgs/argument_parser/case_convert.py +4 -3
- pkgs/filesystem_utils/__init__.py +20 -0
- pkgs/filesystem_utils/_blob_session.py +144 -0
- pkgs/filesystem_utils/_gdrive_session.py +309 -0
- pkgs/filesystem_utils/_local_session.py +69 -0
- pkgs/filesystem_utils/_s3_session.py +118 -0
- pkgs/filesystem_utils/_sftp_session.py +151 -0
- pkgs/filesystem_utils/file_type_utils.py +91 -0
- pkgs/filesystem_utils/filesystem_session.py +39 -0
- pkgs/py.typed +0 -0
- pkgs/serialization/__init__.py +8 -1
- pkgs/serialization/annotation.py +64 -0
- pkgs/serialization/missing_sentry.py +1 -1
- pkgs/serialization/opaque_key.py +1 -1
- pkgs/serialization/serial_alias.py +47 -0
- pkgs/serialization/serial_class.py +69 -54
- pkgs/serialization/serial_generic.py +16 -0
- pkgs/serialization/serial_union.py +84 -0
- pkgs/serialization/yaml.py +57 -0
- pkgs/serialization_util/__init__.py +7 -7
- pkgs/serialization_util/convert_to_snakecase.py +27 -0
- pkgs/serialization_util/dataclasses.py +14 -0
- pkgs/serialization_util/serialization_helpers.py +117 -71
- pkgs/type_spec/actions_registry/__main__.py +0 -4
- pkgs/type_spec/actions_registry/emit_typescript.py +5 -5
- pkgs/type_spec/builder.py +438 -109
- pkgs/type_spec/builder_types.py +9 -0
- pkgs/type_spec/config.py +52 -24
- pkgs/type_spec/cross_output_links.py +99 -0
- pkgs/type_spec/emit_io_ts.py +1 -1
- pkgs/type_spec/emit_open_api.py +160 -41
- pkgs/type_spec/emit_open_api_util.py +13 -7
- pkgs/type_spec/emit_python.py +450 -136
- pkgs/type_spec/emit_typescript.py +117 -250
- pkgs/type_spec/emit_typescript_util.py +293 -4
- pkgs/type_spec/load_types.py +20 -5
- pkgs/type_spec/non_discriminated_union_exceptions.py +14 -0
- pkgs/type_spec/open_api_util.py +29 -4
- pkgs/type_spec/parts/base.py.prepart +13 -10
- pkgs/type_spec/parts/base.ts.prepart +4 -0
- pkgs/type_spec/type_info/__main__.py +3 -1
- pkgs/type_spec/type_info/emit_type_info.py +161 -32
- pkgs/type_spec/ui_entry_actions/__init__.py +4 -0
- pkgs/type_spec/ui_entry_actions/generate_ui_entry_actions.py +308 -0
- pkgs/type_spec/util.py +4 -4
- pkgs/type_spec/value_spec/__main__.py +27 -10
- pkgs/type_spec/value_spec/convert_type.py +21 -1
- pkgs/type_spec/value_spec/emit_python.py +25 -7
- pkgs/type_spec/value_spec/types.py +1 -1
- uncountable/__init__.py +1 -2
- uncountable/core/__init__.py +11 -3
- uncountable/core/async_batch.py +16 -1
- uncountable/core/client.py +247 -52
- uncountable/core/environment.py +41 -0
- uncountable/core/file_upload.py +67 -22
- uncountable/core/types.py +8 -13
- uncountable/integration/cli.py +142 -0
- uncountable/integration/construct_client.py +43 -27
- uncountable/integration/cron.py +12 -11
- uncountable/integration/db/connect.py +12 -2
- uncountable/integration/db/session.py +25 -0
- uncountable/integration/entrypoint.py +4 -34
- uncountable/integration/executors/executors.py +147 -0
- uncountable/integration/executors/generic_upload_executor.py +336 -0
- uncountable/integration/executors/script_executor.py +15 -9
- uncountable/integration/http_server/__init__.py +5 -0
- uncountable/integration/http_server/types.py +69 -0
- uncountable/integration/job.py +246 -19
- uncountable/integration/queue_runner/__init__.py +0 -0
- uncountable/integration/queue_runner/command_server/__init__.py +28 -0
- uncountable/integration/queue_runner/command_server/command_client.py +133 -0
- uncountable/integration/queue_runner/command_server/command_server.py +142 -0
- uncountable/integration/queue_runner/command_server/constants.py +4 -0
- uncountable/integration/queue_runner/command_server/protocol/__init__.py +0 -0
- uncountable/integration/queue_runner/command_server/protocol/command_server.proto +58 -0
- uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +57 -0
- uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +114 -0
- uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +264 -0
- uncountable/integration/queue_runner/command_server/types.py +75 -0
- uncountable/integration/queue_runner/datastore/__init__.py +3 -0
- uncountable/integration/queue_runner/datastore/datastore_sqlite.py +250 -0
- uncountable/integration/queue_runner/datastore/interface.py +29 -0
- uncountable/integration/queue_runner/datastore/model.py +24 -0
- uncountable/integration/queue_runner/job_scheduler.py +200 -0
- uncountable/integration/queue_runner/queue_runner.py +34 -0
- uncountable/integration/queue_runner/types.py +7 -0
- uncountable/integration/queue_runner/worker.py +116 -0
- uncountable/integration/scan_profiles.py +67 -0
- uncountable/integration/scheduler.py +199 -0
- uncountable/integration/secret_retrieval/__init__.py +3 -0
- uncountable/integration/secret_retrieval/retrieve_secret.py +93 -0
- uncountable/integration/server.py +103 -54
- uncountable/integration/telemetry.py +251 -0
- uncountable/integration/webhook_server/entrypoint.py +97 -0
- uncountable/types/__init__.py +149 -30
- uncountable/types/api/batch/execute_batch.py +16 -9
- uncountable/types/api/batch/execute_batch_load_async.py +13 -7
- uncountable/types/api/chemical/convert_chemical_formats.py +20 -8
- uncountable/types/api/condition_parameters/__init__.py +1 -0
- uncountable/types/api/condition_parameters/upsert_condition_match.py +72 -0
- uncountable/types/api/entity/create_entities.py +24 -12
- uncountable/types/api/entity/create_entity.py +22 -13
- uncountable/types/api/entity/create_or_update_entity.py +48 -0
- uncountable/types/api/entity/export_entities.py +59 -0
- uncountable/types/api/entity/get_entities_data.py +18 -9
- uncountable/types/api/entity/grant_entity_permissions.py +48 -0
- uncountable/types/api/entity/list_aggregate.py +79 -0
- uncountable/types/api/entity/list_entities.py +53 -14
- uncountable/types/api/entity/lock_entity.py +45 -0
- uncountable/types/api/entity/lookup_entity.py +116 -0
- uncountable/types/api/entity/resolve_entity_ids.py +19 -10
- uncountable/types/api/entity/set_entity_field_values.py +44 -0
- uncountable/types/api/entity/set_values.py +15 -8
- uncountable/types/api/entity/transition_entity_phase.py +27 -12
- uncountable/types/api/entity/unlock_entity.py +44 -0
- uncountable/types/api/equipment/__init__.py +1 -0
- uncountable/types/api/equipment/associate_equipment_input.py +43 -0
- uncountable/types/api/field_options/__init__.py +1 -0
- uncountable/types/api/field_options/upsert_field_options.py +55 -0
- uncountable/types/api/files/__init__.py +1 -0
- uncountable/types/api/files/download_file.py +77 -0
- uncountable/types/api/id_source/list_id_source.py +20 -11
- uncountable/types/api/id_source/match_id_source.py +15 -10
- uncountable/types/api/input_groups/get_input_group_names.py +16 -7
- uncountable/types/api/inputs/create_inputs.py +28 -14
- uncountable/types/api/inputs/get_input_data.py +34 -16
- uncountable/types/api/inputs/get_input_names.py +19 -10
- uncountable/types/api/inputs/get_inputs_data.py +29 -11
- uncountable/types/api/inputs/set_input_attribute_values.py +16 -10
- uncountable/types/api/inputs/set_input_category.py +44 -0
- uncountable/types/api/inputs/set_input_subcategories.py +45 -0
- uncountable/types/api/inputs/set_intermediate_type.py +50 -0
- uncountable/types/api/integrations/__init__.py +1 -0
- uncountable/types/api/integrations/publish_realtime_data.py +41 -0
- uncountable/types/api/integrations/push_notification.py +49 -0
- uncountable/types/api/integrations/register_sockets_token.py +41 -0
- uncountable/types/api/listing/__init__.py +1 -0
- uncountable/types/api/listing/fetch_listing.py +58 -0
- uncountable/types/api/material_families/__init__.py +1 -0
- uncountable/types/api/material_families/update_entity_material_families.py +47 -0
- uncountable/types/api/notebooks/__init__.py +1 -0
- uncountable/types/api/notebooks/add_notebook_content.py +119 -0
- uncountable/types/api/outputs/get_output_data.py +32 -17
- uncountable/types/api/outputs/get_output_names.py +18 -9
- uncountable/types/api/outputs/get_output_organization.py +173 -0
- uncountable/types/api/outputs/resolve_output_conditions.py +23 -11
- uncountable/types/api/permissions/set_core_permissions.py +31 -15
- uncountable/types/api/project/get_projects.py +20 -11
- uncountable/types/api/project/get_projects_data.py +23 -14
- uncountable/types/api/recipe_links/create_recipe_link.py +17 -10
- uncountable/types/api/recipe_links/remove_recipe_link.py +45 -0
- uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +19 -10
- uncountable/types/api/recipes/add_recipe_to_project.py +42 -0
- uncountable/types/api/recipes/add_time_series_data.py +64 -0
- uncountable/types/api/recipes/archive_recipes.py +14 -7
- uncountable/types/api/recipes/associate_recipe_as_input.py +16 -8
- uncountable/types/api/recipes/associate_recipe_as_lot.py +14 -7
- uncountable/types/api/recipes/clear_recipe_outputs.py +42 -0
- uncountable/types/api/recipes/create_mix_order.py +44 -0
- uncountable/types/api/recipes/create_recipe.py +21 -14
- uncountable/types/api/recipes/create_recipes.py +25 -13
- uncountable/types/api/recipes/disassociate_recipe_as_input.py +14 -7
- uncountable/types/api/recipes/edit_recipe_inputs.py +208 -19
- uncountable/types/api/recipes/get_column_calculation_values.py +57 -0
- uncountable/types/api/recipes/get_curve.py +15 -9
- uncountable/types/api/recipes/get_recipe_calculations.py +17 -11
- uncountable/types/api/recipes/get_recipe_links.py +14 -8
- uncountable/types/api/recipes/get_recipe_names.py +16 -7
- uncountable/types/api/recipes/get_recipe_output_metadata.py +16 -10
- uncountable/types/api/recipes/get_recipes_data.py +96 -45
- uncountable/types/api/recipes/lock_recipes.py +64 -0
- uncountable/types/api/recipes/remove_recipe_from_project.py +42 -0
- uncountable/types/api/recipes/set_recipe_inputs.py +19 -13
- uncountable/types/api/recipes/set_recipe_metadata.py +14 -7
- uncountable/types/api/recipes/set_recipe_output_annotations.py +114 -0
- uncountable/types/api/recipes/set_recipe_output_file.py +55 -0
- uncountable/types/api/recipes/set_recipe_outputs.py +40 -15
- uncountable/types/api/recipes/set_recipe_tags.py +30 -13
- uncountable/types/api/recipes/set_recipe_total.py +59 -0
- uncountable/types/api/recipes/unarchive_recipes.py +41 -0
- uncountable/types/api/recipes/unlock_recipes.py +51 -0
- uncountable/types/api/runsheet/__init__.py +1 -0
- uncountable/types/api/runsheet/complete_async_upload.py +41 -0
- uncountable/types/api/triggers/run_trigger.py +15 -8
- uncountable/types/api/uploader/__init__.py +1 -0
- uncountable/types/api/uploader/complete_async_parse.py +46 -0
- uncountable/types/api/uploader/invoke_uploader.py +46 -0
- uncountable/types/api/user/__init__.py +1 -0
- uncountable/types/api/user/get_current_user_info.py +40 -0
- uncountable/types/async_batch.py +8 -52
- uncountable/types/async_batch_processor.py +694 -18
- uncountable/types/async_batch_t.py +108 -0
- uncountable/types/async_jobs.py +8 -0
- uncountable/types/async_jobs_t.py +52 -0
- uncountable/types/auth_retrieval.py +11 -0
- uncountable/types/auth_retrieval_t.py +75 -0
- uncountable/types/base.py +5 -80
- uncountable/types/base_t.py +87 -0
- uncountable/types/calculations.py +3 -19
- uncountable/types/calculations_t.py +26 -0
- uncountable/types/chemical_structure.py +3 -23
- uncountable/types/chemical_structure_t.py +28 -0
- uncountable/types/client_base.py +1170 -88
- uncountable/types/client_config.py +8 -0
- uncountable/types/client_config_t.py +36 -0
- uncountable/types/curves.py +5 -43
- uncountable/types/curves_t.py +50 -0
- uncountable/types/data.py +12 -0
- uncountable/types/data_t.py +103 -0
- uncountable/types/entity.py +8 -270
- uncountable/types/entity_t.py +446 -0
- uncountable/types/experiment_groups.py +3 -19
- uncountable/types/experiment_groups_t.py +26 -0
- uncountable/types/exports.py +8 -0
- uncountable/types/exports_t.py +34 -0
- uncountable/types/field_values.py +25 -61
- uncountable/types/field_values_t.py +302 -0
- uncountable/types/fields.py +3 -20
- uncountable/types/fields_t.py +27 -0
- uncountable/types/generic_upload.py +14 -0
- uncountable/types/generic_upload_t.py +119 -0
- uncountable/types/id_source.py +7 -45
- uncountable/types/id_source_t.py +68 -0
- uncountable/types/identifier.py +6 -50
- uncountable/types/identifier_t.py +62 -0
- uncountable/types/input_attributes.py +3 -25
- uncountable/types/input_attributes_t.py +29 -0
- uncountable/types/inputs.py +6 -57
- uncountable/types/inputs_t.py +82 -0
- uncountable/types/integration_server.py +8 -0
- uncountable/types/integration_server_t.py +46 -0
- uncountable/types/integration_session.py +10 -0
- uncountable/types/integration_session_t.py +60 -0
- uncountable/types/integrations.py +10 -0
- uncountable/types/integrations_t.py +62 -0
- uncountable/types/job_definition.py +28 -0
- uncountable/types/job_definition_t.py +285 -0
- uncountable/types/listing.py +9 -0
- uncountable/types/listing_t.py +51 -0
- uncountable/types/notices.py +8 -0
- uncountable/types/notices_t.py +37 -0
- uncountable/types/notifications.py +11 -0
- uncountable/types/notifications_t.py +74 -0
- uncountable/types/outputs.py +3 -22
- uncountable/types/outputs_t.py +29 -0
- uncountable/types/overrides.py +9 -0
- uncountable/types/overrides_t.py +49 -0
- uncountable/types/permissions.py +3 -42
- uncountable/types/permissions_t.py +45 -0
- uncountable/types/phases.py +3 -19
- uncountable/types/phases_t.py +26 -0
- uncountable/types/post_base.py +3 -26
- uncountable/types/post_base_t.py +29 -0
- uncountable/types/queued_job.py +17 -0
- uncountable/types/queued_job_t.py +140 -0
- uncountable/types/recipe_identifiers.py +7 -58
- uncountable/types/recipe_identifiers_t.py +75 -0
- uncountable/types/recipe_inputs.py +4 -26
- uncountable/types/recipe_inputs_t.py +29 -0
- uncountable/types/recipe_links.py +4 -46
- uncountable/types/recipe_links_t.py +53 -0
- uncountable/types/recipe_metadata.py +5 -48
- uncountable/types/recipe_metadata_t.py +57 -0
- uncountable/types/recipe_output_metadata.py +3 -20
- uncountable/types/recipe_output_metadata_t.py +27 -0
- uncountable/types/recipe_tags.py +3 -19
- uncountable/types/recipe_tags_t.py +26 -0
- uncountable/types/recipe_workflow_steps.py +9 -73
- uncountable/types/recipe_workflow_steps_t.py +95 -0
- uncountable/types/recipes.py +7 -0
- uncountable/types/recipes_t.py +25 -0
- uncountable/types/response.py +3 -21
- uncountable/types/response_t.py +26 -0
- uncountable/types/secret_retrieval.py +11 -0
- uncountable/types/secret_retrieval_t.py +75 -0
- uncountable/types/sockets.py +20 -0
- uncountable/types/sockets_t.py +169 -0
- uncountable/types/structured_filters.py +25 -0
- uncountable/types/structured_filters_t.py +248 -0
- uncountable/types/units.py +3 -19
- uncountable/types/units_t.py +26 -0
- uncountable/types/uploader.py +24 -0
- uncountable/types/uploader_t.py +222 -0
- uncountable/types/users.py +3 -20
- uncountable/types/users_t.py +27 -0
- uncountable/types/webhook_job.py +9 -0
- uncountable/types/webhook_job_t.py +48 -0
- uncountable/types/workflows.py +4 -28
- uncountable/types/workflows_t.py +38 -0
- uncountablepythonsdk-0.0.131.dist-info/METADATA +64 -0
- uncountablepythonsdk-0.0.131.dist-info/RECORD +363 -0
- {UncountablePythonSDK-0.0.24.dist-info → uncountablepythonsdk-0.0.131.dist-info}/WHEEL +1 -1
- {UncountablePythonSDK-0.0.24.dist-info → uncountablepythonsdk-0.0.131.dist-info}/top_level.txt +0 -1
- UncountablePythonSDK-0.0.24.dist-info/METADATA +0 -47
- UncountablePythonSDK-0.0.24.dist-info/RECORD +0 -216
- docs/quickstart.md +0 -19
- examples/recipe-import/importer.py +0 -39
- type_spec/external/api/batch/execute_batch.yaml +0 -56
- type_spec/external/api/batch/execute_batch_load_async.yaml +0 -18
- type_spec/external/api/chemical/convert_chemical_formats.yaml +0 -33
- type_spec/external/api/entity/create_entities.yaml +0 -45
- type_spec/external/api/entity/create_entity.yaml +0 -51
- type_spec/external/api/entity/get_entities_data.yaml +0 -29
- type_spec/external/api/entity/list_entities.yaml +0 -52
- type_spec/external/api/entity/resolve_entity_ids.yaml +0 -29
- type_spec/external/api/entity/set_values.yaml +0 -18
- type_spec/external/api/entity/transition_entity_phase.yaml +0 -44
- type_spec/external/api/id_source/list_id_source.yaml +0 -35
- type_spec/external/api/id_source/match_id_source.yaml +0 -32
- type_spec/external/api/input_groups/get_input_group_names.yaml +0 -29
- type_spec/external/api/inputs/create_inputs.yaml +0 -48
- type_spec/external/api/inputs/get_input_data.yaml +0 -95
- type_spec/external/api/inputs/get_input_names.yaml +0 -38
- type_spec/external/api/inputs/get_inputs_data.yaml +0 -82
- type_spec/external/api/inputs/set_input_attribute_values.yaml +0 -33
- type_spec/external/api/outputs/get_output_data.yaml +0 -92
- type_spec/external/api/outputs/get_output_names.yaml +0 -35
- type_spec/external/api/outputs/resolve_output_conditions.yaml +0 -50
- type_spec/external/api/permissions/set_core_permissions.yaml +0 -69
- type_spec/external/api/project/get_projects.yaml +0 -42
- type_spec/external/api/project/get_projects_data.yaml +0 -50
- type_spec/external/api/recipe_links/create_recipe_link.yaml +0 -25
- type_spec/external/api/recipe_metadata/get_recipe_metadata_data.yaml +0 -41
- type_spec/external/api/recipes/archive_recipes.yaml +0 -20
- type_spec/external/api/recipes/associate_recipe_as_input.yaml +0 -19
- type_spec/external/api/recipes/associate_recipe_as_lot.yaml +0 -19
- type_spec/external/api/recipes/create_recipe.yaml +0 -39
- type_spec/external/api/recipes/create_recipes.yaml +0 -47
- type_spec/external/api/recipes/disassociate_recipe_as_input.yaml +0 -16
- type_spec/external/api/recipes/edit_recipe_inputs.yaml +0 -85
- type_spec/external/api/recipes/get_curve.yaml +0 -21
- type_spec/external/api/recipes/get_recipe_calculations.yaml +0 -39
- type_spec/external/api/recipes/get_recipe_links.yaml +0 -26
- type_spec/external/api/recipes/get_recipe_names.yaml +0 -29
- type_spec/external/api/recipes/get_recipe_output_metadata.yaml +0 -36
- type_spec/external/api/recipes/get_recipes_data.yaml +0 -244
- type_spec/external/api/recipes/set_recipe_inputs.yaml +0 -42
- type_spec/external/api/recipes/set_recipe_metadata.yaml +0 -20
- type_spec/external/api/recipes/set_recipe_outputs.yaml +0 -52
- type_spec/external/api/recipes/set_recipe_tags.yaml +0 -62
- type_spec/external/api/triggers/run_trigger.yaml +0 -18
- uncountable/integration/types.py +0 -89
|
@@ -0,0 +1,100 @@
|
|
|
1
|
+
import json
|
|
2
|
+
import time
|
|
3
|
+
from dataclasses import dataclass
|
|
4
|
+
from decimal import Decimal
|
|
5
|
+
|
|
6
|
+
from uncountable.integration.job import JobArguments, WebhookJob, register_job
|
|
7
|
+
from uncountable.types import (
|
|
8
|
+
base_t,
|
|
9
|
+
identifier_t,
|
|
10
|
+
job_definition_t,
|
|
11
|
+
sockets_t,
|
|
12
|
+
)
|
|
13
|
+
from uncountable.types.integration_session_t import IntegrationSessionInstrument
|
|
14
|
+
from websockets.sync.client import connect
|
|
15
|
+
from websockets.typing import Data
|
|
16
|
+
|
|
17
|
+
from pkgs.argument_parser.argument_parser import CachedParser
|
|
18
|
+
from pkgs.serialization_util import serialize_for_api
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@dataclass(kw_only=True)
|
|
22
|
+
class InstrumentPayload:
|
|
23
|
+
equipment_id: base_t.ObjectId
|
|
24
|
+
|
|
25
|
+
|
|
26
|
+
@register_job
|
|
27
|
+
class InstrumentExample(WebhookJob[InstrumentPayload]):
|
|
28
|
+
def run(
|
|
29
|
+
self, args: JobArguments, payload: InstrumentPayload
|
|
30
|
+
) -> job_definition_t.JobResult:
|
|
31
|
+
parser: CachedParser[sockets_t.SocketResponse] = CachedParser(
|
|
32
|
+
sockets_t.SocketResponse # type:ignore[arg-type]
|
|
33
|
+
)
|
|
34
|
+
|
|
35
|
+
def parse_message(message: Data) -> sockets_t.SocketEventData | None:
|
|
36
|
+
try:
|
|
37
|
+
return parser.parse_api(json.loads(message)).data
|
|
38
|
+
except ValueError:
|
|
39
|
+
return None
|
|
40
|
+
|
|
41
|
+
integration_session = IntegrationSessionInstrument(
|
|
42
|
+
equipment_key=identifier_t.IdentifierKeyId(id=payload.equipment_id)
|
|
43
|
+
)
|
|
44
|
+
registration_info = args.client.register_sockets_token(
|
|
45
|
+
socket_request=sockets_t.SocketRequestIntegrationSession(
|
|
46
|
+
integration_session=integration_session
|
|
47
|
+
)
|
|
48
|
+
).response
|
|
49
|
+
token = registration_info.token
|
|
50
|
+
room_key = registration_info.room_key
|
|
51
|
+
args.logger.log_info(f"Token: {token}")
|
|
52
|
+
|
|
53
|
+
with connect(
|
|
54
|
+
"ws://host.docker.internal:8765",
|
|
55
|
+
additional_headers={
|
|
56
|
+
"Authorization": f"Bearer {token}",
|
|
57
|
+
"X-UNC-EXTERNAL": "true",
|
|
58
|
+
},
|
|
59
|
+
) as ws:
|
|
60
|
+
ws.send(
|
|
61
|
+
json.dumps(
|
|
62
|
+
serialize_for_api(
|
|
63
|
+
sockets_t.JoinRoomWithTokenSocketClientMessage(token=token)
|
|
64
|
+
)
|
|
65
|
+
)
|
|
66
|
+
)
|
|
67
|
+
for i in range(10):
|
|
68
|
+
args.logger.log_info("Sending reading...")
|
|
69
|
+
ws.send(
|
|
70
|
+
json.dumps(
|
|
71
|
+
serialize_for_api(
|
|
72
|
+
sockets_t.SendInstrumentReadingClientMessage(
|
|
73
|
+
value=Decimal(i * 100), room_key=room_key
|
|
74
|
+
)
|
|
75
|
+
)
|
|
76
|
+
)
|
|
77
|
+
)
|
|
78
|
+
time.sleep(0.75)
|
|
79
|
+
|
|
80
|
+
while True:
|
|
81
|
+
message = parse_message(ws.recv())
|
|
82
|
+
match message:
|
|
83
|
+
case sockets_t.UsersInRoomUpdatedEventData():
|
|
84
|
+
num_users = len(message.user_ids)
|
|
85
|
+
if num_users <= 1:
|
|
86
|
+
break
|
|
87
|
+
else:
|
|
88
|
+
args.logger.log_info(
|
|
89
|
+
f"Session still open, {num_users} users in room."
|
|
90
|
+
)
|
|
91
|
+
case _:
|
|
92
|
+
args.logger.log_info("Session still open...")
|
|
93
|
+
continue
|
|
94
|
+
|
|
95
|
+
args.logger.log_info("Session closed.")
|
|
96
|
+
return job_definition_t.JobResult(success=True)
|
|
97
|
+
|
|
98
|
+
@property
|
|
99
|
+
def webhook_payload_type(self) -> type:
|
|
100
|
+
return InstrumentPayload
|
|
@@ -0,0 +1,140 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
from decimal import Decimal
|
|
3
|
+
|
|
4
|
+
from uncountable.integration.job import JobArguments, WebhookJob, register_job
|
|
5
|
+
from uncountable.types import (
|
|
6
|
+
base_t,
|
|
7
|
+
entity_t,
|
|
8
|
+
generic_upload_t,
|
|
9
|
+
identifier_t,
|
|
10
|
+
job_definition_t,
|
|
11
|
+
notifications_t,
|
|
12
|
+
uploader_t,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(kw_only=True)
|
|
17
|
+
class ParsePayload:
|
|
18
|
+
async_job_id: base_t.ObjectId
|
|
19
|
+
|
|
20
|
+
|
|
21
|
+
@register_job
|
|
22
|
+
class ParseExample(WebhookJob[ParsePayload]):
|
|
23
|
+
def run(
|
|
24
|
+
self, args: JobArguments, payload: ParsePayload
|
|
25
|
+
) -> job_definition_t.JobResult:
|
|
26
|
+
user_id: base_t.ObjectId | None = None
|
|
27
|
+
recipe_id: base_t.ObjectId | None = None
|
|
28
|
+
file_name: str | None = None
|
|
29
|
+
data = args.client.get_entities_data(
|
|
30
|
+
entity_ids=[payload.async_job_id], entity_type=entity_t.EntityType.ASYNC_JOB
|
|
31
|
+
)
|
|
32
|
+
for field_value in data.entity_details[0].field_values:
|
|
33
|
+
if field_value.field_ref_name == "core_async_job_jobData":
|
|
34
|
+
assert isinstance(field_value.value, dict)
|
|
35
|
+
assert isinstance(field_value.value["user_id"], int)
|
|
36
|
+
user_id = field_value.value["user_id"]
|
|
37
|
+
elif (
|
|
38
|
+
field_value.field_ref_name
|
|
39
|
+
== "unc_async_job_custom_parser_recipe_ids_in_view"
|
|
40
|
+
):
|
|
41
|
+
if field_value.value is None:
|
|
42
|
+
continue
|
|
43
|
+
assert isinstance(field_value.value, list)
|
|
44
|
+
if len(field_value.value) > 0:
|
|
45
|
+
assert isinstance(field_value.value[0], int)
|
|
46
|
+
recipe_id = field_value.value[0]
|
|
47
|
+
elif field_value.field_ref_name == "unc_async_job_custom_parser_input_file":
|
|
48
|
+
assert isinstance(field_value.value, list)
|
|
49
|
+
assert len(field_value.value) == 1
|
|
50
|
+
assert isinstance(field_value.value[0], dict)
|
|
51
|
+
assert isinstance(field_value.value[0]["name"], str)
|
|
52
|
+
file_name = field_value.value[0]["name"]
|
|
53
|
+
|
|
54
|
+
assert user_id is not None
|
|
55
|
+
assert file_name is not None
|
|
56
|
+
|
|
57
|
+
dummy_parsed_file_data: list[uploader_t.ParsedFileData] = [
|
|
58
|
+
uploader_t.ParsedFileData(
|
|
59
|
+
file_name=file_name,
|
|
60
|
+
file_structures=[
|
|
61
|
+
uploader_t.DataChannel(
|
|
62
|
+
type=uploader_t.StructureElementType.CHANNEL,
|
|
63
|
+
channel=uploader_t.TextChannelData(
|
|
64
|
+
name="column1",
|
|
65
|
+
type=uploader_t.ChannelType.TEXT_CHANNEL,
|
|
66
|
+
data=[
|
|
67
|
+
uploader_t.StringValue(value="value1"),
|
|
68
|
+
uploader_t.StringValue(value="value4"),
|
|
69
|
+
uploader_t.StringValue(value="value7"),
|
|
70
|
+
],
|
|
71
|
+
),
|
|
72
|
+
),
|
|
73
|
+
uploader_t.DataChannel(
|
|
74
|
+
type=uploader_t.StructureElementType.CHANNEL,
|
|
75
|
+
channel=uploader_t.TextChannelData(
|
|
76
|
+
name="column2",
|
|
77
|
+
type=uploader_t.ChannelType.TEXT_CHANNEL,
|
|
78
|
+
data=[
|
|
79
|
+
uploader_t.StringValue(value="value2"),
|
|
80
|
+
uploader_t.StringValue(value="value5"),
|
|
81
|
+
uploader_t.StringValue(value="value8"),
|
|
82
|
+
],
|
|
83
|
+
),
|
|
84
|
+
),
|
|
85
|
+
uploader_t.DataChannel(
|
|
86
|
+
type=uploader_t.StructureElementType.CHANNEL,
|
|
87
|
+
channel=uploader_t.TextChannelData(
|
|
88
|
+
name="column3",
|
|
89
|
+
type=uploader_t.ChannelType.TEXT_CHANNEL,
|
|
90
|
+
data=[
|
|
91
|
+
uploader_t.StringValue(value="value3"),
|
|
92
|
+
uploader_t.StringValue(value="value6"),
|
|
93
|
+
uploader_t.StringValue(value="value9"),
|
|
94
|
+
],
|
|
95
|
+
),
|
|
96
|
+
),
|
|
97
|
+
uploader_t.HeaderEntry(
|
|
98
|
+
type=uploader_t.StructureElementType.HEADER,
|
|
99
|
+
value=uploader_t.TextHeaderData(
|
|
100
|
+
name="file_source",
|
|
101
|
+
type=uploader_t.HeaderType.TEXT_HEADER,
|
|
102
|
+
data=uploader_t.StringValue(value="my_file_to_upload.xlsx"),
|
|
103
|
+
),
|
|
104
|
+
),
|
|
105
|
+
uploader_t.HeaderEntry(
|
|
106
|
+
type=uploader_t.StructureElementType.HEADER,
|
|
107
|
+
value=uploader_t.NumericHeaderData(
|
|
108
|
+
name="file structure number",
|
|
109
|
+
data=uploader_t.DecimalValue(value=Decimal(99)),
|
|
110
|
+
),
|
|
111
|
+
),
|
|
112
|
+
],
|
|
113
|
+
)
|
|
114
|
+
]
|
|
115
|
+
|
|
116
|
+
complete_async_parse_req = args.batch_processor.complete_async_parse(
|
|
117
|
+
parsed_file_data=dummy_parsed_file_data,
|
|
118
|
+
async_job_key=identifier_t.IdentifierKeyId(id=payload.async_job_id),
|
|
119
|
+
upload_destination=generic_upload_t.UploadDestinationRecipe(
|
|
120
|
+
recipe_key=identifier_t.IdentifierKeyId(id=recipe_id or 1)
|
|
121
|
+
),
|
|
122
|
+
)
|
|
123
|
+
|
|
124
|
+
args.batch_processor.push_notification(
|
|
125
|
+
depends_on=[complete_async_parse_req.batch_reference],
|
|
126
|
+
notification_targets=[
|
|
127
|
+
notifications_t.NotificationTargetUser(
|
|
128
|
+
user_key=identifier_t.IdentifierKeyId(id=user_id)
|
|
129
|
+
)
|
|
130
|
+
],
|
|
131
|
+
subject="Upload complete",
|
|
132
|
+
message="Your file has been uploaded",
|
|
133
|
+
display_notice=True,
|
|
134
|
+
)
|
|
135
|
+
|
|
136
|
+
return job_definition_t.JobResult(success=True)
|
|
137
|
+
|
|
138
|
+
@property
|
|
139
|
+
def webhook_payload_type(self) -> type:
|
|
140
|
+
return ParsePayload
|
|
@@ -0,0 +1,61 @@
|
|
|
1
|
+
import random
|
|
2
|
+
from dataclasses import dataclass
|
|
3
|
+
from datetime import UTC, datetime
|
|
4
|
+
from decimal import Decimal
|
|
5
|
+
|
|
6
|
+
from uncountable.integration.job import JobArguments, WebhookJob, register_job
|
|
7
|
+
from uncountable.types import (
|
|
8
|
+
base_t,
|
|
9
|
+
identifier_t,
|
|
10
|
+
job_definition_t,
|
|
11
|
+
recipe_links_t,
|
|
12
|
+
set_recipe_outputs_t,
|
|
13
|
+
)
|
|
14
|
+
|
|
15
|
+
|
|
16
|
+
@dataclass(kw_only=True)
|
|
17
|
+
class PredictionsPayload:
|
|
18
|
+
output_id: base_t.ObjectId
|
|
19
|
+
recipe_ids: list[base_t.ObjectId]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
@register_job
|
|
23
|
+
class PredictionsExample(WebhookJob[PredictionsPayload]):
|
|
24
|
+
def run(
|
|
25
|
+
self, args: JobArguments, payload: PredictionsPayload
|
|
26
|
+
) -> job_definition_t.JobResult:
|
|
27
|
+
recipe_data = args.client.get_recipes_data(recipe_ids=payload.recipe_ids)
|
|
28
|
+
formatted_datetime = datetime.now(UTC).strftime("%Y-%m-%d %H:%M:%S")
|
|
29
|
+
|
|
30
|
+
for recipe in recipe_data.recipes:
|
|
31
|
+
test_sample_name = f"Predictions Model ({formatted_datetime})"
|
|
32
|
+
created_recipe_id = args.client.create_recipe(
|
|
33
|
+
name=test_sample_name,
|
|
34
|
+
material_family_id=1,
|
|
35
|
+
workflow_id=1,
|
|
36
|
+
definition_key=identifier_t.IdentifierKeyRefName(
|
|
37
|
+
ref_name="unc_test_sample"
|
|
38
|
+
),
|
|
39
|
+
).result_id
|
|
40
|
+
args.client.set_recipe_outputs(
|
|
41
|
+
output_data=[
|
|
42
|
+
set_recipe_outputs_t.RecipeOutputValue(
|
|
43
|
+
recipe_id=created_recipe_id,
|
|
44
|
+
output_id=payload.output_id,
|
|
45
|
+
experiment_num=1,
|
|
46
|
+
value_numeric=Decimal(random.random() * 10),
|
|
47
|
+
)
|
|
48
|
+
]
|
|
49
|
+
)
|
|
50
|
+
args.client.create_recipe_link(
|
|
51
|
+
recipe_from_key=identifier_t.IdentifierKeyId(id=recipe.recipe_id),
|
|
52
|
+
recipe_to_key=identifier_t.IdentifierKeyId(id=created_recipe_id),
|
|
53
|
+
link_type=recipe_links_t.RecipeLinkType.CHILD,
|
|
54
|
+
name=test_sample_name,
|
|
55
|
+
)
|
|
56
|
+
|
|
57
|
+
return job_definition_t.JobResult(success=True)
|
|
58
|
+
|
|
59
|
+
@property
|
|
60
|
+
def webhook_payload_type(self) -> type:
|
|
61
|
+
return PredictionsPayload
|
|
@@ -0,0 +1,39 @@
|
|
|
1
|
+
from io import BytesIO
|
|
2
|
+
|
|
3
|
+
from uncountable.core.file_upload import DataFileUpload, FileUpload
|
|
4
|
+
from uncountable.integration.job import JobArguments, RunsheetWebhookJob, register_job
|
|
5
|
+
from uncountable.types import (
|
|
6
|
+
download_file_t,
|
|
7
|
+
entity_t,
|
|
8
|
+
identifier_t,
|
|
9
|
+
webhook_job_t,
|
|
10
|
+
)
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@register_job
|
|
14
|
+
class StandardRunsheetGenerator(RunsheetWebhookJob):
|
|
15
|
+
def build_runsheet(
|
|
16
|
+
self,
|
|
17
|
+
*,
|
|
18
|
+
args: JobArguments,
|
|
19
|
+
payload: webhook_job_t.RunsheetWebhookPayload,
|
|
20
|
+
) -> FileUpload:
|
|
21
|
+
args.logger.log_info("Retrieving pre-exported runsheet file from async job")
|
|
22
|
+
|
|
23
|
+
file_query = download_file_t.FileDownloadQueryEntityField(
|
|
24
|
+
entity=entity_t.EntityIdentifier(
|
|
25
|
+
type=entity_t.EntityType.ASYNC_JOB,
|
|
26
|
+
identifier_key=identifier_t.IdentifierKeyId(id=payload.async_job_id),
|
|
27
|
+
),
|
|
28
|
+
field_key=identifier_t.IdentifierKeyRefName(
|
|
29
|
+
ref_name="unc_async_job_export_runsheet_recipe_export"
|
|
30
|
+
),
|
|
31
|
+
)
|
|
32
|
+
|
|
33
|
+
downloaded_files = args.client.download_files(file_query=file_query)
|
|
34
|
+
|
|
35
|
+
file_data = downloaded_files[0].data.read()
|
|
36
|
+
return DataFileUpload(
|
|
37
|
+
data=BytesIO(file_data),
|
|
38
|
+
name=downloaded_files[0].name,
|
|
39
|
+
)
|
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
from dataclasses import dataclass
|
|
2
|
+
|
|
3
|
+
from uncountable.integration.job import JobArguments, WebhookJob, register_job
|
|
4
|
+
from uncountable.types import job_definition_t
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
@dataclass(kw_only=True)
|
|
8
|
+
class ExampleWebhookPayload:
|
|
9
|
+
id: int
|
|
10
|
+
message: str
|
|
11
|
+
|
|
12
|
+
|
|
13
|
+
@register_job
|
|
14
|
+
class WebhookExample(WebhookJob[ExampleWebhookPayload]):
|
|
15
|
+
def run(
|
|
16
|
+
self, args: JobArguments, payload: ExampleWebhookPayload
|
|
17
|
+
) -> job_definition_t.JobResult:
|
|
18
|
+
args.logger.log_info(f"webhook invoked with payload: {payload}")
|
|
19
|
+
return job_definition_t.JobResult(success=True)
|
|
20
|
+
|
|
21
|
+
@property
|
|
22
|
+
def webhook_payload_type(self) -> type:
|
|
23
|
+
return ExampleWebhookPayload
|
|
@@ -0,0 +1,104 @@
|
|
|
1
|
+
base_url: http://host.docker.internal: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
|
+
logging_settings:
|
|
20
|
+
enabled: true
|
|
21
|
+
share_with_user_groups:
|
|
22
|
+
- admin:
|
|
23
|
+
type: ref_name
|
|
24
|
+
ref_name: admin
|
|
25
|
+
- id: concurrent_cron_1
|
|
26
|
+
enabled: true
|
|
27
|
+
type: cron
|
|
28
|
+
name: MyConcurrentCron - 1
|
|
29
|
+
cron_spec: "* * * * *"
|
|
30
|
+
executor:
|
|
31
|
+
type: script
|
|
32
|
+
import_path: concurrent_cron
|
|
33
|
+
subqueue_name: subqueue_1
|
|
34
|
+
- id: concurrent_cron_2
|
|
35
|
+
enabled: true
|
|
36
|
+
type: cron
|
|
37
|
+
name: MyConcurrentCron - 2
|
|
38
|
+
cron_spec: "* * * * *"
|
|
39
|
+
executor:
|
|
40
|
+
type: script
|
|
41
|
+
import_path: concurrent_cron
|
|
42
|
+
subqueue_name: subqueue_2
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
- id: example_wh1
|
|
46
|
+
type: webhook
|
|
47
|
+
name: Webhook 1
|
|
48
|
+
signature_key_secret:
|
|
49
|
+
type: env
|
|
50
|
+
env_key: WH1_SIGNATURE_KEY
|
|
51
|
+
executor:
|
|
52
|
+
type: script
|
|
53
|
+
import_path: example_wh
|
|
54
|
+
- id: example_wh2
|
|
55
|
+
type: webhook
|
|
56
|
+
name: Webhook 2
|
|
57
|
+
signature_key_secret:
|
|
58
|
+
type: env
|
|
59
|
+
env_key: WH2_SIGNATURE_KEY
|
|
60
|
+
executor:
|
|
61
|
+
type: script
|
|
62
|
+
import_path: example_wh
|
|
63
|
+
- id: example_http
|
|
64
|
+
type: custom_http
|
|
65
|
+
name: Custom HTTP
|
|
66
|
+
executor:
|
|
67
|
+
type: script
|
|
68
|
+
import_path: example_http
|
|
69
|
+
- id: example_runsheet_wh
|
|
70
|
+
type: webhook
|
|
71
|
+
name: Runsheet Webhook
|
|
72
|
+
signature_key_secret:
|
|
73
|
+
type: env
|
|
74
|
+
env_key: WH_RUNSHEET_SIGNATURE_KEY
|
|
75
|
+
executor:
|
|
76
|
+
type: script
|
|
77
|
+
import_path: example_runsheet_wh
|
|
78
|
+
- id: example_instrument
|
|
79
|
+
type: webhook
|
|
80
|
+
name: Webhook Instrument Connection
|
|
81
|
+
signature_key_secret:
|
|
82
|
+
type: env
|
|
83
|
+
env_key: WH_INSTRUMENT_SIGNATURE_KEY
|
|
84
|
+
executor:
|
|
85
|
+
type: script
|
|
86
|
+
import_path: example_instrument
|
|
87
|
+
- id: example_predictions
|
|
88
|
+
type: webhook
|
|
89
|
+
name: Webook Predictions
|
|
90
|
+
signature_key_secret:
|
|
91
|
+
type: env
|
|
92
|
+
env_key: WH_PREDICTIONS_SIGNATURE_KEY
|
|
93
|
+
executor:
|
|
94
|
+
type: script
|
|
95
|
+
import_path: example_predictions
|
|
96
|
+
- id: example_parse
|
|
97
|
+
type: webhook
|
|
98
|
+
name: Webhook Parse
|
|
99
|
+
signature_key_secret:
|
|
100
|
+
type: env
|
|
101
|
+
env_key: WH_PARSE_SIGNATURE_KEY
|
|
102
|
+
executor:
|
|
103
|
+
type: script
|
|
104
|
+
import_path: example_parse
|
|
@@ -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 ==4.0.0.20250822",
|
|
13
|
+
"types-openpyxl == 3.*",
|
|
14
|
+
"types-pysftp == 0.*",
|
|
15
|
+
"types-pytz ==2025.*",
|
|
16
|
+
"types-requests == 2.*",
|
|
17
|
+
"types-simplejson == 3.*",
|
|
18
|
+
"pandas-stubs",
|
|
19
|
+
"xlrd == 2.*",
|
|
20
|
+
"msgspec == 0.19.*",
|
|
21
|
+
"websockets==15.0.1",
|
|
22
|
+
]
|
|
23
|
+
|
|
24
|
+
[tool.mypy]
|
|
25
|
+
strict = true
|
|
26
|
+
show_error_codes = true
|
|
27
|
+
check_untyped_defs = true
|
|
28
|
+
disallow_any_generics = false
|
|
29
|
+
disallow_incomplete_defs = true
|
|
30
|
+
disallow_subclassing_any = false
|
|
31
|
+
disallow_untyped_calls = false
|
|
32
|
+
disallow_untyped_decorators = true
|
|
33
|
+
disallow_untyped_defs = true
|
|
34
|
+
implicit_reexport = true
|
|
35
|
+
no_implicit_optional = true
|
|
36
|
+
no_implicit_reexport = true
|
|
37
|
+
strict_equality = true
|
|
38
|
+
warn_redundant_casts = true
|
|
39
|
+
warn_unused_ignores = false
|
|
40
|
+
warn_no_return = true
|
|
41
|
+
warn_return_any = true
|
|
42
|
+
local_partial_types = true
|
|
43
|
+
warn_unreachable = false
|
|
44
|
+
warn_unused_configs = true
|
|
45
|
+
exclude = [
|
|
46
|
+
"env"
|
|
47
|
+
]
|
|
48
|
+
|
|
49
|
+
[tool.ruff]
|
|
50
|
+
preview = true
|
|
51
|
+
lint.select = ['ALL']
|
|
52
|
+
lint.ignore = [
|
|
53
|
+
"A001", # Variable shadows python built-in. Nice to have
|
|
54
|
+
"A002", # Variable shadows python built-in. Nice to have
|
|
55
|
+
"A003", # Class attribute shadows python built-in. Nice to have
|
|
56
|
+
"ANN", # Missing type annotations. Skip in favor of mypy
|
|
57
|
+
"ARG", # Unused arguments. Skip
|
|
58
|
+
"B006", # Do not use mutable data structures for argument defaults. Priority.
|
|
59
|
+
"B023", # Function doesn't bind loop variable. Priority
|
|
60
|
+
"B904", # Exception handling raise from. Skip
|
|
61
|
+
"BLE", # Blind exception. Should Add
|
|
62
|
+
"C401", # Unecessary generator. Skip
|
|
63
|
+
"C403", # Unnecessary list comprehension. Skip
|
|
64
|
+
"C405", # Unnecessary list. rewrite as set. Skip
|
|
65
|
+
"C408", # Unnecessary dict call. Skip
|
|
66
|
+
"C416", # Unnecessary list comprehension. Skip
|
|
67
|
+
"C417", # Unnecessary use of map. Should Add
|
|
68
|
+
"COM812", # Trailing comma. Too opinionated. Skip
|
|
69
|
+
"CPY", # Copyright notices. Skip
|
|
70
|
+
"D", # Docstrings. Skip
|
|
71
|
+
"DOC", # Docstrings. Skip
|
|
72
|
+
"DTZ001", # Missing tzinfo. Should add
|
|
73
|
+
"DTZ002", # Use of today instead of now. Should add
|
|
74
|
+
"DTZ003", # Use of utcnow not allowed. Should add
|
|
75
|
+
"DTZ004", # Use of utcfrom timestamp not allowed. Should add
|
|
76
|
+
"DTZ005", # now without tz not allowed. Should add
|
|
77
|
+
"DTZ006", # use of from timestamp without tz not allowed. Should add
|
|
78
|
+
"DTZ007", # replace timezone after strptime. Should add
|
|
79
|
+
"DTZ011", # Use of today not allowed. Should add
|
|
80
|
+
"E501", # Line length. Skip
|
|
81
|
+
"EM101", # exception must not use a string literal. skip
|
|
82
|
+
"EM102", # exception must not use an f string. skip
|
|
83
|
+
"EM103", # exception must not use a format string. skip
|
|
84
|
+
"ERA", # Rules around commented code. Skip
|
|
85
|
+
"EXE002", # Executable files need shebang. Skip
|
|
86
|
+
"F841", # TEMPORARY DISABLE TO CLEAR UP BUILD. Unused variables. Prioritize.
|
|
87
|
+
"FBT001", # boolean positional args. Skip
|
|
88
|
+
"FBT002", # boolean default positional. Skip
|
|
89
|
+
"FBT003", # boolean positional. Skip
|
|
90
|
+
"FIX001", # Fixme comment. Skip
|
|
91
|
+
"FIX002", # todo comment. Skip
|
|
92
|
+
"FIX004", # hack comment. Skip
|
|
93
|
+
"FLY002", # Use F-String instead of join. Should Add
|
|
94
|
+
"FURB101", # replace read function. Skip
|
|
95
|
+
"FURB103", # opinionated file opening. Skip
|
|
96
|
+
"FURB113", # extend vs append. Skip
|
|
97
|
+
"FURB118", # opinionated rules about lambdas. skip
|
|
98
|
+
"FURB140", # starmap vs generator. Skip
|
|
99
|
+
"G004", # avoid f strings in log statements. Should add
|
|
100
|
+
"INP001", # implicit imports. use __init__. Skip
|
|
101
|
+
"ISC001", # rule conflicts with formatter. Skip
|
|
102
|
+
"ISC003", # Explicitly concatenated string should be implicitly concatenated. Skip
|
|
103
|
+
"N801", # class name case. Skip
|
|
104
|
+
"N802", # function name lower case. Skip
|
|
105
|
+
"N803", # argument name lower cas. Skip
|
|
106
|
+
"N804", # cls_ first variable. Should add
|
|
107
|
+
"N806", # lower case variable. Skip
|
|
108
|
+
"N812", # case consistency on import. Skip
|
|
109
|
+
"N815", # mix casing, skip
|
|
110
|
+
"N817", # don't use acronym. Should add
|
|
111
|
+
"N818", # exception override should be named with error. should add
|
|
112
|
+
"N999", # module naming. Should add
|
|
113
|
+
"PD002", # avoid inplace. Skip
|
|
114
|
+
"PD004", # .notna. Should add
|
|
115
|
+
"PD010", # .pivottable. Should add
|
|
116
|
+
"PD011", # use .to_numpy. Skip
|
|
117
|
+
"PD015", # use .merge. Should add
|
|
118
|
+
"PERF203", # avoid try except in loop. Skip
|
|
119
|
+
"PERF401", # use list comprehension. Skip
|
|
120
|
+
"PERF402", # use list.copy. Skip
|
|
121
|
+
"PERF403", # use dictionary comprehension. Skip
|
|
122
|
+
"S307", # avoid eval. Should add
|
|
123
|
+
"PGH003", # ignore specific rules. Skip
|
|
124
|
+
"PGH004", # ignore specific rules. Skip
|
|
125
|
+
"PLC0414", # import alias doesn't rename. Skip
|
|
126
|
+
"PLC0415", # import at top level. Skip
|
|
127
|
+
"PLC1901", # falsy empty string. Skip
|
|
128
|
+
"PLR0124", # self comparison. Skip
|
|
129
|
+
"PLR0402", # alias import. Skip
|
|
130
|
+
"PLR0911", # too many return statements. Skip
|
|
131
|
+
"PLR0912", # too many branches. Skip
|
|
132
|
+
"PLR0913", # too many arguments. Skip
|
|
133
|
+
"PLR0915", # too many statements. Skip
|
|
134
|
+
"PLR0916", # too many expressions. Skip
|
|
135
|
+
"PLR0917", # too many positional arguments. Skip
|
|
136
|
+
"PLR1714", # multiple comparisons. Skip
|
|
137
|
+
"PLR2004", # magic values. skip
|
|
138
|
+
"PLR5501", # use elif instead of else if. skip
|
|
139
|
+
"PLR6104", # use augmented assignment. confuses strings, wait for fix. skip
|
|
140
|
+
"PLR6201", # use a set literal for membership test. skip
|
|
141
|
+
"PLR6301", # method inference. skip
|
|
142
|
+
"PLW0108", # inline lambda. skip
|
|
143
|
+
"PLW0120", # else without break. skip
|
|
144
|
+
"PLW0602", # global withotu assignment. consider
|
|
145
|
+
"PLW0603", # discourage global. skip
|
|
146
|
+
"PLW1510", # subprocess run without check arg. skip
|
|
147
|
+
"PLW1514", # open without encoding. skip
|
|
148
|
+
"PLW2901", # for loop variable overwritten. skip
|
|
149
|
+
"PT001", # change ficture decorator. should add
|
|
150
|
+
"PT011", # use more specific raises decorator. should add
|
|
151
|
+
"PT018", # break down complex assertsions. skip
|
|
152
|
+
"PTH", # enforces new python path library usage. skip
|
|
153
|
+
"PYI030", # turn union of literals to just literal with multiple. should add
|
|
154
|
+
"PYI041", # use float instead of int | float. should remove floats
|
|
155
|
+
"RET", # enforces return semantics. break up and re-evaluate later
|
|
156
|
+
"RSE102", # unnecessary parens on exception. skip.
|
|
157
|
+
"RUF001", # ambiguous characters. skip
|
|
158
|
+
"RUF005", # prefer star to concatenation. skip
|
|
159
|
+
"RUF010", # use explicit conversion flag. skip
|
|
160
|
+
"RUF012", # type with class var. should add
|
|
161
|
+
"RUF015", # prefer next for single element. skip
|
|
162
|
+
"RUF100", # unused noqa. should add
|
|
163
|
+
"S", # should split up
|
|
164
|
+
"S101", # allow asserts. skip
|
|
165
|
+
"SIM102", # use single if instead of nested. skip
|
|
166
|
+
"SIM105", # use exception supress. skip
|
|
167
|
+
"SIM108", # use ternary. skip
|
|
168
|
+
"SIM110", # use any/all. should add
|
|
169
|
+
"SIM112", # case of env variable. skip
|
|
170
|
+
"SIM114", # combine if branches. skip
|
|
171
|
+
"SIM115", # use context handler for files. should add
|
|
172
|
+
"SIM117", # use single with. should add
|
|
173
|
+
"SLF001", # private member access. should add
|
|
174
|
+
"SLOT000", # subclass of string should define slot. should add
|
|
175
|
+
"T201", # print. skip
|
|
176
|
+
"T203", # pprint. skip
|
|
177
|
+
"TC001", # move application import into type checking. skip
|
|
178
|
+
"TC002", # move third party import into type checking. consider
|
|
179
|
+
"TC003", # move library into type checking lbock. consider
|
|
180
|
+
"TD", # todo comments. skip
|
|
181
|
+
"TID252", # eliminate relative imports from parents. skip
|
|
182
|
+
"TRY002", # create your own exception. skip
|
|
183
|
+
"TRY003", # avoid long messages. skip
|
|
184
|
+
"TRY004", # prefer type error. should add
|
|
185
|
+
"TRY201", # raise without exception name. consider
|
|
186
|
+
"TRY300", # move statement to else block. consider
|
|
187
|
+
"TRY301", # move raise to inner function. skip
|
|
188
|
+
"UP007", # use union for type annotations. should add
|
|
189
|
+
"UP013", # eliminate typeddict. should add
|
|
190
|
+
"UP031", # use format specifiers. should add
|
|
191
|
+
"B905", # zip strict. we have a deprecated pattern here, consider
|
|
192
|
+
"UP036", # outdated version block, consider
|
|
193
|
+
"RUF007", # prefer itertools.pairwise over zip, consider
|
|
194
|
+
"RUF022", # __all__ is not sorted. skip due to isort complication
|
|
195
|
+
"UP017", # use datetime.UTC, TODO add back in
|
|
196
|
+
"UP035", # replacing List with list, 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
|
+
"C420", # 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
|
+
known-first-party = ["pkgs"]
|
|
216
|
+
|
|
217
|
+
[tool.ruff.lint.mccabe]
|
|
218
|
+
max-complexity = 130 # goal would be to bring this down to ~50 or so
|
|
219
|
+
|
|
220
|
+
[tool.ruff.lint.pylint]
|
|
221
|
+
max-locals=50
|
|
222
|
+
|
|
223
|
+
[tool.setuptools]
|
|
224
|
+
py-modules = []
|