UncountablePythonSDK 0.0.75__py3-none-any.whl → 0.0.77__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.

Potentially problematic release.


This version of UncountablePythonSDK might be problematic. Click here for more details.

Files changed (45) hide show
  1. {UncountablePythonSDK-0.0.75.dist-info → UncountablePythonSDK-0.0.77.dist-info}/METADATA +2 -2
  2. {UncountablePythonSDK-0.0.75.dist-info → UncountablePythonSDK-0.0.77.dist-info}/RECORD +45 -39
  3. docs/requirements.txt +1 -1
  4. examples/async_batch.py +3 -3
  5. pkgs/argument_parser/argument_parser.py +7 -7
  6. pkgs/filesystem_utils/_s3_session.py +3 -3
  7. pkgs/serialization/serial_class.py +3 -0
  8. pkgs/type_spec/builder.py +26 -27
  9. pkgs/type_spec/config.py +3 -3
  10. pkgs/type_spec/emit_io_ts.py +6 -6
  11. pkgs/type_spec/emit_open_api.py +4 -4
  12. pkgs/type_spec/emit_python.py +20 -20
  13. pkgs/type_spec/emit_typescript.py +4 -4
  14. pkgs/type_spec/emit_typescript_util.py +4 -4
  15. pkgs/type_spec/type_info/emit_type_info.py +6 -6
  16. uncountable/core/environment.py +15 -2
  17. uncountable/core/file_upload.py +1 -3
  18. uncountable/integration/construct_client.py +3 -4
  19. uncountable/integration/executors/generic_upload_executor.py +7 -7
  20. uncountable/integration/executors/script_executor.py +3 -3
  21. uncountable/integration/queue_runner/job_scheduler.py +1 -1
  22. uncountable/integration/queue_runner/worker.py +3 -8
  23. uncountable/integration/scan_profiles.py +39 -15
  24. uncountable/integration/secret_retrieval/retrieve_secret.py +1 -1
  25. uncountable/integration/server.py +4 -12
  26. uncountable/integration/telemetry.py +2 -2
  27. uncountable/integration/webhook_server/entrypoint.py +4 -10
  28. uncountable/types/__init__.py +8 -0
  29. uncountable/types/api/entity/create_entities.py +4 -2
  30. uncountable/types/api/entity/create_entity.py +4 -2
  31. uncountable/types/api/entity/grant_entity_permissions.py +48 -0
  32. uncountable/types/api/recipes/get_column_calculation_values.py +58 -0
  33. uncountable/types/async_batch_processor.py +43 -0
  34. uncountable/types/async_batch_t.py +1 -0
  35. uncountable/types/auth_retrieval.py +12 -0
  36. uncountable/types/auth_retrieval_t.py +75 -0
  37. uncountable/types/client_base.py +62 -4
  38. uncountable/types/entity.py +3 -0
  39. uncountable/types/entity_t.py +20 -0
  40. uncountable/types/integration_server.py +9 -0
  41. uncountable/types/integration_server_t.py +37 -0
  42. uncountable/types/job_definition.py +1 -5
  43. uncountable/types/job_definition_t.py +20 -60
  44. {UncountablePythonSDK-0.0.75.dist-info → UncountablePythonSDK-0.0.77.dist-info}/WHEEL +0 -0
  45. {UncountablePythonSDK-0.0.75.dist-info → UncountablePythonSDK-0.0.77.dist-info}/top_level.txt +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: UncountablePythonSDK
3
- Version: 0.0.75
3
+ Version: 0.0.77
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
@@ -16,7 +16,7 @@ Classifier: Topic :: Utilities
16
16
  Classifier: Typing :: Typed
17
17
  Requires-Python: >=3.11
18
18
  Description-Content-Type: text/markdown
19
- Requires-Dist: aiotus ==0.*
19
+ Requires-Dist: aiotus ==1.*
20
20
  Requires-Dist: aiohttp ==3.*
21
21
  Requires-Dist: requests ==2.*
22
22
  Requires-Dist: SQLAlchemy >=1.4.0
@@ -3,7 +3,7 @@ docs/conf.py,sha256=YF5J-9g_Wg8wXmyHsGaE8xYlDEzqocNl3UWUmP0CwBg,1702
3
3
  docs/index.md,sha256=eEdirX_Ds6ICTRtIS5iT4irCquHcQyKN7E4M5QP9T8A,257
4
4
  docs/justfile,sha256=cvNcpb-ByPOF2aCrFlg3DDZBoYMx5W8xGdr13m9HcnI,215
5
5
  docs/quickstart.md,sha256=3GuJ0MB1O5kjlsrgAmdSkDq0rYqATrYy-tzEHDy8H-c,422
6
- docs/requirements.txt,sha256=pHca02KQbB3qx4V6MUrwtctgvIheT--jGQvs6OVqaUg,138
6
+ docs/requirements.txt,sha256=XNw3eJfJPf6Z2DpwtcNgEJpoEKS0g5v3vY6UBFtiEKM,138
7
7
  docs/static/logo_blue.png,sha256=SyYpMTVhhBbhF5Wl8lWaVwz-_p1MIR6dW6bVhufQRME,46708
8
8
  docs/static/favicons/android-chrome-192x192.png,sha256=XoF-AhD55JlSBDGsEPJKfT_VeXT-awhwKyZnxLhrwvk,1369
9
9
  docs/static/favicons/android-chrome-512x512.png,sha256=1S4xwY9YtJQ5ifFsZ-DOzssoyBYs0t9uwdOUmYx0Xso,3888
@@ -14,7 +14,7 @@ docs/static/favicons/favicon-32x32.png,sha256=U4UU652zGnSeU3P9kUqxPeEnVf6zhtdNdN
14
14
  docs/static/favicons/manifest.json,sha256=6q_3nZkcg_x0xut4eE-xpdeMY1TydwiZIcbXlLAq9X8,437
15
15
  docs/static/favicons/mstile-150x150.png,sha256=eAK4QdEofhdLtfmjuPTpnX3MJqYnvGXsHYUjlcQekyY,1035
16
16
  docs/static/favicons/safari-pinned-tab.svg,sha256=S84fRnz0ZxLnQrKtmmFZytiRyu1xLtMR_RVy5jmwU7k,1926
17
- examples/async_batch.py,sha256=CffQ8O9drJ-Mdd6S5DnMIOBsHv5aVkTZrD3l3xBnB4s,1094
17
+ examples/async_batch.py,sha256=tEyvgxk2uf681mKlN4TDuPMkb1OHyM9oO8pYW4A7HvM,1142
18
18
  examples/create_entity.py,sha256=t6WBZsWRDbWZgFCWXKGgKL5LAB6-38oaiNYGxMAa2No,686
19
19
  examples/edit_recipe_inputs.py,sha256=mtk_oSkN-OT2hKkb1XKXrRiUaGYTJstXuOKyTR51Fjo,1663
20
20
  examples/invoke_uploader.py,sha256=rEvmVY5TjigN_-4PTQdkjY-bC5DrYMcJgquyZ4Tt5FM,748
@@ -29,19 +29,19 @@ pkgs/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
29
29
  pkgs/argument_parser/__init__.py,sha256=JRfZkC0-q6axr8F5_TKrjSprJ7d7chfcPvf-iMQqFg0,447
