UncountablePythonSDK 0.0.72__tar.gz → 0.0.74__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.

Files changed (293) hide show
  1. {uncountablepythonsdk-0.0.72/UncountablePythonSDK.egg-info → uncountablepythonsdk-0.0.74}/PKG-INFO +1 -1
  2. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74/UncountablePythonSDK.egg-info}/PKG-INFO +1 -1
  3. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/integration-server/jobs/materials_auto/profile.yaml +1 -1
  4. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/argument_parser/__init__.py +1 -0
  5. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/argument_parser/argument_parser.py +13 -1
  6. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization/serial_class.py +18 -0
  7. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization/serial_union.py +3 -0
  8. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/builder.py +70 -22
  9. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/config.py +5 -0
  10. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/emit_python.py +35 -22
  11. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/emit_typescript.py +31 -22
  12. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/emit_typescript_util.py +0 -2
  13. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/load_types.py +3 -2
  14. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/type_info/emit_type_info.py +7 -7
  15. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/util.py +1 -1
  16. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/core/client.py +2 -2
  17. uncountablepythonsdk-0.0.74/uncountable/integration/entrypoint.py +13 -0
  18. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/worker.py +9 -5
  19. uncountablepythonsdk-0.0.74/uncountable/integration/server.py +125 -0
  20. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/batch/execute_batch.py +8 -0
  21. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/batch/execute_batch_load_async.py +7 -0
  22. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/chemical/convert_chemical_formats.py +7 -0
  23. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/create_entities.py +11 -1
  24. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/create_entity.py +8 -1
  25. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/get_entities_data.py +10 -0
  26. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/list_entities.py +8 -0
  27. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/lock_entity.py +7 -0
  28. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/resolve_entity_ids.py +10 -0
  29. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/set_values.py +7 -0
  30. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/transition_entity_phase.py +8 -0
  31. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/unlock_entity.py +7 -0
  32. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/equipment/associate_equipment_input.py +7 -0
  33. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/field_options/upsert_field_options.py +10 -0
  34. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/id_source/list_id_source.py +10 -0
  35. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/id_source/match_id_source.py +10 -0
  36. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/input_groups/get_input_group_names.py +10 -0
  37. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/create_inputs.py +13 -0
  38. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/get_input_data.py +19 -0
  39. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/get_input_names.py +10 -0
  40. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/get_inputs_data.py +19 -0
  41. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/set_input_attribute_values.py +7 -0
  42. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/set_input_category.py +7 -0
  43. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/set_input_subcategories.py +7 -0
  44. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/set_intermediate_type.py +7 -0
  45. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/material_families/update_entity_material_families.py +7 -0
  46. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/outputs/get_output_data.py +16 -0
  47. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/outputs/get_output_names.py +10 -0
  48. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/outputs/resolve_output_conditions.py +13 -0
  49. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/permissions/set_core_permissions.py +10 -0
  50. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/project/get_projects.py +10 -0
  51. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/project/get_projects_data.py +10 -0
  52. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipe_links/create_recipe_link.py +7 -0
  53. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipe_links/remove_recipe_link.py +7 -0
  54. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipe_metadata/get_recipe_metadata_data.py +10 -0
  55. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/add_recipe_to_project.py +7 -0
  56. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/archive_recipes.py +7 -0
  57. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/associate_recipe_as_input.py +7 -0
  58. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/associate_recipe_as_lot.py +7 -0
  59. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/clear_recipe_outputs.py +7 -0
  60. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/create_recipe.py +7 -0
  61. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/create_recipes.py +13 -0
  62. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/disassociate_recipe_as_input.py +7 -0
  63. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/edit_recipe_inputs.py +20 -0
  64. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/get_curve.py +7 -0
  65. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/get_recipe_calculations.py +7 -0
  66. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/get_recipe_links.py +7 -0
  67. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/get_recipe_names.py +10 -0
  68. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/get_recipe_output_metadata.py +7 -0
  69. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/get_recipes_data.py +25 -0
  70. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/lock_recipes.py +10 -0
  71. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/remove_recipe_from_project.py +7 -0
  72. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/set_recipe_inputs.py +7 -0
  73. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/set_recipe_metadata.py +7 -0
  74. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/set_recipe_output_annotations.py +13 -0
  75. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/set_recipe_output_file.py +10 -0
  76. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/set_recipe_outputs.py +10 -0
  77. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/set_recipe_tags.py +12 -0
  78. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/unarchive_recipes.py +7 -0
  79. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/unlock_recipes.py +7 -0
  80. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/triggers/run_trigger.py +7 -0
  81. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/uploader/invoke_uploader.py +9 -1
  82. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/async_batch_processor.py +4 -1
  83. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/async_batch_t.py +10 -0
  84. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/calculations_t.py +4 -0
  85. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/chemical_structure_t.py +1 -0
  86. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/client_base.py +6 -3
  87. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/client_config_t.py +4 -0
  88. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/curves_t.py +4 -0
  89. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/entity_t.py +8 -0
  90. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/experiment_groups_t.py +4 -0
  91. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/field_values_t.py +4 -0
  92. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/fields_t.py +4 -0
  93. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/generic_upload_t.py +13 -0
  94. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/id_source_t.py +13 -0
  95. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/identifier_t.py +3 -0
  96. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/input_attributes_t.py +1 -0
  97. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/inputs_t.py +4 -0
  98. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/job_definition_t.py +33 -0
  99. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/outputs_t.py +4 -0
  100. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/overrides_t.py +7 -0
  101. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/phases_t.py +4 -0
  102. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/queued_job_t.py +16 -0
  103. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_identifiers_t.py +3 -0
  104. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_links_t.py +4 -0
  105. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_metadata_t.py +5 -0
  106. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_output_metadata_t.py +4 -0
  107. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_tags_t.py +4 -0
  108. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_workflow_steps_t.py +7 -0
  109. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipes_t.py +4 -0
  110. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/response_t.py +1 -0
  111. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/secret_retrieval_t.py +6 -0
  112. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/units_t.py +4 -0
  113. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/users_t.py +4 -0
  114. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/webhook_job_t.py +4 -0
  115. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/workflows_t.py +7 -0
  116. uncountablepythonsdk-0.0.72/uncountable/integration/entrypoint.py +0 -21
  117. uncountablepythonsdk-0.0.72/uncountable/integration/server.py +0 -128
  118. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/.github/workflows/documentation.yml +0 -0
  119. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/.github/workflows/publish.yml +0 -0
  120. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/.gitignore +0 -0
  121. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/README.md +0 -0
  122. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/UncountablePythonSDK.egg-info/SOURCES.txt +0 -0
  123. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/UncountablePythonSDK.egg-info/dependency_links.txt +0 -0
  124. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/UncountablePythonSDK.egg-info/requires.txt +0 -0
  125. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/UncountablePythonSDK.egg-info/top_level.txt +0 -0
  126. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/.gitignore +0 -0
  127. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/conf.py +0 -0
  128. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/index.md +0 -0
  129. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/justfile +0 -0
  130. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/quickstart.md +0 -0
  131. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/requirements.txt +0 -0
  132. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/android-chrome-192x192.png +0 -0
  133. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/android-chrome-512x512.png +0 -0
  134. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/apple-touch-icon.png +0 -0
  135. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/browserconfig.xml +0 -0
  136. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/favicon-16x16.png +0 -0
  137. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/favicon-32x32.png +0 -0
  138. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/manifest.json +0 -0
  139. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/mstile-150x150.png +0 -0
  140. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/favicons/safari-pinned-tab.svg +0 -0
  141. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/docs/static/logo_blue.png +0 -0
  142. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/async_batch.py +0 -0
  143. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/create_entity.py +0 -0
  144. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/edit_recipe_inputs.py +0 -0
  145. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/integration-server/jobs/materials_auto/example_cron.py +0 -0
  146. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/integration-server/pyproject.toml +0 -0
  147. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/invoke_uploader.py +0 -0
  148. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/set_recipe_metadata_file.py +0 -0
  149. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/set_recipe_output_file_sdk.py +0 -0
  150. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/examples/upload_files.py +0 -0
  151. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/__init__.py +0 -0
  152. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/argument_parser/_is_enum.py +0 -0
  153. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/argument_parser/_is_namedtuple.py +0 -0
  154. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/argument_parser/case_convert.py +0 -0
  155. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/filesystem_utils/__init__.py +0 -0
  156. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/filesystem_utils/_gdrive_session.py +0 -0
  157. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/filesystem_utils/_local_session.py +0 -0
  158. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/filesystem_utils/_s3_session.py +0 -0
  159. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/filesystem_utils/_sftp_session.py +0 -0
  160. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/filesystem_utils/file_type_utils.py +0 -0
  161. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/filesystem_utils/filesystem_session.py +0 -0
  162. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/py.typed +0 -0
  163. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization/__init__.py +0 -0
  164. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization/missing_sentry.py +0 -0
  165. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization/opaque_key.py +0 -0
  166. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization/yaml.py +0 -0
  167. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization_util/__init__.py +0 -0
  168. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization_util/_get_type_for_serialization.py +0 -0
  169. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization_util/convert_to_snakecase.py +0 -0
  170. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/serialization_util/serialization_helpers.py +0 -0
  171. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/strenum_compat/__init__.py +0 -0
  172. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/strenum_compat/strenum_compat.py +0 -0
  173. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/__init__.py +0 -0
  174. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/__main__.py +0 -0
  175. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/actions_registry/__init__.py +0 -0
  176. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/actions_registry/__main__.py +0 -0
  177. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/actions_registry/emit_typescript.py +0 -0
  178. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/emit_io_ts.py +0 -0
  179. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/emit_open_api.py +0 -0
  180. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/emit_open_api_util.py +0 -0
  181. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/open_api_util.py +0 -0
  182. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/parts/base.py.prepart +0 -0
  183. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/parts/base.ts.prepart +0 -0
  184. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/test.py +0 -0
  185. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/type_info/__main__.py +0 -0
  186. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/value_spec/__init__.py +0 -0
  187. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/value_spec/__main__.py +0 -0
  188. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/value_spec/convert_type.py +0 -0
  189. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/value_spec/emit_python.py +0 -0
  190. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pkgs/type_spec/value_spec/types.py +0 -0
  191. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/pyproject.toml +0 -0
  192. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/setup.cfg +0 -0
  193. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/__init__.py +0 -0
  194. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/core/__init__.py +0 -0
  195. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/core/async_batch.py +0 -0
  196. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/core/environment.py +0 -0
  197. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/core/file_upload.py +0 -0
  198. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/core/types.py +0 -0
  199. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/__init__.py +0 -0
  200. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/cli.py +0 -0
  201. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/construct_client.py +0 -0
  202. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/cron.py +0 -0
  203. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/db/__init__.py +0 -0
  204. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/db/connect.py +0 -0
  205. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/db/session.py +0 -0
  206. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/executors/__init__.py +0 -0
  207. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/executors/executors.py +0 -0
  208. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/executors/generic_upload_executor.py +0 -0
  209. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/executors/script_executor.py +0 -0
  210. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/job.py +0 -0
  211. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/__init__.py +0 -0
  212. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/__init__.py +0 -0
  213. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/command_client.py +0 -0
  214. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/command_server.py +0 -0
  215. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/protocol/__init__.py +0 -0
  216. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/protocol/command_server.proto +0 -0
  217. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.py +0 -0
  218. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2.pyi +0 -0
  219. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/protocol/command_server_pb2_grpc.py +0 -0
  220. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/command_server/types.py +0 -0
  221. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/datastore/__init__.py +0 -0
  222. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/datastore/datastore_sqlite.py +0 -0
  223. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/datastore/interface.py +0 -0
  224. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/datastore/model.py +0 -0
  225. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/job_scheduler.py +0 -0
  226. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/queue_runner.py +0 -0
  227. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/queue_runner/types.py +0 -0
  228. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/scan_profiles.py +0 -0
  229. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/scheduler.py +0 -0
  230. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/secret_retrieval/__init__.py +0 -0
  231. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/secret_retrieval/retrieve_secret.py +0 -0
  232. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/telemetry.py +0 -0
  233. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/integration/webhook_server/entrypoint.py +0 -0
  234. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/py.typed +0 -0
  235. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/__init__.py +0 -0
  236. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/__init__.py +0 -0
  237. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/batch/__init__.py +0 -0
  238. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/chemical/__init__.py +0 -0
  239. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/entity/__init__.py +0 -0
  240. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/equipment/__init__.py +0 -0
  241. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/field_options/__init__.py +0 -0
  242. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/id_source/__init__.py +0 -0
  243. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/input_groups/__init__.py +0 -0
  244. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/inputs/__init__.py +0 -0
  245. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/material_families/__init__.py +0 -0
  246. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/outputs/__init__.py +0 -0
  247. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/permissions/__init__.py +0 -0
  248. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/project/__init__.py +0 -0
  249. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipe_links/__init__.py +0 -0
  250. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipe_metadata/__init__.py +0 -0
  251. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/recipes/__init__.py +0 -0
  252. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/triggers/__init__.py +0 -0
  253. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/api/uploader/__init__.py +0 -0
  254. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/async_batch.py +0 -0
  255. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/base.py +0 -0
  256. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/base_t.py +0 -0
  257. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/calculations.py +0 -0
  258. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/chemical_structure.py +0 -0
  259. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/client_config.py +0 -0
  260. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/curves.py +0 -0
  261. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/entity.py +0 -0
  262. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/experiment_groups.py +0 -0
  263. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/field_values.py +0 -0
  264. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/fields.py +0 -0
  265. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/generic_upload.py +0 -0
  266. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/id_source.py +0 -0
  267. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/identifier.py +0 -0
  268. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/input_attributes.py +0 -0
  269. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/inputs.py +0 -0
  270. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/job_definition.py +0 -0
  271. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/outputs.py +0 -0
  272. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/overrides.py +0 -0
  273. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/permissions.py +0 -0
  274. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/permissions_t.py +0 -0
  275. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/phases.py +0 -0
  276. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/post_base.py +0 -0
  277. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/post_base_t.py +0 -0
  278. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/queued_job.py +0 -0
  279. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_identifiers.py +0 -0
  280. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_inputs.py +0 -0
  281. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_inputs_t.py +0 -0
  282. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_links.py +0 -0
  283. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_metadata.py +0 -0
  284. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_output_metadata.py +0 -0
  285. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_tags.py +0 -0
  286. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipe_workflow_steps.py +0 -0
  287. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/recipes.py +0 -0
  288. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/response.py +0 -0
  289. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/secret_retrieval.py +0 -0
  290. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/units.py +0 -0
  291. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/users.py +0 -0
  292. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/webhook_job.py +0 -0
  293. {uncountablepythonsdk-0.0.72 → uncountablepythonsdk-0.0.74}/uncountable/types/workflows.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.72
