UncountablePythonSDK 0.0.30__tar.gz → 0.0.33__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.30 → uncountablepythonsdk-0.0.33}/.github/workflows/documentation.yml +4 -4
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/.github/workflows/publish.yml +5 -5
- {uncountablepythonsdk-0.0.30/UncountablePythonSDK.egg-info → uncountablepythonsdk-0.0.33}/PKG-INFO +3 -3
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33/UncountablePythonSDK.egg-info}/PKG-INFO +3 -3
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/UncountablePythonSDK.egg-info/SOURCES.txt +6 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/UncountablePythonSDK.egg-info/requires.txt +2 -2
- uncountablepythonsdk-0.0.33/docs/requirements.txt +7 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/argument_parser/argument_parser.py +41 -2
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/argument_parser/case_convert.py +4 -3
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization/__init__.py +2 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization/serial_class.py +31 -37
- uncountablepythonsdk-0.0.33/pkgs/serialization/serial_union.py +81 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization_util/__init__.py +1 -7
- uncountablepythonsdk-0.0.33/pkgs/serialization_util/convert_to_snakecase.py +27 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization_util/serialization_helpers.py +48 -59
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/builder.py +57 -1
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/emit_open_api.py +6 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/emit_python.py +23 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/emit_typescript.py +6 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/type_info/emit_type_info.py +43 -9
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pyproject.toml +2 -2
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/__init__.py +8 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/list_entities.py +7 -0
- uncountablepythonsdk-0.0.33/uncountable/types/api/inputs/set_intermediate_type.py +43 -0
- uncountablepythonsdk-0.0.33/uncountable/types/api/recipes/add_recipe_to_project.py +35 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/associate_recipe_as_input.py +1 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/edit_recipe_inputs.py +39 -1
- uncountablepythonsdk-0.0.33/uncountable/types/api/recipes/remove_recipe_from_project.py +35 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/set_recipe_outputs.py +2 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/client_base.py +72 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/inputs.py +1 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/recipe_workflow_steps.py +14 -3
- uncountablepythonsdk-0.0.33/uncountable/types/recipes.py +21 -0
- uncountablepythonsdk-0.0.30/docs/requirements.txt +0 -7
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/.gitignore +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/README.md +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/UncountablePythonSDK.egg-info/dependency_links.txt +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/UncountablePythonSDK.egg-info/top_level.txt +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/.gitignore +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/conf.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/index.md +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/justfile +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/quickstart.md +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/android-chrome-192x192.png +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/android-chrome-512x512.png +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/apple-touch-icon.png +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/browserconfig.xml +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/favicon-16x16.png +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/favicon-32x32.png +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/manifest.json +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/mstile-150x150.png +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/favicons/safari-pinned-tab.svg +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/docs/static/logo_blue.png +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/examples/async_batch.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/examples/create_entity.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/examples/upload_files.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/argument_parser/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/argument_parser/_is_enum.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/argument_parser/_is_namedtuple.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization/missing_sentry.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization/opaque_key.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization_util/_get_type_for_serialization.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/strenum_compat/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/strenum_compat/strenum_compat.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/__main__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/actions_registry/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/actions_registry/__main__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/actions_registry/emit_typescript.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/config.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/emit_io_ts.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/emit_open_api_util.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/emit_typescript_util.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/load_types.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/open_api_util.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/parts/base.py.prepart +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/parts/base.ts.prepart +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/test.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/type_info/__main__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/util.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/value_spec/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/value_spec/__main__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/value_spec/convert_type.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/value_spec/emit_python.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/type_spec/value_spec/types.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/setup.cfg +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/core/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/core/async_batch.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/core/client.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/core/file_upload.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/core/types.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/construct_client.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/cron.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/db/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/db/connect.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/entrypoint.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/executors/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/executors/script_executor.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/job.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/server.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/integration/types.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/py.typed +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/batch/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/batch/execute_batch.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/batch/execute_batch_load_async.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/chemical/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/chemical/convert_chemical_formats.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/create_entities.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/create_entity.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/get_entities_data.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/lock_entity.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/resolve_entity_ids.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/set_values.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/transition_entity_phase.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/entity/unlock_entity.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/field_options/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/field_options/upsert_field_options.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/id_source/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/id_source/list_id_source.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/id_source/match_id_source.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/input_groups/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/input_groups/get_input_group_names.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/create_inputs.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/get_input_data.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/get_input_names.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/get_inputs_data.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/set_input_attribute_values.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/set_input_category.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/inputs/set_input_subcategories.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/material_families/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/material_families/update_entity_material_families.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/outputs/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/outputs/get_output_data.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/outputs/get_output_names.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/outputs/resolve_output_conditions.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/permissions/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/permissions/set_core_permissions.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/project/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/project/get_projects.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/project/get_projects_data.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipe_links/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipe_links/create_recipe_link.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipe_metadata/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/archive_recipes.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/associate_recipe_as_lot.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/create_recipe.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/create_recipes.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/disassociate_recipe_as_input.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/get_curve.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/get_recipe_calculations.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/get_recipe_links.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/get_recipe_names.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/get_recipe_output_metadata.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/get_recipes_data.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/set_recipe_inputs.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/set_recipe_metadata.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/set_recipe_tags.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/recipes/unarchive_recipes.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/triggers/__init__.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/api/triggers/run_trigger.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/async_batch.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/async_batch_processor.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/base.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/calculations.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/chemical_structure.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/curves.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/entity.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/experiment_groups.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/field_values.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/fields.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/id_source.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/identifier.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/input_attributes.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/outputs.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/permissions.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/phases.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/post_base.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/recipe_identifiers.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/recipe_inputs.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/recipe_links.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/recipe_metadata.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/recipe_output_metadata.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/recipe_tags.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/response.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/units.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/users.py +0 -0
- {uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/uncountable/types/workflows.py +0 -0
{uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/.github/workflows/documentation.yml
RENAMED
|
@@ -9,9 +9,9 @@ jobs:
|
|
|
9
9
|
docs:
|
|
10
10
|
runs-on: ubuntu-latest
|
|
11
11
|
steps:
|
|
12
|
-
- uses: actions/checkout@v3
|
|
13
|
-
- uses: actions/setup-python@
|
|
14
|
-
- uses: extractions/setup-just@
|
|
12
|
+
- uses: actions/checkout@f43a0e5ff2bd294095638e18286ca9a3d1956744 # v3
|
|
13
|
+
- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5
|
|
14
|
+
- uses: extractions/setup-just@dd310ad5a97d8e7b41793f8ef055398d51ad4de6 # v2
|
|
15
15
|
with:
|
|
16
16
|
just-version: '1.8.0'
|
|
17
17
|
github-token: ${{ secrets.GITHUB_TOKEN }}
|
|
@@ -25,7 +25,7 @@ jobs:
|
|
|
25
25
|
run: |
|
|
26
26
|
just -f docs/justfile docs-build
|
|
27
27
|
- name: Deploy to GitHub Pages
|
|
28
|
-
uses: peaceiris/actions-gh-pages@
|
|
28
|
+
uses: peaceiris/actions-gh-pages@4f9cc6602d3f66b9c108549d475ec49e8ef4d45e # v4
|
|
29
29
|
if: ${{ github.event_name == 'push' && github.ref == 'refs/heads/main' }}
|
|
30
30
|
with:
|
|
31
31
|
publish_branch: gh-pages
|
|
@@ -19,10 +19,10 @@ jobs:
|
|
|
19
19
|
name: Build distribution packages
|
|
20
20
|
runs-on: ubuntu-latest
|
|
21
21
|
steps:
|
|
22
|
-
- uses: actions/checkout@v4
|
|
22
|
+
- uses: actions/checkout@692973e3d937129bcbf40652eb9f2f61becf3332 # v4
|
|
23
23
|
with:
|
|
24
24
|
fetch-depth: 0
|
|
25
|
-
- uses: actions/setup-python@v5
|
|
25
|
+
- uses: actions/setup-python@82c7e631bb3cdc910f68e0081d67478d79c6982d # v5
|
|
26
26
|
with:
|
|
27
27
|
python-version: '3.11'
|
|
28
28
|
- name: Install build dependencies
|
|
@@ -31,7 +31,7 @@ jobs:
|
|
|
31
31
|
- name: Build distributions and wheels
|
|
32
32
|
run: |
|
|
33
33
|
python3 -m build
|
|
34
|
-
- uses: actions/upload-artifact@v4
|
|
34
|
+
- uses: actions/upload-artifact@65462800fd760344b1a7b4382951275a0abb4808 # v4
|
|
35
35
|
with:
|
|
36
36
|
name: package-distributions
|
|
37
37
|
path: dist/
|
|
@@ -45,9 +45,9 @@ jobs:
|
|
|
45
45
|
permissions:
|
|
46
46
|
id-token: write
|
|
47
47
|
steps:
|
|
48
|
-
- uses: actions/download-artifact@v4
|
|
48
|
+
- uses: actions/download-artifact@65a9edc5881444af0b9093a5e628f2fe47ea3b2e # v4
|
|
49
49
|
with:
|
|
50
50
|
name: package-distributions
|
|
51
51
|
path: dist/
|
|
52
52
|
- name: Publish package distributions to PyPI
|
|
53
|
-
uses: pypa/gh-action-pypi-publish@
|
|
53
|
+
uses: pypa/gh-action-pypi-publish@ec4db0b4ddc65acdf4bff5fa45ac92d78b56bdf0
|
{uncountablepythonsdk-0.0.30/UncountablePythonSDK.egg-info → uncountablepythonsdk-0.0.33}/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.33
|
|
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
|
|
@@ -19,7 +19,7 @@ Description-Content-Type: text/markdown
|
|
|
19
19
|
Requires-Dist: aiotus==0.*
|
|
20
20
|
Requires-Dist: aiohttp==3.*
|
|
21
21
|
Requires-Dist: requests==2.*
|
|
22
|
-
Requires-Dist: SQLAlchemy
|
|
22
|
+
Requires-Dist: SQLAlchemy>=1.4.0
|
|
23
23
|
Requires-Dist: APScheduler==3.*
|
|
24
24
|
Requires-Dist: python-dateutil==2.*
|
|
25
25
|
Requires-Dist: shelljob==0.*
|
|
@@ -28,7 +28,7 @@ Provides-Extra: test
|
|
|
28
28
|
Requires-Dist: mypy==1.*; extra == "test"
|
|
29
29
|
Requires-Dist: ruff==0.*; extra == "test"
|
|
30
30
|
Requires-Dist: pytest==8.*; extra == "test"
|
|
31
|
-
Requires-Dist: coverage[toml]==
|
|
31
|
+
Requires-Dist: coverage[toml]==7.*; extra == "test"
|
|
32
32
|
Requires-Dist: pytest-cov==5.*; extra == "test"
|
|
33
33
|
Requires-Dist: pytest-xdist==3.*; extra == "test"
|
|
34
34
|
|
{uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33/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.33
|
|
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
|
|
@@ -19,7 +19,7 @@ Description-Content-Type: text/markdown
|
|
|
19
19
|
Requires-Dist: aiotus==0.*
|
|
20
20
|
Requires-Dist: aiohttp==3.*
|
|
21
21
|
Requires-Dist: requests==2.*
|
|
22
|
-
Requires-Dist: SQLAlchemy
|
|
22
|
+
Requires-Dist: SQLAlchemy>=1.4.0
|
|
23
23
|
Requires-Dist: APScheduler==3.*
|
|
24
24
|
Requires-Dist: python-dateutil==2.*
|
|
25
25
|
Requires-Dist: shelljob==0.*
|
|
@@ -28,7 +28,7 @@ Provides-Extra: test
|
|
|
28
28
|
Requires-Dist: mypy==1.*; extra == "test"
|
|
29
29
|
Requires-Dist: ruff==0.*; extra == "test"
|
|
30
30
|
Requires-Dist: pytest==8.*; extra == "test"
|
|
31
|
-
Requires-Dist: coverage[toml]==
|
|
31
|
+
Requires-Dist: coverage[toml]==7.*; extra == "test"
|
|
32
32
|
Requires-Dist: pytest-cov==5.*; extra == "test"
|
|
33
33
|
Requires-Dist: pytest-xdist==3.*; extra == "test"
|
|
34
34
|
|
|
@@ -37,8 +37,10 @@ pkgs/serialization/__init__.py
|
|
|
37
37
|
pkgs/serialization/missing_sentry.py
|
|
38
38
|
pkgs/serialization/opaque_key.py
|
|
39
39
|
pkgs/serialization/serial_class.py
|
|
40
|
+
pkgs/serialization/serial_union.py
|
|
40
41
|
pkgs/serialization_util/__init__.py
|
|
41
42
|
pkgs/serialization_util/_get_type_for_serialization.py
|
|
43
|
+
pkgs/serialization_util/convert_to_snakecase.py
|
|
42
44
|
pkgs/serialization_util/serialization_helpers.py
|
|
43
45
|
pkgs/strenum_compat/__init__.py
|
|
44
46
|
pkgs/strenum_compat/strenum_compat.py
|
|
@@ -113,6 +115,7 @@ uncountable/types/recipe_metadata.py
|
|
|
113
115
|
uncountable/types/recipe_output_metadata.py
|
|
114
116
|
uncountable/types/recipe_tags.py
|
|
115
117
|
uncountable/types/recipe_workflow_steps.py
|
|
118
|
+
uncountable/types/recipes.py
|
|
116
119
|
uncountable/types/response.py
|
|
117
120
|
uncountable/types/units.py
|
|
118
121
|
uncountable/types/users.py
|
|
@@ -148,6 +151,7 @@ uncountable/types/api/inputs/get_inputs_data.py
|
|
|
148
151
|
uncountable/types/api/inputs/set_input_attribute_values.py
|
|
149
152
|
uncountable/types/api/inputs/set_input_category.py
|
|
150
153
|
uncountable/types/api/inputs/set_input_subcategories.py
|
|
154
|
+
uncountable/types/api/inputs/set_intermediate_type.py
|
|
151
155
|
uncountable/types/api/material_families/__init__.py
|
|
152
156
|
uncountable/types/api/material_families/update_entity_material_families.py
|
|
153
157
|
uncountable/types/api/outputs/__init__.py
|
|
@@ -164,6 +168,7 @@ uncountable/types/api/recipe_links/create_recipe_link.py
|
|
|
164
168
|
uncountable/types/api/recipe_metadata/__init__.py
|
|
165
169
|
uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py
|
|
166
170
|
uncountable/types/api/recipes/__init__.py
|
|
171
|
+
uncountable/types/api/recipes/add_recipe_to_project.py
|
|
167
172
|
uncountable/types/api/recipes/archive_recipes.py
|
|
168
173
|
uncountable/types/api/recipes/associate_recipe_as_input.py
|
|
169
174
|
uncountable/types/api/recipes/associate_recipe_as_lot.py
|
|
@@ -177,6 +182,7 @@ uncountable/types/api/recipes/get_recipe_links.py
|
|
|
177
182
|
uncountable/types/api/recipes/get_recipe_names.py
|
|
178
183
|
uncountable/types/api/recipes/get_recipe_output_metadata.py
|
|
179
184
|
uncountable/types/api/recipes/get_recipes_data.py
|
|
185
|
+
uncountable/types/api/recipes/remove_recipe_from_project.py
|
|
180
186
|
uncountable/types/api/recipes/set_recipe_inputs.py
|
|
181
187
|
uncountable/types/api/recipes/set_recipe_metadata.py
|
|
182
188
|
uncountable/types/api/recipes/set_recipe_outputs.py
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
aiotus==0.*
|
|
2
2
|
aiohttp==3.*
|
|
3
3
|
requests==2.*
|
|
4
|
-
SQLAlchemy
|
|
4
|
+
SQLAlchemy>=1.4.0
|
|
5
5
|
APScheduler==3.*
|
|
6
6
|
python-dateutil==2.*
|
|
7
7
|
shelljob==0.*
|
|
@@ -11,6 +11,6 @@ PyYAML==6.*
|
|
|
11
11
|
mypy==1.*
|
|
12
12
|
ruff==0.*
|
|
13
13
|
pytest==8.*
|
|
14
|
-
coverage[toml]==
|
|
14
|
+
coverage[toml]==7.*
|
|
15
15
|
pytest-cov==5.*
|
|
16
16
|
pytest-xdist==3.*
|
{uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/argument_parser/argument_parser.py
RENAMED
|
@@ -10,7 +10,12 @@ from importlib import resources
|
|
|
10
10
|
import dateutil.parser
|
|
11
11
|
import yaml
|
|
12
12
|
|
|
13
|
-
from pkgs.serialization import
|
|
13
|
+
from pkgs.serialization import (
|
|
14
|
+
MissingSentryType,
|
|
15
|
+
OpaqueKey,
|
|
16
|
+
get_serial_class_data,
|
|
17
|
+
get_serial_union_data,
|
|
18
|
+
)
|
|
14
19
|
|
|
15
20
|
from ._is_enum import is_string_enum_class
|
|
16
21
|
from ._is_namedtuple import is_namedtuple_type
|
|
@@ -112,6 +117,23 @@ def _invoke_membership_parser(
|
|
|
112
117
|
raise ValueError(f"Expected value from {expected_values} but got value {value}")
|
|
113
118
|
|
|
114
119
|
|
|
120
|
+
def _build_parser_discriminated_union(
|
|
121
|
+
discriminator: str, discriminator_map: dict[str, ParserFunction[T]]
|
|
122
|
+
) -> ParserFunction[T]:
|
|
123
|
+
def parse(value: typing.Any) -> typing.Any:
|
|
124
|
+
discriminant = value.get(discriminator)
|
|
125
|
+
if discriminant is None:
|
|
126
|
+
raise ValueError("missing-union-discriminant")
|
|
127
|
+
if not isinstance(discriminant, str):
|
|
128
|
+
raise ValueError("union-discriminant-is-not-string")
|
|
129
|
+
parser = discriminator_map.get(discriminant)
|
|
130
|
+
if parser is None:
|
|
131
|
+
raise ValueError("missing-type-for-union-discriminant", discriminant)
|
|
132
|
+
return parser(value)
|
|
133
|
+
|
|
134
|
+
return parse
|
|
135
|
+
|
|
136
|
+
|
|
115
137
|
def _build_parser_inner(
|
|
116
138
|
parsed_type: type[T],
|
|
117
139
|
context: ParserContext,
|
|
@@ -130,6 +152,23 @@ def _build_parser_inner(
|
|
|
130
152
|
are cached now, as they don't use the argument, and they're known to be safe.
|
|
131
153
|
This is also enough to support some recursion.
|
|
132
154
|
"""
|
|
155
|
+
|
|
156
|
+
serial_union = get_serial_union_data(parsed_type)
|
|
157
|
+
if serial_union is not None:
|
|
158
|
+
discriminator = serial_union.discriminator
|
|
159
|
+
discriminator_map = serial_union.discriminator_map
|
|
160
|
+
if discriminator is None or discriminator_map is None:
|
|
161
|
+
# fallback to standard union parsing
|
|
162
|
+
parsed_type = serial_union.get_union_underlying()
|
|
163
|
+
else:
|
|
164
|
+
return _build_parser_discriminated_union(
|
|
165
|
+
discriminator,
|
|
166
|
+
{
|
|
167
|
+
key: _build_parser_inner(value, context)
|
|
168
|
+
for key, value in discriminator_map.items()
|
|
169
|
+
},
|
|
170
|
+
)
|
|
171
|
+
|
|
133
172
|
if dataclasses.is_dataclass(parsed_type):
|
|
134
173
|
return _build_parser_dataclass(parsed_type, context) # type: ignore[arg-type]
|
|
135
174
|
|
|
@@ -341,7 +380,7 @@ def _build_parser_dataclass(
|
|
|
341
380
|
|
|
342
381
|
except Exception as e:
|
|
343
382
|
raise ValueError(
|
|
344
|
-
f"unable
|
|
383
|
+
f"unable-to-parse-field:{field.name}", field_raw_value
|
|
345
384
|
) from e
|
|
346
385
|
|
|
347
386
|
if context.options.strict_property_parsing:
|
{uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/argument_parser/case_convert.py
RENAMED
|
@@ -4,9 +4,10 @@ import re
|
|
|
4
4
|
|
|
5
5
|
@functools.lru_cache(maxsize=500000)
|
|
6
6
|
def snake_to_camel_case(o: str) -> str:
|
|
7
|
-
|
|
8
|
-
|
|
9
|
-
|
|
7
|
+
tokens = o.split("_")
|
|
8
|
+
if len(tokens) < 2:
|
|
9
|
+
return o
|
|
10
|
+
return "".join([part.title() if i > 0 else part for i, part in enumerate(tokens)])
|
|
10
11
|
|
|
11
12
|
|
|
12
13
|
def kebab_to_pascal_case(o: str) -> str:
|
|
@@ -8,3 +8,5 @@ from .serial_class import get_serial_class_data as get_serial_class_data
|
|
|
8
8
|
from .serial_class import get_serial_string_enum_data as get_serial_string_enum_data
|
|
9
9
|
from .serial_class import serial_class as serial_class
|
|
10
10
|
from .serial_class import serial_string_enum as serial_string_enum
|
|
11
|
+
from .serial_union import serial_union_annotation as serial_union_annotation
|
|
12
|
+
from .serial_union import get_serial_union_data as get_serial_union_data
|
{uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization/serial_class.py
RENAMED
|
@@ -16,6 +16,9 @@ class _SerialClassData:
|
|
|
16
16
|
parse_require: set[str] = dataclasses.field(default_factory=set)
|
|
17
17
|
|
|
18
18
|
|
|
19
|
+
EMPTY_SERIAL_CLASS_DATA = _SerialClassData()
|
|
20
|
+
|
|
21
|
+
|
|
19
22
|
def serial_class(
|
|
20
23
|
*,
|
|
21
24
|
unconverted_keys: Optional[set[str]] = None,
|
|
@@ -57,58 +60,49 @@ def serial_class(
|
|
|
57
60
|
|
|
58
61
|
|
|
59
62
|
class SerialClassDataInspector:
|
|
60
|
-
bases: list[SerialClassDataInspector]
|
|
61
|
-
|
|
62
63
|
def __init__(
|
|
63
|
-
self,
|
|
64
|
+
self,
|
|
65
|
+
current: _SerialClassData,
|
|
64
66
|
) -> None:
|
|
65
|
-
self.bases = bases
|
|
66
67
|
self.current = current
|
|
67
68
|
|
|
68
69
|
def has_unconverted_key(self, key: str) -> bool:
|
|
69
|
-
|
|
70
|
-
return True
|
|
71
|
-
for base in self.bases:
|
|
72
|
-
if base.has_unconverted_key(key):
|
|
73
|
-
return True
|
|
74
|
-
return False
|
|
70
|
+
return key in self.current.unconverted_keys
|
|
75
71
|
|
|
76
72
|
def has_unconverted_value(self, key: str) -> bool:
|
|
77
|
-
|
|
78
|
-
return True
|
|
79
|
-
for base in self.bases:
|
|
80
|
-
if base.has_unconverted_value(key):
|
|
81
|
-
return True
|
|
82
|
-
return False
|
|
73
|
+
return key in self.current.unconverted_values
|
|
83
74
|
|
|
84
75
|
def has_to_string_value(self, key: str) -> bool:
|
|
85
|
-
|
|
86
|
-
return True
|
|
87
|
-
for base in self.bases:
|
|
88
|
-
if base.has_to_string_value(key):
|
|
89
|
-
return True
|
|
90
|
-
return False
|
|
76
|
+
return key in self.current.to_string_values
|
|
91
77
|
|
|
92
78
|
def has_parse_require(self, key: str) -> bool:
|
|
93
|
-
|
|
94
|
-
return True
|
|
95
|
-
for base in self.bases:
|
|
96
|
-
if base.has_parse_require(key):
|
|
97
|
-
return True
|
|
98
|
-
return False
|
|
79
|
+
return key in self.current.parse_require
|
|
99
80
|
|
|
100
81
|
|
|
101
|
-
def
|
|
102
|
-
|
|
103
|
-
[get_serial_class_data(base) for base in type_class.__bases__]
|
|
104
|
-
if type_class.__bases__ is not None
|
|
105
|
-
else []
|
|
106
|
-
)
|
|
107
|
-
return SerialClassDataInspector(
|
|
108
|
-
bases,
|
|
82
|
+
def _get_merged_serial_class_data(type_class: type[Any]) -> _SerialClassData | None:
|
|
83
|
+
base_class_data = (
|
|
109
84
|
cast(_SerialClassData, type_class.__unc_serial_data)
|
|
110
85
|
if hasattr(type_class, "__unc_serial_data")
|
|
111
|
-
else
|
|
86
|
+
else None
|
|
87
|
+
)
|
|
88
|
+
if type_class.__bases__ is not None:
|
|
89
|
+
for base in type_class.__bases__:
|
|
90
|
+
curr_base_class_data = _get_merged_serial_class_data(base)
|
|
91
|
+
if curr_base_class_data is not None:
|
|
92
|
+
if base_class_data is None:
|
|
93
|
+
base_class_data = _SerialClassData()
|
|
94
|
+
base_class_data.unconverted_keys |= curr_base_class_data.unconverted_keys
|
|
95
|
+
base_class_data.unconverted_values |= (
|
|
96
|
+
curr_base_class_data.unconverted_values
|
|
97
|
+
)
|
|
98
|
+
base_class_data.to_string_values |= curr_base_class_data.to_string_values
|
|
99
|
+
base_class_data.parse_require |= curr_base_class_data.parse_require
|
|
100
|
+
return base_class_data
|
|
101
|
+
|
|
102
|
+
|
|
103
|
+
def get_serial_class_data(type_class: type[Any]) -> SerialClassDataInspector:
|
|
104
|
+
return SerialClassDataInspector(
|
|
105
|
+
_get_merged_serial_class_data(type_class) or EMPTY_SERIAL_CLASS_DATA
|
|
112
106
|
)
|
|
113
107
|
|
|
114
108
|
|
|
@@ -0,0 +1,81 @@
|
|
|
1
|
+
import dataclasses
|
|
2
|
+
import typing
|
|
3
|
+
|
|
4
|
+
T = typing.TypeVar("T")
|
|
5
|
+
|
|
6
|
+
|
|
7
|
+
class IdentityHashWrapper(typing.Generic[T]):
|
|
8
|
+
"""This allows unhashable types to be used in the SerialUnion, like dict.
|
|
9
|
+
Since we have only one copy of the types themselves, we rely on
|
|
10
|
+
object identity for the hashing."""
|
|
11
|
+
|
|
12
|
+
def __init__(self, inner: T) -> None:
|
|
13
|
+
self.inner = inner
|
|
14
|
+
|
|
15
|
+
def __hash__(self) -> int:
|
|
16
|
+
return id(self.inner)
|
|
17
|
+
|
|
18
|
+
|
|
19
|
+
@dataclasses.dataclass(kw_only=True, frozen=True, eq=True)
|
|
20
|
+
class _SerialUnion:
|
|
21
|
+
"""
|
|
22
|
+
This class is to be kept private, to provide flexibility in registration/lookup.
|
|
23
|
+
Places that need the data should access it via help classes/methods.
|
|
24
|
+
"""
|
|
25
|
+
|
|
26
|
+
# If specified, indicates the Union has a discriminator which should be used to
|
|
27
|
+
# determine which type to parse.
|
|
28
|
+
discriminator: typing.Optional[str] = None
|
|
29
|
+
discriminator_map: typing.Optional[IdentityHashWrapper[dict[str, type]]] = None
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
def serial_union_annotation(
|
|
33
|
+
*,
|
|
34
|
+
discriminator: typing.Optional[str] = None,
|
|
35
|
+
discriminator_map: typing.Optional[dict[str, type]] = None,
|
|
36
|
+
) -> _SerialUnion:
|
|
37
|
+
return _SerialUnion(
|
|
38
|
+
discriminator=discriminator,
|
|
39
|
+
discriminator_map=IdentityHashWrapper(discriminator_map)
|
|
40
|
+
if discriminator_map is not None
|
|
41
|
+
else None,
|
|
42
|
+
)
|
|
43
|
+
|
|
44
|
+
|
|
45
|
+
def _get_serial_union(parsed_type: type[T]) -> _SerialUnion | None:
|
|
46
|
+
if not hasattr(parsed_type, "__metadata__"):
|
|
47
|
+
return None
|
|
48
|
+
metadata = parsed_type.__metadata__ # type:ignore[attr-defined]
|
|
49
|
+
if not isinstance(metadata, tuple) or len(metadata) != 1:
|
|
50
|
+
return None
|
|
51
|
+
serial = metadata[0]
|
|
52
|
+
if not isinstance(serial, _SerialUnion):
|
|
53
|
+
return None
|
|
54
|
+
return serial
|
|
55
|
+
|
|
56
|
+
|
|
57
|
+
class SerialClassInspector(typing.Generic[T]):
|
|
58
|
+
def __init__(self, parsed_type: type[T], serial_union: _SerialUnion) -> None:
|
|
59
|
+
self._parsed_type = parsed_type
|
|
60
|
+
self._serial_union = serial_union
|
|
61
|
+
|
|
62
|
+
def get_union_underlying(self) -> type[T]:
|
|
63
|
+
return typing.get_args(self._parsed_type)[0] # type:ignore[no-any-return]
|
|
64
|
+
|
|
65
|
+
@property
|
|
66
|
+
def discriminator(self) -> typing.Optional[str]:
|
|
67
|
+
return self._serial_union.discriminator
|
|
68
|
+
|
|
69
|
+
@property
|
|
70
|
+
def discriminator_map(self) -> typing.Optional[dict[str, type]]:
|
|
71
|
+
if self._serial_union.discriminator_map is None:
|
|
72
|
+
return None
|
|
73
|
+
return self._serial_union.discriminator_map.inner
|
|
74
|
+
|
|
75
|
+
|
|
76
|
+
def get_serial_union_data(parsed_type: type[T]) -> SerialClassInspector[T] | None:
|
|
77
|
+
serial = _get_serial_union(parsed_type)
|
|
78
|
+
if serial is None:
|
|
79
|
+
return None
|
|
80
|
+
|
|
81
|
+
return SerialClassInspector(parsed_type, serial)
|
{uncountablepythonsdk-0.0.30 → uncountablepythonsdk-0.0.33}/pkgs/serialization_util/__init__.py
RENAMED
|
@@ -1,8 +1,5 @@
|
|
|
1
|
+
from .convert_to_snakecase import convert_dict_to_snake_case
|
|
1
2
|
from .serialization_helpers import (
|
|
2
|
-
convert_dict_to_snake_case,
|
|
3
|
-
convert_to_camelcase,
|
|
4
|
-
resolve_missing_to_none,
|
|
5
|
-
serialize,
|
|
6
3
|
serialize_for_api,
|
|
7
4
|
serialize_for_storage,
|
|
8
5
|
serialize_for_storage_dict,
|
|
@@ -10,9 +7,6 @@ from .serialization_helpers import (
|
|
|
10
7
|
|
|
11
8
|
__all__: list[str] = [
|
|
12
9
|
"convert_dict_to_snake_case",
|
|
13
|
-
"convert_to_camelcase",
|
|
14
|
-
"resolve_missing_to_none",
|
|
15
|
-
"serialize",
|
|
16
10
|
"serialize_for_api",
|
|
17
11
|
"serialize_for_storage",
|
|
18
12
|
"serialize_for_storage_dict",
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
from typing import (
|
|
2
|
+
Any,
|
|
3
|
+
)
|
|
4
|
+
|
|
5
|
+
from pkgs.argument_parser import camel_to_snake_case
|
|
6
|
+
from pkgs.serialization import (
|
|
7
|
+
MISSING_SENTRY,
|
|
8
|
+
OpaqueKey,
|
|
9
|
+
)
|
|
10
|
+
|
|
11
|
+
|
|
12
|
+
def _key_convert_to_snake_case(o: Any) -> Any:
|
|
13
|
+
if isinstance(o, OpaqueKey):
|
|
14
|
+
return o
|
|
15
|
+
if isinstance(o, str):
|
|
16
|
+
return camel_to_snake_case(o)
|
|
17
|
+
return o
|
|
18
|
+
|
|
19
|
+
|
|
20
|
+
def convert_dict_to_snake_case(data: Any) -> Any:
|
|
21
|
+
return {
|
|
22
|
+
_key_convert_to_snake_case(k): convert_dict_to_snake_case(v)
|
|
23
|
+
if isinstance(v, dict)
|
|
24
|
+
else v
|
|
25
|
+
for k, v in data.items()
|
|
26
|
+
if v != MISSING_SENTRY
|
|
27
|
+
}
|