30
30
  pkgs/argument_parser/_is_enum.py,sha256=Gw6jJa8nBwYGqXwwCZbSnWL8Rvr5alkg5lSVAqXtOZM,257
31
31
  pkgs/argument_parser/_is_namedtuple.py,sha256=Rjc1bKanIPPogl3qG5JPBxglG1TqWYOo1nxxhBASQWY,265
32
- pkgs/argument_parser/argument_parser.py,sha256=Z8lR_2L_N0zuxdOsK91D_9mjlsCcR_FJwtCLIfJz5oI,17713
32
+ pkgs/argument_parser/argument_parser.py,sha256=XjWQdcWanfaCGdLx7c_yQtqbZp7db-KAWzw8sTpXOsY,17713
33
33
  pkgs/argument_parser/case_convert.py,sha256=NuJLJUJRbyVb6_Slen4uqaStEHbcOS1d-hBBfDrrw-c,605
34
34
  pkgs/filesystem_utils/__init__.py,sha256=NSsQrUCoGISBCqCCyq6_583sYHTVEQeDjDO8hvZn3ag,1261
35
35
  pkgs/filesystem_utils/_gdrive_session.py,sha256=GJuZYJq1W4QQ_7OLvZIMK99FgRq8FxJHg6cMUx9prtA,11077
36
36
  pkgs/filesystem_utils/_local_session.py,sha256=xFEYhAvNqrOYqwt4jrEYOuYkjJn0zclZhTelW_Q1-rw,2325
37
- pkgs/filesystem_utils/_s3_session.py,sha256=FSdCZBmargKgOWDfyvlsgVNJxwYHBrmHscD9pjN6Bgk,3962
37
+ pkgs/filesystem_utils/_s3_session.py,sha256=_jLK5C-UElT5Sl5teM2pFR7fQe11NlhUd04EgwN9FRs,3962
38
38
  pkgs/filesystem_utils/_sftp_session.py,sha256=6zoF7YsEUp0GpyFb-BeIhUAWvbTK7IUjvPNJ1B0vEyI,4743
39
39
  pkgs/filesystem_utils/file_type_utils.py,sha256=Xd-mg35mAENUgNJVz5uK8nEfrUp-NQld_gnXFEq3K-8,1487
40
40
  pkgs/filesystem_utils/filesystem_session.py,sha256=BQ2Go8Mu9-GcnaWh2Pm4x7ugLVsres6XrOQ8RoiEpcE,1045
41
41
  pkgs/serialization/__init__.py,sha256=LifasRW0a50A3qRFmo2bf3FQ6TXhZWOTz2-CVTgPjcQ,753
42
42
  pkgs/serialization/missing_sentry.py,sha256=aM_9KxbCk9dVvXvcOKgkIQBqFWvLhv8QlIUCiuFEXMo,806
43
43
  pkgs/serialization/opaque_key.py,sha256=FIfXEE0DA1U8R_taFbQ1RCoTSgehrPjP06-qvo-GeNQ,177
44
- pkgs/serialization/serial_class.py,sha256=D7vSnfJw4rWEDFbDd07pxgzyfTFZT5SKeQEv4C1c4H0,6057
44
+ pkgs/serialization/serial_class.py,sha256=xURwC05-ImnHU1pKM8BBYpzbrhTtiZr30UlzaA0T7zY,6110
45
45
  pkgs/serialization/serial_union.py,sha256=xpdeqCrRd0sNCaUwBQRzje6V40ndCbJpZrLX2K0d5xo,2741
46
46
  pkgs/serialization/yaml.py,sha256=yoJtu7_ixnJV6uTxA_U1PpK5F_ixT08AKVh5ocyYwXM,1466
47
47
  pkgs/serialization_util/__init__.py,sha256=MVKqHTUl2YnWZAFG9xCxu1SgmkQ5xPofrAGlYg6h7rI,330
@@ -52,14 +52,14 @@ pkgs/strenum_compat/__init__.py,sha256=wXRFeNvBm8RU6dy1PFJ5sRLgUIEeH_DVR95Sv5qpG
52
52
  pkgs/strenum_compat/strenum_compat.py,sha256=uOUAgpYTjHs1MX8dG81jRlyTkt3KNbkV_25zp7xTX2s,36
53
53
  pkgs/type_spec/__init__.py,sha256=h5DmJTca4QVV10sZR1x0-MlkZfuGYDfapR3zHvXfzto,19
54
54
  pkgs/type_spec/__main__.py,sha256=5bJaX9Y_-FavP0qwzhk-z-V97UY7uaezJTa1zhO_HHQ,1048
55
- pkgs/type_spec/builder.py,sha256=nuHdVNOmwbHbHV5_8nqtsrxOfzIII6jcQO7eLOljT4c,48856
56
- pkgs/type_spec/config.py,sha256=ZUmPWCzTwjesAqlqeL1_E_yoIUZE_8g0kI2yXtbU0Zc,4811
57
- pkgs/type_spec/emit_io_ts.py,sha256=U03sQBpgRqYOaMKrPCRnYb70YboiCgaZfseCXSzW5NY,5707
58
- pkgs/type_spec/emit_open_api.py,sha256=5a0iAHBbgFD4wfKuyjPvxCYYHNTjKxEHA0aYjMGSqe4,24596
55
+ pkgs/type_spec/builder.py,sha256=0CF9xJaZ74LsmRh4GzgxBsUkTjAObariAB0M399r-MI,48796
56
+ pkgs/type_spec/config.py,sha256=pMUNnpZRuS8hybgcPZiVYXz79qZcO9i_ZoiFAgbtVq4,4813
57
+ pkgs/type_spec/emit_io_ts.py,sha256=CUvBs0boB_X-Kndh66yYcqFfq3oC_LGs8YffLkJ0ZXA,5707
58
+ pkgs/type_spec/emit_open_api.py,sha256=_oBTuYixZUp3DT2cJaiY55VnCi_jGjqV_1vBx2dYdsw,24596
59
59
  pkgs/type_spec/emit_open_api_util.py,sha256=x4GCiZSGdypJ9Qtm6I5W_3UvwdJyMs8_OGhJ8_THznA,2401
60
- pkgs/type_spec/emit_python.py,sha256=eBct7PMYgcv35POo2JU089lLggPrgLfTOrKpqAukn1E,47370
61
- pkgs/type_spec/emit_typescript.py,sha256=PL1h2UvTp1PRMkTXH893ZYS3cPUrrupjnLg_9ndZGDQ,8838
62
- pkgs/type_spec/emit_typescript_util.py,sha256=e2rGSs9OTD-iXwcHfU4V9E35jwMc5qVshhOKMknGrJ8,10319
60
+ pkgs/type_spec/emit_python.py,sha256=GC-HSMTS0E0QgREjv8DbMRA9NJ1RkYywTOTqZ5ZHmkM,47375
61
+ pkgs/type_spec/emit_typescript.py,sha256=PNeXHoeMA8UWgxsgJisIhJeFX5CNXn0NIz8UtgTvxes,8838
62
+ pkgs/type_spec/emit_typescript_util.py,sha256=lG3Wtm5vN6etE0NeYrKfnrxj1vVWGzQBSDcDItaszWk,10319
63
63
  pkgs/type_spec/load_types.py,sha256=vO8VLI7aTKzzHQIla-WO-5Z_mfTuwUqH4ZSKN9E9n5U,3688