3
+ Version: 0.0.74
4
4
  Summary: Uncountable SDK
5
5
  Project-URL: Homepage, https://github.com/uncountableinc/uncountable-python-sdk
6
6
  Project-URL: Repository, https://github.com/uncountableinc/uncountable-python-sdk.git
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.72
3
+ Version: 0.0.74
4
4
  Summary: Uncountable SDK
5
5
  Project-URL: Homepage, https://github.com/uncountableinc/uncountable-python-sdk
6
6
  Project-URL: Repository, https://github.com/uncountableinc/uncountable-python-sdk.git
@@ -1,4 +1,4 @@
1
- base_url: http://0.0.0.0:5000
1
+ base_url: http://host.docker.internal:5000
2
2
  auth_retrieval:
3
3
  type: basic
4
4
  api_id_secret:
@@ -1,4 +1,5 @@
1
1
  from .argument_parser import CachedParser as CachedParser
2
+ from .argument_parser import ParserFunction as ParserFunction
2
3
  from .argument_parser import ParserOptions as ParserOptions
3
4
  from .argument_parser import build_parser as build_parser
4
5
  from .case_convert import camel_to_snake_case as camel_to_snake_case
@@ -1,4 +1,5 @@
1
1
  import dataclasses
2
+ import math
2
3
  import types