64
64
  pkgs/type_spec/open_api_util.py,sha256=IGh-_snGPST_P_8FdYtO8MTEa9PUxRW6Rzg9X9EgQik,7114
65
65
  pkgs/type_spec/test.py,sha256=4ueujBq-pEgnX3Z69HyPmD-bullFXmpixcpVzfOkhP4,489
@@ -70,7 +70,7 @@ pkgs/type_spec/actions_registry/emit_typescript.py,sha256=Z1ZM4zOw26tvLspvW6Emg7
70
70
  pkgs/type_spec/parts/base.py.prepart,sha256=wGNoDyQnLolHRZGRwHQX5TrPfKnu558NXCocYvqyroc,2174
71
71
  pkgs/type_spec/parts/base.ts.prepart,sha256=2FJJvpg2olCcavxj0nbYWdwKl6KeScour2JjSvN42l8,1001
72
72
  pkgs/type_spec/type_info/__main__.py,sha256=pmVjVqXyVh8vKTNCTFgz80Sg74C5BKToP3E6GS-X_So,857
73
- pkgs/type_spec/type_info/emit_type_info.py,sha256=C4Rq5z22c3IJTyQriNkQWgGV7I3ZgTDjwKm_JM_sOYI,13362
73
+ pkgs/type_spec/type_info/emit_type_info.py,sha256=EzX0ONjrLtQFlN5cEAaw2RPVyadmgmZazOfqHUbL_PI,13362
74
74
  pkgs/type_spec/value_spec/__init__.py,sha256=Z-grlcZtxAfEXhPHsK0nD7PFLGsv4eqvunaPN7_TA84,83
75
75
  pkgs/type_spec/value_spec/__main__.py,sha256=6bzP85p_Cm4bPp5tXz8D_4p64wMn5SKsXC7SqSZquYc,8318
76
76
  pkgs/type_spec/value_spec/convert_type.py,sha256=Tg5YsYOwvmf_EqbCAtCmqy3-dud8OwdbEOzAaRN7cCs,2286
@@ -81,31 +81,31 @@ uncountable/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
81
81
  uncountable/core/__init__.py,sha256=RFv0kO6rKFf1PtBPu83hCGmxqkJamRtsgQ9_-ztw7tA,341
82
82
  uncountable/core/async_batch.py,sha256=Gur0VOS0AH2ugwvk65hwoX-iqwQAAyJaejY_LyAZZPo,1210
83
83
  uncountable/core/client.py,sha256=qTM61IJV4DTE2LsTZyv4kePBZAv55vncWt2rtBf-SLQ,10632
84
- uncountable/core/environment.py,sha256=n46mWvG5uBOy6H_aetu_iuaYmO_d23uSbQBRgb6xStw,677
85
- uncountable/core/file_upload.py,sha256=qR7BBBWVxFNrb1_WICreo3dkZygE9lcE1fmZCQrDZU0,3469
84
+ uncountable/core/environment.py,sha256=K2TtE52JbW5UOBkBSc2Ee2l9rDIoRNoFDXDqRha1fJI,1036
85
+ uncountable/core/file_upload.py,sha256=L1tjW-zw0vu6y7ytqSWR_aVF8OIsqlQYHCa-24kbAf4,3408
86
86
  uncountable/core/types.py,sha256=s2CjqYJpsmbC7xMwxxT7kJ_V9bwokrjjWVVjpMcQpKI,333
87
87
  uncountable/integration/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
88
88
  uncountable/integration/cli.py,sha256=h3RE0l1SdjkveOKeY2amlmrJppK4HEQJXk8VG9UJRWg,1359
89
- uncountable/integration/construct_client.py,sha256=I2XTamht13vs-JYkV4PpNS_Pc4FJm-KVYqNNvxI4qNk,1916
89
+ uncountable/integration/construct_client.py,sha256=u_vKLG3uMjk-8mM8SbHMn1-Sh-jMeYEGHrOaU_X2b3c,1949
90
90
  uncountable/integration/cron.py,sha256=6eH-kIs3sdYPCyb62_L2M7U_uQTdMTdwY5hreEJb0hw,887
91
91
  uncountable/integration/entrypoint.py,sha256=BHOYPQgKvZE6HG8Rv15MkdYl8lRkvfDgv1OdLo0oQ9Q,433
92
92
  uncountable/integration/job.py,sha256=af197JUceIKzpIN5C2z8zeZOPhIQ16ipyC6qVt1WXv0,2386
93
- uncountable/integration/scan_profiles.py,sha256=ro4u5_1ClUeyW4vcWJ9epf2UQaJrjtc7S1R5bZpuHTM,1430
93
+ uncountable/integration/scan_profiles.py,sha256=760zbv7O7wXxHUHqUkFBpd1Afe8hqxMPU3ugwZGdhEo,2925
94
94
  uncountable/integration/scheduler.py,sha256=sVe7V5zlUbSzSMyC30rAlWR30w0jurhrYYCgK8-lVRo,4546
95
- uncountable/integration/server.py,sha256=zUDj2W45ih_UyvGou0Dsep9RVXb5m0o8i6mkm4BQCrg,5066
96
- uncountable/integration/telemetry.py,sha256=MwQLmgCoxpmA_UTp3e2ZB37wcDzKM0qzm5MrmaiJWhU,7142
95
+ uncountable/integration/server.py,sha256=Hwi3fpdhcSK2HynI6Zwi7A3mWTTCaK_ic53M5-4IEp4,4716
96
+ uncountable/integration/telemetry.py,sha256=bX68_a2PyG23n1QtIFxcH30JynUoovMz6HgA_jgUb1A,7132
97
97
  uncountable/integration/db/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
98
98
  uncountable/integration/db/connect.py,sha256=mE3bdV0huclH2iT_dXCQdRL4LkjIuf_myAR64RTWXEs,498
99
99
  uncountable/integration/db/session.py,sha256=96cGQXpe6IugBTdSsjdP0S5yhJ6toSmbVB6qhc3FJzE,693
100
100
  uncountable/integration/executors/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
101
101
  uncountable/integration/executors/executors.py,sha256=CbwatKkHrLhnqYr_nsBjr0KYeOn8KqijxrZPHbxChBY,1961
102
- uncountable/integration/executors/generic_upload_executor.py,sha256=NlW5WcYePPA7_fwp5uW_2afAiQLKK7rCkKF06wQ948E,10375
103
- uncountable/integration/executors/script_executor.py,sha256=OmSBOtU48G3mqza9c2lCm84pGGyaDk-ZBJCx3RsdJXc,846
102
+ uncountable/integration/executors/generic_upload_executor.py,sha256=0vs9NVk1UL2FBhiMCH6o8p4KtVXNFNvv861QCOD3UU4,10375
103
+ uncountable/integration/executors/script_executor.py,sha256=BBQ9f0l7uH2hgKf60jtm-pONzwk-EeOhM2qBAbv_URo,846
104
104
  uncountable/integration/queue_runner/__init__.py,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
105
- uncountable/integration/queue_runner/job_scheduler.py,sha256=n6bM6ZqVOPD0PoJuZV5Y5tuhmw2gI-_p6JbnVlK42uI,5016
105
+ uncountable/integration/queue_runner/job_scheduler.py,sha256=5Z74Wb17oohz7EFN40JBymH1UWW7-Dnk9HhOz3wZ08E,5005
106
106
  uncountable/integration/queue_runner/queue_runner.py,sha256=0BmYu5zHdothTevGsB-nXg6MBd1UD-WkP3h1WCKMdQg,710
107
107
  uncountable/integration/queue_runner/types.py,sha256=8qTq29BTSa5rmW6CBlBntP0pNIiDcwu1wHa78pjroS0,219
108
- uncountable/integration/queue_runner/worker.py,sha256=Bwp7_OD4AughY01QQtZxlmZ5yrDmDk1GuijH09xhUkk,4455
108
+ uncountable/integration/queue_runner/worker.py,sha256=pYLd6D3-ZSM3zcd7UKwyYUADVYEAUK9Hfi0PprwkNqo,4170
109
109
  uncountable/integration/queue_runner/command_server/__init__.py,sha256=gQPVILGpWzCr2i5GJyoqna7AOSFvtn4tav69gB78mTQ,571
110
110
  uncountable/integration/queue_runner/command_server/command_client.py,sha256=DJb0TUVFkiiLBEQzHSN94sTRnuEbutNEgdN39XmnOXI,2046
111
111
  uncountable/integration/queue_runner/command_server/command_server.py,sha256=yyXryhiEC2eGS0yFElLGsVzSKwOuYvj-zp22jQorkv0,2138
@@ -120,25 +120,27 @@ uncountable/integration/queue_runner/datastore/datastore_sqlite.py,sha256=UZQABT
120
120
  uncountable/integration/queue_runner/datastore/interface.py,sha256=j4D-zVvLq-48VTVwHVei82UVUJ_P3cxiseyiTl0MoNw,534
121
121
  uncountable/integration/queue_runner/datastore/model.py,sha256=8-RI5A2yPZVGBLWINVmMd6VOl_oHtqGtnaNXcapAChw,577
122
122
  uncountable/integration/secret_retrieval/__init__.py,sha256=3QXVj35w8rRMxVvmmsViFYDi3lcb3g70incfalOEm6o,87
123
- uncountable/integration/secret_retrieval/retrieve_secret.py,sha256=eoPWbkUtCn_63A4TFlK_nvEDvfm4u2fiOoglmAkBG3U,3004
124
- uncountable/integration/webhook_server/entrypoint.py,sha256=hgbEtdVo3QU3odlHSygxmrsxR9g7rgU0yKt-o9nVAHE,5686
125
- uncountable/types/__init__.py,sha256=KSsSEBnGhn88NPex5q9MZtY4kj8PRqVTbaKtko4hxUU,8561
123
+ uncountable/integration/secret_retrieval/retrieve_secret.py,sha256=9iz9N8Z-B68QwFCXsx8hTYbgDbk06ejkJ3RQ9mCLMyM,3000
124
+ uncountable/integration/webhook_server/entrypoint.py,sha256=aaulH6GS7uvBw1jPrZwPDS3mRE9NY-lKxuX7vtoJcGg,5407
125
+ uncountable/types/__init__.py,sha256=mjJX5fo0Oq8_CRx6eo3NbY6ycKaB3rTb8EXH4vXY5ok,8965
126
126
  uncountable/types/async_batch.py,sha256=_OhT25_dEVts_z_n1kqfJH3xlZg3btLqR6TNkfFLlXE,609
127
- uncountable/types/async_batch_processor.py,sha256=esKBP56RiRH-VjAFBr8wgfcgKsRkUfiLBmQmYGx4XXY,11462
128
- uncountable/types/async_batch_t.py,sha256=CZ-rltFUiKVowvL5BhMfWaFxgf-Z0KPsghvjsg-PweY,2493
127
+ uncountable/types/async_batch_processor.py,sha256=DJn9KdgUv_l7ojCVJ_d9wCS3GUNc21b5cOrpunty2KU,13129
128
+ uncountable/types/async_batch_t.py,sha256=niXgIM7FQXb_1RLX8CBXiGaYSa8nqd-jqX68p7gMgJo,2558
129
+ uncountable/types/auth_retrieval.py,sha256=FY8Vr_BWD4O8PsauPNt_7_08YZSHFaUlTT72L5XJ-4o,570
130
+ uncountable/types/auth_retrieval_t.py,sha256=D2ptCIsuCecJa_P8K2qrNk2-zz1WuBpOrsZ65BRP-Dw,2221
129
131
  uncountable/types/base.py,sha256=xVSjWvA_fUUnkCg83EjoYEFvAfmskinKFMeYFOxNc9E,359
130
132
  uncountable/types/base_t.py,sha256=XXjZXexx0xWFUxMMhW8i9nIL6n8dsZVsHwdgnhZ0zJ4,2714
131
133
  uncountable/types/calculations.py,sha256=FFO_D3BbKoGDZnqWvTKpW4KF359i2vrKjpdFCLYzJC0,284
132
134
  uncountable/types/calculations_t.py,sha256=157qD0VqijD5kNDF5BRsfGli3WaPGnNjoo2o2CPX-Ik,669
133
135
  uncountable/types/chemical_structure.py,sha256=E-LnikTFDoVQ1b2zKaVUIO_PAKm-7aZZYJi8I8SDSic,302
134
136
  uncountable/types/chemical_structure_t.py,sha256=zDJ6WkeT3YwWZRZT21znQn2ZYelv3L7yv7kJiGoNZCw,824
135
- uncountable/types/client_base.py,sha256=qTifyQNBOwlspjWccQXg4gOhuwyQDy5z77rlreDynBU,67603
137
+ uncountable/types/client_base.py,sha256=fpVHWPifRToIiaBPKcM_YT8WQFrK-SW58muGnCTX3d0,68780
136
138
  uncountable/types/client_config.py,sha256=4h5Liko9uKCo9_0gdbPhoK6Jr2Kv7tioLiQ8iKeq-_4,301
137
139
  uncountable/types/client_config_t.py,sha256=6dStfR0IEHiPW8f9_aF3DD_tHmXXw2rEVrgpebzq8Fg,747
138
140
  uncountable/types/curves.py,sha256=W6uMpG5SyW1MS82szNpxkFEn1MnxNpBFyFbQb2Ysfng,366
139
141
  uncountable/types/curves_t.py,sha256=lKhRM-2cZ_sFaW7pa_I_Ipz_pJhm3_yTFehRXI79pKk,1416
140
- uncountable/types/entity.py,sha256=3XhLteFDRDZvHejDuYh-KvB65hpwrBygljFfiUcOAM8,315
141
- uncountable/types/entity_t.py,sha256=8OkFVgvrItdA1ysyWB21mLL85JTPdcdzAmb6CNBUVI0,15003
142
+ uncountable/types/entity.py,sha256=ECvhswTj9xp4gUEKTZoZYyxHvx1oyvE5FNiGNfSyUgk,528
143
+ uncountable/types/entity_t.py,sha256=78elxgVHHQ9GM9uvQVtTMSLnRXgDiznk9GEbAIzlK-k,16246
142
144
  uncountable/types/experiment_groups.py,sha256=_0OXcPzSAbkE-rfKt5tPx178YJ4pcEKZvrCxUHgDnvw,309
143
145
  uncountable/types/experiment_groups_t.py,sha256=qEs8YW0eJOJ_sCOObT5v9QRx9wsjLYpJqJhCJXa-vNA,721