3
4
  import typing
4
5
  from collections import defaultdict
@@ -299,7 +300,18 @@ def _build_parser_inner(
299
300
 
300
301
  return parse_str
301
302
 
302
- if parsed_type in (float, dict, bool, Decimal) or is_string_enum_class(parsed_type):
303
+ if parsed_type in (float, Decimal):
304
+
305
+ def parse_as_numeric_type(value: typing.Any) -> T:
306
+ numeric_value: Decimal | float = parsed_type(value) # type: ignore
307
+ if math.isnan(numeric_value):
308
+ raise ValueError(f"Invalid numeric value: {numeric_value}")
309
+
310
+ return numeric_value # type: ignore
311
+
312
+ return parse_as_numeric_type
313
+
314
+ if parsed_type in (dict, bool) or is_string_enum_class(parsed_type):
303
315
  return lambda value: parsed_type(value) # type: ignore
304
316
 
305
317
  if parsed_type is MissingSentryType:
@@ -14,6 +14,11 @@ class _SerialClassData:
14
14
  unconverted_values: set[str] = dataclasses.field(default_factory=set)
15
15
  to_string_values: set[str] = dataclasses.field(default_factory=set)
16
16
  parse_require: set[str] = dataclasses.field(default_factory=set)
17
+ named_type_path: Optional[str] = None
18
+ # Tracks if this data was provided as a decorator to the type.
19
+ # This is used to track "proper types" which are appropriate
20
+ # for serialization and/or dynamic discovery
21
+ from_decorator: bool = False
17
22
 
18
23
 
19
24
  EMPTY_SERIAL_CLASS_DATA = _SerialClassData()
@@ -25,6 +30,7 @@ def serial_class(
25
30
  unconverted_values: Optional[set[str]] = None,
26
31
  to_string_values: Optional[set[str]] = None,
27
32
  parse_require: Optional[set[str]] = None,
33
+ named_type_path: Optional[str] = None,
28
34
  ) -> Callable[[_ClassT], _ClassT]:
29
35
  """
30
36
  An additional decorator to a dataclass that specifies serialization options.
@@ -45,6 +51,8 @@ def serial_class(
45
51
  This field is always required while parsing, even if it has a default in the definition.
46
52
  This allows supporting literal type defaults for Python instantiation, but
47
53
  requiring them for the API input.
54
+ @param named_type_path
55
+ The type_spec type-path to this type. This applies only to named types.
48
56
  """
49
57
 
50
58
  def decorate(orig_class: _ClassT) -> _ClassT:
@@ -53,6 +61,8 @@ def serial_class(
53
61
  unconverted_values=unconverted_values or set(),
54
62
  to_string_values=to_string_values or set(),
55
63
  parse_require=parse_require or set(),
64
+ named_type_path=named_type_path,
65
+ from_decorator=True,
56
66
  )
57
67
  return orig_class
58
68
 
@@ -78,6 +88,14 @@ class SerialClassDataInspector:
78
88
  def has_parse_require(self, key: str) -> bool:
79
89
  return key in self.current.parse_require
80
90
 
91
+ @property
92
+ def from_decorator(self) -> bool:
93
+ return self.current.from_decorator
94
+
95
+ @property
96
+ def named_type_path(self) -> Optional[str]:
97
+ return self.current.named_type_path
98
+
81
99
 
82
100
  def _get_merged_serial_class_data(type_class: type[Any]) -> _SerialClassData | None:
83
101
  base_class_data = (
@@ -27,18 +27,21 @@ class _SerialUnion:
27
27
  # determine which type to parse.
28
28
  discriminator: typing.Optional[str] = None
29
29
  discriminator_map: typing.Optional[IdentityHashWrapper[dict[str, type]]] = None
30
+ named_type_path: typing.Optional[str] = None
30
31
 
31
32
 
32
33
  def serial_union_annotation(
33
34
  *,
34
35
  discriminator: typing.Optional[str] = None,
35
36
  discriminator_map: typing.Optional[dict[str, type]] = None,
37
+ named_type_path: typing.Optional[str] = None,
36
38
  ) -> _SerialUnion:
37
39
  return _SerialUnion(
38
40
  discriminator=discriminator,
39
41
  discriminator_map=IdentityHashWrapper(discriminator_map)
40
42
  if discriminator_map is not None
41
43
  else None,
44
+ named_type_path=named_type_path,
42
45
  )
43
46
 
44
47
 
@@ -307,6 +307,9 @@ class SpecTypeDefn(SpecType):
307
307
  def is_base_type(self, type_: BaseTypeName) -> bool:
308
308
  return self.is_base and self.name == type_
309
309
 
310
+ def can_process(self, builder: SpecBuilder, data: RawDict) -> bool:
311
+ return True
312
+
310
313
  @abc.abstractmethod
311
314
  def process(self, builder: SpecBuilder, data: RawDict) -> None: ...
312
315
 
@@ -666,15 +669,30 @@ class SpecTypeDefnStringEnum(SpecTypeDefn):
666
669
  self.desc: str | None = None
667
670
  self.sql_type_name: Optional[str] = None
668
671
  self.emit_id_source = False
672
+ self.source_enums: list[SpecType] = []
673
+
674
+ def can_process(self, builder: SpecBuilder, data: dict[Any, Any]) -> bool:
675
+ source_enums = data.get("source_enums")
676
+ try:
677
+ for sub_type_str in source_enums or []:
678
+ sub_type = builder.parse_type(self.namespace, sub_type_str)
679
+ assert isinstance(sub_type, SpecTypeDefnStringEnum)
680
+ assert len(sub_type.values) > 0
681
+ except AssertionError:
682
+ return False
683
+ return super().can_process(builder, data)
669
684
 
670
685
  def process(self, builder: SpecBuilder, data: RawDict) -> None:
671
686
  super().base_process(
672
- builder, data, ["type", "desc", "values", "name_case", "sql", "emit"]
687
+ builder,
688
+ data,
689
+ ["type", "desc", "values", "name_case", "sql", "emit", "source_enums"],
673
690
  )
674
691
  self.name_case = NameCase(data.get("name_case", "convert"))
675
692
  self.values = {}
676
- data_values = data["values"]
693
+ data_values = data.get("values")
677
694
  self.desc = data.get("desc", None)
695
+ source_enums = data.get("source_enums", None)
678
696
  if isinstance(data_values, dict):
679
697
  for name, value in data_values.items():
680
698
  builder.push_where(name)
@@ -717,7 +735,8 @@ class SpecTypeDefnStringEnum(SpecTypeDefn):
717
735
  )
718
736
  self.values[value] = StringEnumEntry(name=value, value=value)
719
737
  else:
720
- raise Exception("unsupported values type")
738
+ if source_enums is None or data_values is not None:
739
+ raise Exception("unsupported values type")
721
740
 
722
741
  sql_data = data.get("sql")
723
742
  if sql_data is not None:
@@ -739,9 +758,18 @@ class SpecTypeDefnStringEnum(SpecTypeDefn):
739
758
  builder.ensure(
740
759
  entry.label is not None, f"need-label-for-id-source:{entry.name}"
741
760
  )
761
+ for sub_type_str in source_enums or []:
762
+ sub_type = builder.parse_type(self.namespace, sub_type_str)
763
+ self.source_enums.append(sub_type)
764
+
765
+ for sub_type in self.source_enums:
766
+ builder.push_where(sub_type.name)
767
+ if isinstance(sub_type, SpecTypeDefnStringEnum):
768
+ self.values.update(sub_type.values)
769
+ builder.pop_where()
742
770
 
743
771
  def get_referenced_types(self) -> list[SpecType]:
744
- return []
772
+ return self.source_enums
745
773
 
746
774
 
747
775
  TOKEN_ENDPOINT = "$endpoint"
@@ -1122,28 +1150,41 @@ class SpecNamespace:
1122
1150
  Complete the definition of each type.
1123
1151
  """
1124
1152
  builder.push_where(self.name)
1125
- for full_name, defn in data.items():
1126
- parsed_name = parse_type_str(full_name)[0]
1127
- name = parsed_name.name
1153
+ items_to_process: list[NameDataPair] = [
1154
+ NameDataPair(full_name=full_name, data=defn)
1155
+ for full_name, defn in data.items()
1156
+ ]
1157
+ while len(items_to_process) > 0:
1158
+ deferred_items: list[NameDataPair] = []
1159
+ for item in items_to_process:
1160
+ full_name = item.full_name
1161
+ defn = item.data
1162
+ parsed_name = parse_type_str(full_name)[0]
1163
+ name = parsed_name.name
1164
+
1165
+ if name in [TOKEN_EMIT_IO_TS, TOKEN_EMIT_TYPE_INFO, TOKEN_IMPORT]:
1166
+ continue
1128
1167
 
1129
- if name in [TOKEN_EMIT_IO_TS, TOKEN_EMIT_TYPE_INFO, TOKEN_IMPORT]:
1130
- continue
1168
+ builder.push_where(name)
1131
1169
 
1132
- builder.push_where(name)
1170
+ if "value" in defn:
1171
+ spec_constant = self.constants[name]
1172
+ spec_constant.process(builder, defn)
1133
1173
 
1134
- if "value" in defn:
1135
- spec_constant = self.constants[name]
1136
- spec_constant.process(builder, defn)
1174
+ elif name == TOKEN_ENDPOINT:
1175
+ assert self.endpoint
1176
+ self.endpoint.process(builder, defn)
1137
1177
 
1138
- elif name == TOKEN_ENDPOINT:
1139
- assert self.endpoint
1140
- self.endpoint.process(builder, defn)
1141
-
1142
- else:
1143
- spec_type = self.types[name]
1144
- spec_type.process(builder, defn)
1178
+ else:
1179
+ spec_type = self.types[name]
1180
+ if spec_type.can_process(builder, defn):
1181
+ spec_type.process(builder, defn)
1182
+ else:
1183
+ deferred_items.append(item)
1145
1184
 
1146
- builder.pop_where()
1185
+ builder.pop_where()
1186
+ assert len(deferred_items) < len(items_to_process)
1187
+ items_to_process = [deferred for deferred in deferred_items]
1147
1188
 
1148
1189
  builder.pop_where()
1149
1190
 
@@ -1158,8 +1199,15 @@ class NamespaceDataPair:
1158
1199
  data: RawDict
1159
1200
 
1160
1201
 
1202
+ @dataclass(kw_only=True)
1203
+ class NameDataPair:
1204
+ full_name: str
1205
+ data: RawDict
1206
+
1207
+
1161
1208
  class SpecBuilder:
1162
- def __init__(self, *, api_endpoints: dict[str, str]) -> None:
1209
+ def __init__(self, *, api_endpoints: dict[str, str], top_namespace: str) -> None:
1210
+ self.top_namespace = top_namespace
1163
1211
  self.where: list[str] = []
1164
1212
  self.namespaces = {}
1165
1213
  self.pending: list[NamespaceDataPair] = []
@@ -86,6 +86,7 @@ class OpenAPIConfig(BaseLanguageConfig):
86
86
 
87
87
  @dataclass(kw_only=True)
88
88
  class Config:
89
+ top_namespace: str
89
90
  type_spec_types: list[str] # folders containing the yaml type spec definitions
90
91
  api_endpoint: dict[str, str]
91
92
  # languages
@@ -130,7 +131,11 @@ def parse_yaml_config(config_file: str) -> Config:
130
131
  else None
131
132
  )
132
133
 
134
+ top_namespace = raw_config["top_namespace"]
135
+ assert isinstance(top_namespace, str)
136
+
133
137
  return Config(
138
+ top_namespace=top_namespace,
134
139
  type_spec_types=type_spec_types,
135
140
  api_endpoint=api_endpoint,
136
141
  typescript=typescript,
@@ -44,7 +44,6 @@ class TrackingContext:
44
44
  use_enum: bool = False
45
45
  use_serial_string_enum: bool = False
46
46
  use_dataclass: bool = False
47
- use_serial_class: bool = False
48
47
  use_serial_union: bool = False
49
48
  use_missing: bool = False
50
49
  use_opaque_key: bool = False
@@ -54,6 +53,7 @@ class TrackingContext:
54
53
  class Context(TrackingContext):
55
54
  out: io.StringIO
56
55
  namespace: builder.SpecNamespace
56
+ builder: builder.SpecBuilder
57
57
 
58
58
 
59
59
  def _resolve_namespace_name(namespace: builder.SpecNamespace) -> str:
@@ -222,7 +222,6 @@ def _emit_types_imports(*, out: io.StringIO, ctx: Context) -> None:
222
222
  out.write("from pkgs.strenum_compat import StrEnum\n")
223
223
  if ctx.use_dataclass:
224
224
  out.write("import dataclasses\n")
225
- if ctx.use_serial_class:
226
225
  out.write("from pkgs.serialization import serial_class\n")
227
226
  if ctx.use_serial_union:
228
227
  out.write("from pkgs.serialization import serial_union_annotation\n")
@@ -258,6 +257,7 @@ def _emit_types(*, builder: builder.SpecBuilder, config: PythonConfig) -> None:
258
257
  ctx = Context(
259
258
  out=io.StringIO(),
260
259
  namespace=namespace,
260
+ builder=builder,
261
261
  )
262
262
 
263
263
  _emit_namespace(ctx, namespace)
@@ -753,6 +753,12 @@ def _emit_properties(
753
753
  )
754
754
 
755
755
 
756
+ def _named_type_path(ctx: Context, stype: builder.SpecTypeDefn) -> str:
757
+ parts = [] if stype.is_base else stype.namespace.path.copy()
758
+ parts.append(stype.name)
759
+ return f"{ctx.builder.top_namespace}.{".".join(parts)}"
760
+
761
+
756
762
  def _emit_type(ctx: Context, stype: builder.SpecType) -> None:
757
763
  if not isinstance(stype, builder.SpecTypeDefn):
758
764
  return
@@ -781,6 +787,9 @@ def _emit_type(ctx: Context, stype: builder.SpecType) -> None:
781
787
  ctx.out.write(f"{stype.name} = typing.Annotated[\n")
782
788
  ctx.out.write(f"{INDENT}{refer_to(ctx, stype.get_backing_type())},\n")
783
789
  ctx.out.write(f"{INDENT}serial_union_annotation(\n")
790
+ ctx.out.write(
791
+ f"{INDENT}named_type_path={util.encode_common_string(_named_type_path(ctx, stype))},\n"
792
+ )
784
793
  if stype.discriminator is not None:
785
794
  ctx.out.write(
786
795
  f"{INDENT * 2}discriminator={util.encode_common_string(stype.discriminator)},\n"
@@ -822,28 +831,26 @@ def _emit_type(ctx: Context, stype: builder.SpecType) -> None:
822
831
 
823
832
  _emit_generic(ctx, stype.get_generic())
824
833
 
825
- if (
826
- len(unconverted_values) > 0
827
- or len(to_string_values) > 0
828
- or len(unconverted_keys) > 0
829
- or len(parse_require) > 0
830
- ):
831
- ctx.use_serial_class = True
832
- ctx.out.write("@serial_class(\n")
834
+ # Emit serial_class decorator
835
+ ctx.out.write("@serial_class(\n")
836
+ ctx.out.write(
837
+ f"{INDENT}named_type_path={util.encode_common_string(_named_type_path(ctx, stype))},\n"
838
+ )
833
839
 
834
- def write_values(key: str, values: set[str]) -> None:
835
- if len(values) == 0:
836
- return
837
- value_str = ", ".join([f'"{name}"' for name in sorted(values)])
838
- ctx.out.write(f"{INDENT}{key}={{{value_str}}},\n")
840
+ def write_values(key: str, values: set[str]) -> None:
841
+ if len(values) == 0:
842
+ return
843
+ value_str = ", ".join([f'"{name}"' for name in sorted(values)])
844
+ ctx.out.write(f"{INDENT}{key}={{{value_str}}},\n")
839
845
 
840
- write_values("unconverted_keys", unconverted_keys)
841
- write_values("unconverted_values", unconverted_values)
842
- write_values("to_string_values", to_string_values)
843
- write_values("parse_require", parse_require)
846
+ write_values("unconverted_keys", unconverted_keys)
847
+ write_values("unconverted_values", unconverted_values)
848
+ write_values("to_string_values", to_string_values)
849
+ write_values("parse_require", parse_require)
844
850
 
845
- ctx.out.write(")\n")
851
+ ctx.out.write(")\n")
846
852
 
853
+ # Emit dataclass decorator
847
854
  dataclass = "@dataclasses.dataclass"
848
855
  dc_args = []
849
856
  if stype.is_kw_only():
@@ -1275,7 +1282,9 @@ def _emit_async_batch_processor(
1275
1282
 
1276
1283
  async_batch_processor_out = io.StringIO()
1277
1284
  ctx = Context(
1278
- out=io.StringIO(), namespace=builder.SpecNamespace("async_batch_processor")
1285
+ out=io.StringIO(),
1286
+ namespace=builder.SpecNamespace("async_batch_processor"),
1287
+ builder=spec_builder,
1279
1288
  )
1280
1289
 
1281
1290
  for namespace in sorted(
@@ -1325,7 +1334,11 @@ def _emit_client_class(
1325
1334
  return
1326
1335
 
1327
1336
  client_base_out = io.StringIO()
1328
- ctx = Context(out=io.StringIO(), namespace=builder.SpecNamespace("client_base"))
1337
+ ctx = Context(
1338
+ out=io.StringIO(),
1339
+ builder=spec_builder,
1340
+ namespace=builder.SpecNamespace("client_base"),
1341
+ )
1329
1342
  for namespace in sorted(
1330
1343
  spec_builder.namespaces.values(),
1331
1344
  key=lambda ns: _resolve_namespace_name(ns),
@@ -82,6 +82,25 @@ def emit_typescript(builder: builder.SpecBuilder, config: TypeScriptConfig) -> N
82
82
  _emit_id_source(builder, config)
83
83
 
84
84
 
85
+ def emit_namespace_imports_ts(
86
+ namespaces: set[builder.SpecNamespace],
87
+ out: io.StringIO,
88
+ current_namespace: builder.SpecNamespace,
89
+ ) -> None:
90
+ for ns in sorted(
91
+ namespaces,
92
+ key=lambda name: _resolve_namespace_name(name),
93
+ ):
94
+ import_as = resolve_namespace_ref(ns)
95
+ import_path = (
96
+ "./"
97
+ if len(current_namespace.path) == 1
98
+ else "../" * (len(current_namespace.path) - 1)
99
+ )
100
+ import_from = f"{import_path}{_resolve_namespace_name(ns)}"
101
+ out.write(f'import * as {import_as} from "{import_from}"\n') # noqa: E501
102
+
103
+
85
104
  def _emit_types(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
86
105
  index_out = io.StringIO()
87
106
  index_out.write(MODIFY_NOTICE)
@@ -92,11 +111,9 @@ def _emit_types(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
92
111
  builder.namespaces.values(),
93
112
  key=lambda ns: _resolve_namespace_name(ns),
94
113
  ):
95
- ctx = EmitTypescriptContext(
96
- out=io.StringIO(), namespace=namespace, config=config
97
- )
114
+ ctx = EmitTypescriptContext(out=io.StringIO(), namespace=namespace)
98
115
 
99
- _emit_namespace(ctx, namespace)
116
+ _emit_namespace(ctx, config, namespace)
100
117
 
101
118
  prepart = builder.preparts["typescript"].get(namespace.name)
102
119
  part = builder.parts["typescript"].get(namespace.name)
@@ -123,16 +140,7 @@ def _emit_types(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
123
140
  full.write(f"// === END section from {namespace.name}.ts.prepart ===\n")
124
141
  full.write("\n")
125
142
 
126
- for ns in sorted(
127
- ctx.namespaces,
128
- key=lambda name: _resolve_namespace_name(name),
129
- ):
130
- import_as = resolve_namespace_ref(ns)
131
- import_path = (
132
- "./" if len(namespace.path) == 1 else "../" * (len(namespace.path) - 1)
133
- )
134
- import_from = f"{import_path}{_resolve_namespace_name(ns)}"
135
- full.write(f'import * as {import_as} from "{import_from}"\n') # noqa: E501
143
+ emit_namespace_imports_ts(ctx.namespaces, out=full, current_namespace=namespace)
136
144
  if namespace.emit_io_ts:
137
145
  full.write("import * as IO from 'io-ts';")
138
146
  full.write(ctx.out.getvalue())
@@ -164,23 +172,26 @@ def _emit_types(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
164
172
 
165
173
 
166
174
  def _emit_namespace(
167
- ctx: EmitTypescriptContext, namespace: builder.SpecNamespace
175
+ ctx: EmitTypescriptContext,
176
+ config: TypeScriptConfig,
177
+ namespace: builder.SpecNamespace,
168
178
  ) -> None:
169
179
  for stype in namespace.types.values():
170
180
  if namespace.emit_io_ts:
171
181
  emit_type_io_ts(ctx, stype, namespace.derive_types_from_io_ts)
172
182
  if not namespace.emit_io_ts or not namespace.derive_types_from_io_ts:
173
- _emit_type(ctx, stype)
183
+ emit_type_ts(ctx, stype)
174
184
 
175
185
  for sconst in namespace.constants.values():
176
186
  _emit_constant(ctx, sconst)
177
187
 
178
188
  if namespace.endpoint is not None:
179
- _emit_endpoint(ctx, namespace, namespace.endpoint)
189
+ _emit_endpoint(ctx, config, namespace, namespace.endpoint)
180
190
 
181
191
 
182
192
  def _emit_endpoint(
183
193
  ctx: EmitTypescriptContext,
194
+ config: TypeScriptConfig,
184
195
  namespace: builder.SpecNamespace,
185
196
  endpoint: builder.SpecEndpoint,
186
197
  ) -> None:
@@ -265,14 +276,12 @@ export const apiCall = {wrap_call}(
265
276
  )
266
277
  {data_loader_body}"""
267
278
 
268
- output = f"{ctx.config.routes_output}/{"/".join(namespace.path)}.tsx"
279
+ output = f"{config.routes_output}/{"/".join(namespace.path)}.tsx"
269
280
  util.rewrite_file(output, tsx_api)
270
281
 
271
282
  # Hacky index support, until enough is migrated to regen entirely
272
283
  # Emits the import into the UI API index file
273
- index_path = (
274
- f"{ctx.config.routes_output}/{"/".join(namespace.path[0:-1])}/index.tsx"
275
- )
284
+ index_path = f"{config.routes_output}/{"/".join(namespace.path[0:-1])}/index.tsx"
276
285
  api_name = f"Api{ts_type_name(namespace.path[0 - 1])}"
277
286
  if os.path.exists(index_path):
278
287
  with open(index_path) as index:
@@ -288,7 +297,7 @@ export const apiCall = {wrap_call}(
288
297
  index.write(f"export {{ {api_name} }}\n")
289
298
 
290
299
 
291
- def _emit_type(ctx: EmitTypescriptContext, stype: builder.SpecType) -> None:
300
+ def emit_type_ts(ctx: EmitTypescriptContext, stype: builder.SpecType) -> None:
292
301
  if not isinstance(stype, builder.SpecTypeDefn):
293
302
  return
294
303
 
@@ -2,7 +2,6 @@ import io
2
2
  from dataclasses import dataclass, field
3
3
 
4
4
  from . import builder, util
5
- from .config import TypeScriptConfig
6
5
 
7
6
  INDENT = " "
8
7
 
@@ -11,7 +10,6 @@ MODIFY_NOTICE = "// DO NOT MODIFY -- This file is generated by type_spec\n"
11
10
 
12
11
  @dataclass(kw_only=True)
13
12
  class EmitTypescriptContext:
14
- config: TypeScriptConfig
15
13
  out: io.StringIO
16
14
  namespace: builder.SpecNamespace
17
15
  namespaces: set[builder.SpecNamespace] = field(default_factory=set)
@@ -42,7 +42,9 @@ def find_and_handle_files(
42
42
 
43
43
 
44
44
  def load_types(config: Config) -> Optional[SpecBuilder]:
45
- builder = SpecBuilder(api_endpoints=config.api_endpoint)
45
+ builder = SpecBuilder(
46
+ api_endpoints=config.api_endpoint, top_namespace=config.top_namespace
47
+ )
46
48
 
47
49
  def handle_builder_add(
48
50
  file_name: str, file_content: str, handler: Callable[[str, str, str], None]
@@ -115,4 +117,3 @@ def load_types(config: Config) -> Optional[SpecBuilder]:
115
117
  return None
116
118
 
117
119
  return builder
118
- return True
@@ -5,7 +5,7 @@ import io
5
5
  import json
6
6
  from typing import Any, Optional, Union, cast
7
7
 
8
- from main.base.types import data_t
8
+ from main.base.types import data_t, type_info_t
9
9
  from main.base.types.base_t import PureJsonValue
10
10
  from pkgs.argument_parser import CachedParser
11
11
  from pkgs.serialization_util import (
@@ -17,7 +17,7 @@ from .. import builder, util
17
17
  from ..emit_typescript_util import MODIFY_NOTICE, ts_name
18
18
  from ..value_spec import convert_to_value_spec_type
19
19
 
20
- ext_info_parser = CachedParser(data_t.ExtInfo)
20
+ ext_info_parser = CachedParser(type_info_t.ExtInfo, strict_property_parsing=True)
21
21
 
22
22
 
23
23
  def type_path_of(stype: builder.SpecType) -> object: # NamePath
@@ -174,7 +174,7 @@ class InheritablePropertyParts:
174
174
 
175
175
  label: Optional[str] = None
176
176
  desc: Optional[str] = None
177
- ext_info: Optional[data_t.ExtInfo] = None
177
+ ext_info: Optional[type_info_t.ExtInfo] = None
178
178
 
179
179
 
180
180
  def _extract_inheritable_property_parts(
@@ -201,7 +201,7 @@ def _extract_inheritable_property_parts(
201
201
  elif base_parts.ext_info is None:
202
202
  ext_info = local_ext_info
203
203
  else:
204
- ext_info = data_t.ExtInfo(
204
+ ext_info = type_info_t.ExtInfo(
205
205
  **(local_ext_info.__dict__ | base_parts.ext_info.__dict__)
206
206
  )
207
207
 
@@ -214,7 +214,7 @@ ALL_FIELDS_GROUP = "*all_fields"
214
214
 
215
215
  def _extract_and_validate_layout(
216
216
  stype: builder.SpecTypeDefnObject,
217
- ext_info: data_t.ExtInfo,
217
+ ext_info: type_info_t.ExtInfo,
218
218
  base_layout: ExtInfoLayout | None,
219
219
  ) -> ExtInfoLayout:
220
220
  """
@@ -264,7 +264,7 @@ def _extract_and_validate_layout(
264
264
 
265
265
  def _validate_type_ext_info(
266
266
  stype: builder.SpecTypeDefnObject,
267
- ) -> tuple[ExtInfoLayout | None, Optional[data_t.ExtInfo]]:
267
+ ) -> tuple[ExtInfoLayout | None, Optional[type_info_t.ExtInfo]]:
268
268
  ext_info = _parse_ext_info(stype.ext_info)
269
269
  if ext_info is None:
270
270
  return None, None
@@ -364,7 +364,7 @@ def _build_map_type(
364
364
  return None
365
365
 
366
366
 
367
- def _parse_ext_info(in_ext: Any) -> Optional[data_t.ExtInfo]:
367
+ def _parse_ext_info(in_ext: Any) -> Optional[type_info_t.ExtInfo]:
368
368
  if in_ext is None:
369
369
  return None
370
370
  assert isinstance(in_ext, dict)
@@ -159,7 +159,7 @@ def is_valid_property_name(name: str) -> bool:
159
159
  def check_fields(data: dict[str, T], allowed: list[str]) -> None:
160
160
  for key in data:
161
161
  if key not in allowed:
162
- raise Exception(f"unexpected-field: {key}")
162
+ raise Exception(f"unexpected-field: {key}. Allowed: {allowed}")
163
163
 
164
164
 
165
165
  def split_any_name(name: str) -> list[str]:
@@ -65,7 +65,7 @@ class ClientConfig(ClientConfigOptions):
65
65
  OAUTH_REFRESH_WINDOW_SECONDS = 60 * 5
66
66
 
67
67
 
68
- class APIResponseError(BaseException):
68
+ class APIResponseError(Exception):
69
69
  status_code: int
70
70
  message: str
71
71
  extra_details: dict[str, JsonValue] | None
@@ -107,7 +107,7 @@ class APIResponseError(BaseException):
107
107
  )
108
108
 
109
109
 
110
- class SDKError(BaseException):
110
+ class SDKError(Exception):
111
111
  message: str
112
112
  request_id: str
113
113