144
146
  uncountable/types/field_values.py,sha256=uuIWX-xmfvcinYPdfkWJeb56zzQY01mc9rmotMPMh24,503
@@ -155,8 +157,10 @@ uncountable/types/input_attributes.py,sha256=IrIKQnHqHdS1Utdfzr9GnOe17a8riaqYcO1
155
157
  uncountable/types/input_attributes_t.py,sha256=mD9JIagE8TQ0KVwGkl-hinKz_gcunV3y30w_dW5sfeU,884
156
158
  uncountable/types/inputs.py,sha256=jFZHyo0ZOGJ3bb4TOPXovhE3Fo1-kf7B7T3usk4Sqg8,467
157
159
  uncountable/types/inputs_t.py,sha256=CpuuKRduZGET_wvkGUpUFN6rbZCHsdOIp1veEM-hspI,2143
158
- uncountable/types/job_definition.py,sha256=HXfaYl5Nafm9C0teQLBtqzroe1HlfKJtfGVm2-40hvg,1937
159
- uncountable/types/job_definition_t.py,sha256=A62fgHEK5JHTekDQ-UXCLJIEbWx64MJMk2Hlo64p8rg,8895
160
+ uncountable/types/integration_server.py,sha256=61NuGs1pbgovU5Vuje7oN9HpLwOGCCw9Q_CcUvt_0qI,385
161
+ uncountable/types/integration_server_t.py,sha256=wa45RWChRsj2oAvWcOfZXA2xZxyEEkzltuJqZwKTna8,1048
162
+ uncountable/types/job_definition.py,sha256=DEma_s-0oBo2tPI5u9IU_UDw-9MWbn4mTZsd_RHiYGE,1667
163
+ uncountable/types/job_definition_t.py,sha256=N9080NAzwfYQKTusY2vs3z1UrM5s_QGtzWyoFxr2_iM,7931
160
164
  uncountable/types/outputs.py,sha256=sUZx_X-TKCZtLm1YCEH8OISX9DdPlv9ZuUfM3-askCc,281
161
165
  uncountable/types/outputs_t.py,sha256=AdJZvIzqikHV9CnlC24WEo0OUe-5vrD4cjMqc2txEs0,765
162
166
  uncountable/types/overrides.py,sha256=Mv-smwK1B3pvbt48fNOiqkeQn9wMgYlBFJKUBOJqceE,431
@@ -204,9 +208,10 @@ uncountable/types/api/batch/execute_batch_load_async.py,sha256=j5a5dk0_lTJ-YslrB
204
208
  uncountable/types/api/chemical/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
205
209
  uncountable/types/api/chemical/convert_chemical_formats.py,sha256=xLpma1W1O9MzgxM4CCl5GPnpj3dpqRHhKcXr3b_ToAo,1589
206
210
  uncountable/types/api/entity/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
207
- uncountable/types/api/entity/create_entities.py,sha256=hG81k_nKD4orTtb5jKIkCarkSbUa3fXAxES6IZVkhL0,2276
208
- uncountable/types/api/entity/create_entity.py,sha256=BV99ZfkxPfMEGD0YvuMizK25Nll0o0GFho8_Mzb0Clk,2388
211
+ uncountable/types/api/entity/create_entities.py,sha256=XJXLcKgpiYpNLVNtkDAAe6Q09rNJSW_h2wu3i7OmFxw,1630
212
+ uncountable/types/api/entity/create_entity.py,sha256=N69a-4dymv2tg_Dhj6OBdnWPodFrJtn05JvLRQwoHp8,1742
209
213
  uncountable/types/api/entity/get_entities_data.py,sha256=gTEZ7Z7T-DWP8BZPNDF4c__EHtf9kAb1sGtHmiGOgnM,1454
214
+ uncountable/types/api/entity/grant_entity_permissions.py,sha256=YAXyJ3I_nqDQYFYGEO3MmD20vYyhoFZzID9tpVpgryM,1442
210
215
  uncountable/types/api/entity/list_entities.py,sha256=ykbdq4DD31uiRz4i8LH-8LLeA2Lpp_5fWfb5fdyx248,2000
211
216
  uncountable/types/api/entity/lock_entity.py,sha256=mMZx2tWOtuYg0sIftdPsFWgZO5LCav2ubqTw97dCtDU,1197
212
217
  uncountable/types/api/entity/resolve_entity_ids.py,sha256=GnQjeoTdzL0PIubrLay-PpaRsYFFWVGrTxhzSmP4hhw,1387
@@ -257,6 +262,7 @@ uncountable/types/api/recipes/create_recipe.py,sha256=Gh6Z_7wBfYBMGUgUSixw57ucRj
257
262
  uncountable/types/api/recipes/create_recipes.py,sha256=kmTDi0nF5OK5wYIErg_4CY3YsF3pDbrj4LLFqgDNRoU,1940
258
263
  uncountable/types/api/recipes/disassociate_recipe_as_input.py,sha256=YcLCle-yQ8A7hPmFg8wPfW4dyJwpMQXNKzJxCEr8xlw,1127
259
264
  uncountable/types/api/recipes/edit_recipe_inputs.py,sha256=7TBjzA8-yXYIko_jx0AvKMs8SnIkiQukhQFWyf2fkxk,7815
265
+ uncountable/types/api/recipes/get_column_calculation_values.py,sha256=u_KBiGpXnVLwRruEG-FmopiR8UDkuX6i47B4OY-IYWU,1702
260
266
  uncountable/types/api/recipes/get_curve.py,sha256=SPD9kx4m95KPXAD0MawX52IFl8W7gVKj-WmA4Wx2YtU,1126
261
267
  uncountable/types/api/recipes/get_recipe_calculations.py,sha256=_sBE5M2xzwagh1beTW32D_HTxqu9OrZTPZBGMba6Myk,1730
262
268
  uncountable/types/api/recipes/get_recipe_links.py,sha256=IIA_LV-iPayZRAsVmDCpSA8jgFnzcgGpk0lAnygyi-s,1180
@@ -277,7 +283,7 @@ uncountable/types/api/triggers/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr
277
283
  uncountable/types/api/triggers/run_trigger.py,sha256=-oZgPyn43xEKSCs81DVNzwaYMCdRJxbM9GY6fsqKwf4,1090
278
284
  uncountable/types/api/uploader/__init__.py,sha256=gCgbynxG3jA8FQHzercKtrHKHkiIKr8APdZYUniAor8,55
279
285
  uncountable/types/api/uploader/invoke_uploader.py,sha256=6mwVG136oLp9JcbB2I-kZnrcm3aeZzYZB-SFjEImY2o,1314
280
- UncountablePythonSDK-0.0.75.dist-info/METADATA,sha256=__fXg5O7uTKPPzAFToY3pOV8EHnNl6uX7UWCNat0E8Y,2051
281
- UncountablePythonSDK-0.0.75.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
282
- UncountablePythonSDK-0.0.75.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
283
- UncountablePythonSDK-0.0.75.dist-info/RECORD,,
286
+ UncountablePythonSDK-0.0.77.dist-info/METADATA,sha256=0IkwPFb5e6eCDVdYt67m6MXM5wU5jxsFoRuwCSE9oGI,2051
287
+ UncountablePythonSDK-0.0.77.dist-info/WHEEL,sha256=P9jw-gEje8ByB7_hXoICnHtVCrEwMQh-630tKvQWehc,91
288
+ UncountablePythonSDK-0.0.77.dist-info/top_level.txt,sha256=1UVGjAU-6hJY9qw2iJ7nCBeEwZ793AEN5ZfKX9A1uj4,31
289
+ UncountablePythonSDK-0.0.77.dist-info/RECORD,,
docs/requirements.txt CHANGED
@@ -2,6 +2,6 @@ furo==2024.8.6
2
2
  myst-parser==4.0.0
3
3
  sphinx-autoapi==3.3.0
4
4
  sphinx-copybutton==0.5.2
5
- Sphinx==8.0.0
5
+ Sphinx==8.1.3
6
6
  sphinx_design==0.6.1
7
7
  sphinx-favicon==1.0.1
examples/async_batch.py CHANGED
@@ -1,3 +1,4 @@
1
+ import os
1
2
  from decimal import Decimal
2
3
 
3
4
  from uncountable.core import AsyncBatchProcessor, AuthDetailsApiKey, Client
@@ -11,10 +12,9 @@ from uncountable.types.recipe_identifiers import (
11
12
  )
12
13
 
13
14
  client = Client(
14
- base_url="https://app.uncountable.com",
15
+ base_url=os.environ["UNC_BASE_URL"],
15
16
  auth_details=AuthDetailsApiKey(
16
- api_id="X",
17
- api_secret_key="X",
17
+ api_id=os.environ["UNC_API_ID"], api_secret_key=os.environ["UNC_API_SECRET_KEY"]
18
18
  ),
19
19
  )
20
20
  batch_loader = AsyncBatchProcessor(client=client)
@@ -49,7 +49,7 @@ class ParserExtraFieldsError(ParserError):
49
49
  self.extra_fields = extra_fields
50
50
 
51
51
  def __str__(self) -> str:
52
- return f"extra fields were provided: {", ".join(self.extra_fields)}"
52
+ return f"extra fields were provided: {', '.join(self.extra_fields)}"
53
53
 
54
54
 
55
55
  def is_optional(field_type: typing.Any) -> bool:
@@ -268,15 +268,15 @@ def _build_parser_inner(
268
268
 
269
269
  def parse_int(value: typing.Any) -> T:
270
270
  if isinstance(value, str):
271
- assert (
272
- "_" not in value
273
- ), "numbers with underscores not considered integers"
271
+ assert "_" not in value, (
272
+ "numbers with underscores not considered integers"
273
+ )
274
274
 
275
275
  dec_value = Decimal(value)
276
276
  int_value = int(dec_value)
277
- assert (
278
- int_value == dec_value
279
- ), f"value ({value}) cannot be parsed to int without discarding precision"
277
+ assert int_value == dec_value, (
278
+ f"value ({value}) cannot be parsed to int without discarding precision"
279
+ )
280
280
  return int_value # type: ignore
281
281
 
282
282
  return parse_int
@@ -76,9 +76,9 @@ class S3Session(FileSystemSession):
76
76
  filepaths: list[FileSystemObject],
77
77
  ) -> list[FileObjectData]:
78
78
  downloaded_files: list[FileObjectData] = []
79
- assert (
80
- self.bucket is not None
81
- ), "call to download_files on uninitialized s3 session"
79
+ assert self.bucket is not None, (
80
+ "call to download_files on uninitialized s3 session"
81
+ )
82
82
 
83
83
  for file_object in filepaths:
84
84
  if (
@@ -103,6 +103,9 @@ def _get_merged_serial_class_data(type_class: type[Any]) -> _SerialClassData | N
103
103
  if hasattr(type_class, "__unc_serial_data")
104
104
  else None
105
105
  )
106
+ if base_class_data is None:
107
+ return None
108
+
106
109
  if type_class.__bases__ is not None:
107
110
  for base in type_class.__bases__:
108
111
  curr_base_class_data = _get_merged_serial_class_data(base)
pkgs/type_spec/builder.py CHANGED
@@ -359,9 +359,9 @@ class SpecTypeDefn(SpecType):
359
359
  property_name_case = NameCase(name_case_raw)
360
360
 
361
361
  if property_name_case != NameCase.preserve:
362
- assert util.is_valid_property_name(
363
- name
364
- ), f"{name} is not a valid property name"
362
+ assert util.is_valid_property_name(name), (
363
+ f"{name} is not a valid property name"
364
+ )
365
365
 
366
366
  data_type = data.get("type")
367
367
  builder.ensure(data_type is not None, "missing `type` entry")
@@ -535,13 +535,8 @@ class SpecTypeDefnObject(SpecTypeDefn):
535
535
  base_type: list[SpecType] = [self.base] if self.base is not None else []
536
536
  return base_type + prop_types
537
537
 
538
- def get_generic(self) -> Optional[str]:
539
- if len(self.parameters) > 0:
540
- assert (
541
- len(self.parameters) == 1
542
- ), "Only single generic parameters current supported"
543
- return self.parameters[0]
544
- return None
538
+ def get_generics(self) -> list[str]:
539
+ return self.parameters
545
540
 
546
541
 
547
542
  class SpecTypeDefnAlias(SpecTypeDefn):
@@ -595,21 +590,21 @@ class SpecTypeDefnUnion(SpecTypeDefn):
595
590
  self.discriminator_map = {}
596
591
  for sub_type in self.types:
597
592
  builder.push_where(sub_type.name)
598
- assert isinstance(
599
- sub_type, SpecTypeDefnObject
600
- ), "union-type-must-be-object"
593
+ assert isinstance(sub_type, SpecTypeDefnObject), (
594
+ "union-type-must-be-object"
595
+ )
601
596
  assert sub_type.properties is not None
602
597
  discriminator_type = sub_type.properties.get(self.discriminator)
603
- assert (
604
- discriminator_type is not None
605
- ), f"missing-discriminator-field: {sub_type}"
598
+ assert discriminator_type is not None, (
599
+ f"missing-discriminator-field: {sub_type}"
600
+ )
606
601
  prop_type = unwrap_literal_type(discriminator_type.spec_type)
607
602
  assert prop_type is not None
608
603
  assert prop_type.is_value_to_string()
609
604
  discriminant = str(prop_type.value)
610
- assert (
611
- discriminant not in self.discriminator_map
612
- ), f"duplicated-discriminant, {discriminant} in {sub_type}"
605
+ assert discriminant not in self.discriminator_map, (
606
+ f"duplicated-discriminant, {discriminant} in {sub_type}"
607
+ )
613
608
  self.discriminator_map[discriminant] = sub_type
614
609
 
615
610
  builder.pop_where()
@@ -929,9 +924,9 @@ class SpecEndpoint:
929
924
  self.is_external = self.path_root == "api/external"
930
925
  self.has_attachment = data.get("has_attachment", False)
931
926
 
932
- assert (
933
- not is_sdk or self.desc is not None
934
- ), f"Endpoint description required for SDK endpoints, missing: {path}"
927
+ assert not is_sdk or self.desc is not None, (
928
+ f"Endpoint description required for SDK endpoints, missing: {path}"
929
+ )
935
930
 
936
931
  @property
937
932
  def resolved_path(self: Self) -> str:
@@ -1113,9 +1108,9 @@ class SpecNamespace:
1113
1108
  continue
1114
1109
 
1115
1110
  if "value" in defn:
1116
- assert util.is_valid_property_name(
1117
- name
1118
- ), f"{name} is not a valid constant name"
1111
+ assert util.is_valid_property_name(name), (
1112
+ f"{name} is not a valid constant name"
1113
+ )
1119
1114
  spec_constant = SpecConstant(self, name)
1120
1115
  self.constants[name] = spec_constant
1121
1116
  continue
@@ -1134,7 +1129,11 @@ class SpecNamespace:
1134
1129
  spec_type = SpecTypeDefnStringEnum(self, name)
1135
1130
  else:
1136
1131
  parameters = (
1137
- [parameter.name for parameter in parsed_name.parameters[0]]
1132
+ [
1133
+ parameter.name
1134
+ for name_parameters in parsed_name.parameters
1135
+ for parameter in name_parameters
1136
+ ]
1138
1137
  if parsed_name.parameters is not None
1139
1138
  else None
1140
1139
  )
@@ -1456,4 +1455,4 @@ class SpecBuilder:
1456
1455
  )
1457
1456
 
1458
1457
  def resolve_proper_name(self, stype: SpecTypeDefn) -> str:
1459
- return f"{".".join(stype.namespace.path)}.{stype.name}"
1458
+ return f"{'.'.join(stype.namespace.path)}.{stype.name}"
pkgs/type_spec/config.py CHANGED
@@ -108,9 +108,9 @@ def parse_yaml_config(config_file: str) -> Config:
108
108
  raw_config: dict[str, ConfigValueType] = yaml.safe_load(input)
109
109
 
110
110
  raw_type_spec_types = raw_config["type_spec_types"]
111
- assert isinstance(
112
- raw_type_spec_types, list
113
- ), "type_spec_types, must be a list of folders"
111
+ assert isinstance(raw_type_spec_types, list), (
112
+ "type_spec_types, must be a list of folders"
113
+ )
114
114
  type_spec_types = [os.path.abspath(folder) for folder in raw_type_spec_types]
115
115
 
116
116
  api_endpoint = _parse_string_lookup(
@@ -100,14 +100,14 @@ def _emit_type_io_ts_impl(ctx: EmitTypescriptContext, stype: builder.SpecType) -
100
100
  else:
101
101
  assert len(missable_lines) > 0 and len(required_lines) > 0
102
102
  ctx.out.write("IO.intersection([\n")
103
- ctx.out.write(f"{INDENT}IO.partial({"{"}\n")
103
+ ctx.out.write(f"{INDENT}IO.partial({'{'}\n")
104
104
  for line in missable_lines:
105
105
  ctx.out.write(f"{INDENT}{line}")
106
- ctx.out.write(f"{INDENT}{"}"}),\n")
107
- ctx.out.write(f"{INDENT}IO.type({"{"}\n")
106
+ ctx.out.write(f"{INDENT}{'}'}),\n")
107
+ ctx.out.write(f"{INDENT}IO.type({'{'}\n")
108
108
  for line in required_lines:
109
109
  ctx.out.write(f"{INDENT}{line}")
110
- ctx.out.write(f"{INDENT}{"}"}),\n")
110
+ ctx.out.write(f"{INDENT}{'}'}),\n")
111
111
  ctx.out.write("])\n")
112
112
 
113
113
  ctx.out.write("\n")
@@ -125,11 +125,11 @@ def refer_to_io_ts(
125
125
  spec = refer_to_io_ts(ctx, stype.parameters[0])
126
126
  return f"IO.array({spec})"
127
127
  if stype.defn_type.name == builder.BaseTypeName.s_union:
128
- return f'IO.union([{", ".join([refer_to_io_ts(ctx, p) for p in stype.parameters])}])'
128
+ return f"IO.union([{', '.join([refer_to_io_ts(ctx, p) for p in stype.parameters])}])"
129
129
  if stype.defn_type.name == builder.BaseTypeName.s_optional:
130
130
  return f"IO.optional({refer_to_io_ts(ctx, stype.parameters[0])})"
131
131
  if stype.defn_type.name == builder.BaseTypeName.s_tuple:
132
- return f"IO.tuple([{", ".join([refer_to_io_ts(ctx, p) for p in stype.parameters])}])"
132
+ return f"IO.tuple([{', '.join([refer_to_io_ts(ctx, p) for p in stype.parameters])}])"
133
133
  return refer_to_io_ts(ctx, stype.defn_type)
134
134
 
135
135
  assert isinstance(stype, builder.SpecTypeDefn)
@@ -416,7 +416,7 @@ def _emit_namespace(
416
416
  {name: value.asdict() for name, value in types.items()},
417
417
  )
418
418
 
419
- path = f"{config.types_output}/common/{"/".join(namespace.path)}.yaml"
419
+ path = f"{config.types_output}/common/{'/'.join(namespace.path)}.yaml"
420
420
  oa_namespace = {"components": oa_components}
421
421
  _rewrite_with_notice(path, yaml.dumps(oa_namespace, sort_keys=False))
422
422
 
@@ -559,7 +559,7 @@ def _emit_endpoint(
559
559
  gctx.tags.add(EmitOpenAPITag(name=tag_name, description=""))
560
560
  gctx.tag_groups[tag_group].add(tag_name)
561
561
 
562
- ref_path = f"common/{"/".join(namespace.path)}.yaml#/components/endpoint"
562
+ ref_path = f"common/{'/'.join(namespace.path)}.yaml#/components/endpoint"
563
563
  ep = namespace.endpoint
564
564
  gctx.paths.append(
565
565
  EmitOpenAPIPath(
@@ -577,7 +577,7 @@ def _emit_endpoint(
577
577
  ctx.endpoint = EmitOpenAPIEndpoint(
578
578
  method=namespace.endpoint.method.lower(),
579
579
  tags=[tag_name],
580
- summary=f"{"/".join(namespace.path[path_cutoff:])}",
580
+ summary=f"{'/'.join(namespace.path[path_cutoff:])}",
581
581
  description=description,
582
582
  is_beta=namespace.endpoint.is_beta,
583
583
  stability_level=namespace.endpoint.stability_level,
@@ -694,5 +694,5 @@ def open_api_type(
694
694
  ctx.namespaces.add(stype.namespace)
695
695
  # external namespace resolution
696
696
  return OpenAPIRefType(
697
- source=f"{resolve_namespace_ref(source_path=ctx.namespace.path, ref_path=stype.namespace.path, ref="/components/schema")}/{stype.name}"
697
+ source=f"{resolve_namespace_ref(source_path=ctx.namespace.path, ref_path=stype.namespace.path, ref='/components/schema')}/{stype.name}"
698
698
  )
@@ -296,7 +296,7 @@ def _emit_types(*, builder: builder.SpecBuilder, config: PythonConfig) -> None:
296
296
  full.write(f"# === END section from {namespace.name}.part.py ===\n")
297
297
 
298
298
  basename = "/".join(namespace.path)
299
- filename = f"{config.types_output}/{basename}{"" if len(namespace.path) > 1 else "_t"}.py"
299
+ filename = f"{config.types_output}/{basename}{'' if len(namespace.path) > 1 else '_t'}.py"
300
300
  util.rewrite_file(filename, full.getvalue())
301
301
 
302
302
  # Deprecated SDK support
@@ -390,13 +390,13 @@ from .base_t import ObjectId as ObjectId
390
390
  def _validate_supports_handler_generation(
391
391
  stype: builder.SpecTypeDefn, name: str, supports_inheritance: bool = False
392
392
  ) -> builder.SpecTypeDefnObject:
393
- assert isinstance(
394
- stype, builder.SpecTypeDefnObject
395
- ), f"External api {name} must be an object"
393
+ assert isinstance(stype, builder.SpecTypeDefnObject), (
394
+ f"External api {name} must be an object"
395
+ )
396
396
  if not supports_inheritance:
397
- assert (
398
- stype.base is None or stype.base.is_base
399
- ), f"Inheritance not supported in external api {name}"
397
+ assert stype.base is None or stype.base.is_base, (
398
+ f"Inheritance not supported in external api {name}"
399
+ )
400
400
  return stype
401
401
 
402
402
 
@@ -756,7 +756,7 @@ def _emit_properties(
756
756
  def _named_type_path(ctx: Context, stype: builder.SpecTypeDefn) -> str:
757
757
  parts = [] if stype.is_base else stype.namespace.path.copy()
758
758
  parts.append(stype.name)
759
- return f"{ctx.builder.top_namespace}.{".".join(parts)}"
759
+ return f"{ctx.builder.top_namespace}.{'.'.join(parts)}"
760
760
 
761
761
 
762
762
  def _emit_type(ctx: Context, stype: builder.SpecType) -> None:
@@ -814,11 +814,11 @@ def _emit_type(ctx: Context, stype: builder.SpecType) -> None:
814
814
 
815
815
  class_out = io.StringIO()
816
816
  base_class = ""
817
- generic = stype.get_generic()
817
+ generics = stype.get_generics()
818
818
  if not stype.base.is_base:
819
819
  base_class = f"({refer_to(ctx, stype.base)})"
820
- elif generic is not None:
821
- base_class = f"(typing.Generic[{generic}])"
820
+ elif len(generics) > 0:
821
+ base_class = f"(typing.Generic[{', '.join(generics)}])"
822
822
  class_out.write(f"class {stype.name}{base_class}:\n")
823
823
 
824
824
  emitted_properties_metadata = _emit_type_properties(
@@ -829,7 +829,7 @@ def _emit_type(ctx: Context, stype: builder.SpecType) -> None:
829
829
  to_string_values = emitted_properties_metadata.to_string_values
830
830
  parse_require = emitted_properties_metadata.parse_require
831
831
 
832
- _emit_generic(ctx, stype.get_generic())
832
+ _emit_generics(ctx, generics)
833
833
 
834
834
  # Emit serial_class decorator
835
835
  ctx.out.write("@serial_class(\n")
@@ -858,14 +858,14 @@ def _emit_type(ctx: Context, stype: builder.SpecType) -> None:
858
858
  if stype.is_hashable:
859
859
  dc_args.extend(["frozen=True", "eq=True"])
860
860
  if len(dc_args) > 0:
861
- dataclass += f'({", ".join(dc_args)})'
861
+ dataclass += f"({', '.join(dc_args)})"
862
862
 
863
863
  ctx.out.write(f"{dataclass}\n")
864
864
  ctx.out.write(class_out.getvalue())
865
865
 
866
866
 
867
- def _emit_generic(ctx: Context, generic: Optional[str]) -> None:
868
- if generic is not None:
867
+ def _emit_generics(ctx: Context, generics: list[str]) -> None:
868
+ for generic in generics:
869
869
  ctx.out.write(f'{generic} = typing.TypeVar("{generic}")\n')
870
870
  ctx.out.write(f"{LINE_BREAK}{LINE_BREAK}")
871
871
 
@@ -966,9 +966,9 @@ from main.site.framework.types import StaticRouteType
966
966
  )
967
967
  sorted_endpoints = sorted(endpoints, key=_route_identifier)
968
968
 
969
- assert len(endpoints) == len(
970
- set(map(_route_identifier, endpoints))
971
- ), "Endpoints are not unique"
969
+ assert len(endpoints) == len(set(map(_route_identifier, endpoints))), (
970
+ "Endpoints are not unique"
971
+ )
972
972
 
973
973
  path_set = set()
974
974
  for endpoint in sorted_endpoints:
@@ -1037,7 +1037,7 @@ def _emit_namespace_imports(
1037
1037
  if ns.endpoint is not None:
1038
1038
  import_alias = "_".join(ns.path[2:]) + "_t"
1039
1039
  out.write(
1040
- f"import {config.types_package}.{".".join(ns.path)} as {import_alias}\n"
1040
+ f"import {config.types_package}.{'.'.join(ns.path)} as {import_alias}\n"
1041
1041
  )
1042
1042
  continue
1043
1043
  elif from_namespace is not None:
@@ -1195,7 +1195,7 @@ def _emit_api_argument_lookup(
1195
1195
  continue
1196
1196
 
1197
1197
  import_alias = "_".join(namespace.path[1:])
1198
- api_import = f"{config.types_package}.{".".join(namespace.path)}"
1198
+ api_import = f"{config.types_package}.{'.'.join(namespace.path)}"
1199
1199
  imports.append(f"import {api_import} as {import_alias}")
1200
1200
 
1201
1201
  route_group = (
@@ -48,7 +48,7 @@ def _emit_types(builder: builder.SpecBuilder, config: TypeScriptConfig) -> None:
48
48
  # Try to capture some common incompleteness errors
49
49
  if namespace.endpoint is None or namespace.endpoint.function is None:
50
50
  raise Exception(
51
- f"Namespace {"/".join(namespace.path)} is incomplete. It should have an endpoint with function, types, and/or constants"
51
+ f"Namespace {'/'.join(namespace.path)} is incomplete. It should have an endpoint with function, types, and/or constants"
52
52
  )
53
53
  continue
54
54
 
@@ -157,7 +157,7 @@ def _emit_endpoint(
157
157
  wrap_call = (
158
158
  f"{wrap_name}<Arguments>" if is_binary else f"{wrap_name}<Arguments, Response>"
159
159
  )
160
- type_path = f"unc_mat/types/{"/".join(namespace.path)}"
160
+ type_path = f"unc_mat/types/{'/'.join(namespace.path)}"
161
161
 
162
162
  if is_binary:
163
163
  tsx_response_part = f"""import {{ {wrap_name} }} from "unc_base/api"
@@ -196,12 +196,12 @@ export const apiCall = {wrap_call}(
196
196
  )
197
197
  {data_loader_body}"""
198
198
 
199
- output = f"{config.routes_output}/{"/".join(namespace.path)}.tsx"
199
+ output = f"{config.routes_output}/{'/'.join(namespace.path)}.tsx"
200
200
  util.rewrite_file(output, tsx_api)
201
201
 
202
202
  # Hacky index support, until enough is migrated to regen entirely
203
203
  # Emits the import into the UI API index file
204
- index_path = f"{config.routes_output}/{"/".join(namespace.path[0:-1])}/index.tsx"
204
+ index_path = f"{config.routes_output}/{'/'.join(namespace.path[0:-1])}/index.tsx"
205
205
  api_name = f"Api{ts_type_name(namespace.path[0 - 1])}"
206
206
  if os.path.exists(index_path):
207
207
  with open(index_path) as index: