dataerai-sdk 0.3.0b8__tar.gz → 0.3.0.dev1__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.
Files changed (413) hide show
  1. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/PKG-INFO +113 -23
  2. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/README.md +89 -20
  3. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/__init__.py +2 -0
  4. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_events.py +25 -1
  5. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_framing.py +6 -1
  6. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_types.py +14 -10
  7. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_version.py +1 -1
  8. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/fleet_hub.py +14 -1
  9. dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/__init__.py +1 -0
  10. dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/anthropic.py +56 -0
  11. dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/openai.py +77 -0
  12. dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/recorder.py +168 -0
  13. dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/transport.py +148 -0
  14. dataerai_sdk-0.3.0.dev1/dataerai/ci.py +123 -0
  15. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/client.py +268 -38
  16. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/envelope.py +22 -3
  17. dataerai_sdk-0.3.0.dev1/dataerai/instruments/__init__.py +8 -0
  18. dataerai_sdk-0.3.0.dev1/dataerai/instruments/__main__.py +220 -0
  19. dataerai_sdk-0.3.0.dev1/dataerai/instruments/formats.py +326 -0
  20. dataerai_sdk-0.3.0.dev1/dataerai/instruments/pipeline.py +353 -0
  21. dataerai_sdk-0.3.0.dev1/dataerai/instruments/spool.py +177 -0
  22. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/magics.py +3 -1
  23. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/__init__.py +4 -0
  24. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/tiff.py +15 -5
  25. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/__init__.py +1 -0
  26. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/_bounded.py +264 -0
  27. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/art.py +205 -0
  28. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/audio.py +155 -0
  29. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/cad.py +149 -0
  30. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/electronics.py +262 -0
  31. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/manufacturing.py +232 -0
  32. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/mesh.py +342 -0
  33. dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/volumes.py +224 -0
  34. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/leica_lif.py +48 -4
  35. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/nd2.py +13 -4
  36. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/registry.py +238 -0
  37. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/safe_xml.py +58 -17
  38. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/text_metadata.py +49 -15
  39. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/__init__.py +3 -0
  40. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/access.py +291 -18
  41. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/client.py +25 -18
  42. dataerai_sdk-0.3.0.dev1/dataerai/ml/attribution/evaluation.py +112 -0
  43. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/inference.py +14 -4
  44. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/training.py +52 -16
  45. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/cache.py +54 -3
  46. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/croissant.py +5 -6
  47. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/gpu.py +55 -13
  48. dataerai_sdk-0.3.0.dev1/dataerai/ml/huggingface.py +110 -0
  49. dataerai_sdk-0.3.0.dev1/dataerai/ml/integrations.py +40 -0
  50. dataerai_sdk-0.3.0.dev1/dataerai/ml/lightning.py +117 -0
  51. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/lineage.py +29 -19
  52. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/loader.py +78 -10
  53. dataerai_sdk-0.3.0.dev1/dataerai/ml/marketplace.py +51 -0
  54. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/inputs.py +8 -5
  55. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/runtime.py +18 -15
  56. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/staging.py +11 -8
  57. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/telemetry.py +12 -1
  58. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/train_reference.py +57 -3
  59. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/zarr_dataset.py +7 -1
  60. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/__init__.py +16 -0
  61. dataerai_sdk-0.3.0.dev1/dataerai/nn/_batch_integrity.py +244 -0
  62. dataerai_sdk-0.3.0.dev1/dataerai/nn/batch_audit.py +130 -0
  63. dataerai_sdk-0.3.0.dev1/dataerai/nn/batch_ledger.py +318 -0
  64. dataerai_sdk-0.3.0.dev1/dataerai/nn/weight_delta.py +204 -0
  65. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/notebook_trace.py +327 -24
  66. dataerai_sdk-0.3.0.dev1/dataerai/prepare/__init__.py +341 -0
  67. dataerai_sdk-0.3.0.dev1/dataerai/prepare/__main__.py +50 -0
  68. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/__init__.py +2 -0
  69. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/auth.py +2 -0
  70. dataerai_sdk-0.3.0.dev1/dataerai/rest/ci_auth.py +407 -0
  71. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/client.py +246 -27
  72. dataerai_sdk-0.3.0.dev1/dataerai/rest/pipelines.py +176 -0
  73. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/agent.py +562 -65
  74. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/api.py +140 -26
  75. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/capabilities.py +49 -8
  76. dataerai_sdk-0.3.0.dev1/dataerai/runner/cli.py +694 -0
  77. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/executor.py +353 -36
  78. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/__init__.py +25 -2
  79. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/_harness.py +11 -10
  80. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/bench.py +4 -1
  81. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/script.py +51 -16
  82. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/stage.py +4 -1
  83. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/train.py +4 -1
  84. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/heartbeat.py +14 -0
  85. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/image_ref.py +8 -3
  86. dataerai_sdk-0.3.0.dev1/dataerai/runner/state.py +383 -0
  87. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/venvs.py +131 -10
  88. dataerai_sdk-0.3.0.dev1/dataerai/runner/workload.py +491 -0
  89. dataerai_sdk-0.3.0.dev1/dataerai/runner/workload_handler.py +101 -0
  90. dataerai_sdk-0.3.0.dev1/dataerai/runner/workload_http.py +212 -0
  91. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/watermark.py +34 -3
  92. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/PKG-INFO +113 -23
  93. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/SOURCES.txt +80 -0
  94. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/entry_points.txt +1 -0
  95. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/requires.txt +29 -2
  96. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/pyproject.toml +25 -6
  97. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ai_ready_croissant_external.py +1 -1
  98. dataerai_sdk-0.3.0.dev1/tests/test_ai_ready_preparation.py +374 -0
  99. dataerai_sdk-0.3.0.dev1/tests/test_attribution_finalize_seal.py +124 -0
  100. dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_anthropic.py +87 -0
  101. dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_connect_site_origin.py +78 -0
  102. dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_openai.py +99 -0
  103. dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_recorder.py +21 -0
  104. dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_sdk_message_inputs.py +57 -0
  105. dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_transport.py +136 -0
  106. dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_transport_without_fchmod.py +41 -0
  107. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_client.py +8 -2
  108. dataerai_sdk-0.3.0.dev1/tests/test_collection_sync_failures.py +70 -0
  109. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_collections.py +26 -14
  110. dataerai_sdk-0.3.0.dev1/tests/test_croissant_original_content_url_fixture.py +37 -0
  111. dataerai_sdk-0.3.0.dev1/tests/test_dpb401_windows_runner.py +266 -0
  112. dataerai_sdk-0.3.0.dev1/tests/test_envelope_go_timestamp.py +73 -0
  113. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_infer_handler.py +2 -3
  114. dataerai_sdk-0.3.0.dev1/tests/test_instrument_formats.py +348 -0
  115. dataerai_sdk-0.3.0.dev1/tests/test_instrument_pipeline.py +246 -0
  116. dataerai_sdk-0.3.0.dev1/tests/test_instrument_spool.py +131 -0
  117. dataerai_sdk-0.3.0.dev1/tests/test_instrument_worker.py +195 -0
  118. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_lineage_client.py +14 -5
  119. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_lineage_duplicate_policy.py +104 -3
  120. dataerai_sdk-0.3.0.dev1/tests/test_marketplace_sdk.py +49 -0
  121. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_cred_lifecycle.py +97 -0
  122. dataerai_sdk-0.3.0.dev1/tests/test_ml_docker_token_lifetime.py +262 -0
  123. dataerai_sdk-0.3.0.dev1/tests/test_ml_dpb347_nonowner_bypass.py +100 -0
  124. dataerai_sdk-0.3.0.dev1/tests/test_ml_dpb347_review_regressions.py +112 -0
  125. dataerai_sdk-0.3.0.dev1/tests/test_ml_gpu_capabilities.py +201 -0
  126. dataerai_sdk-0.3.0.dev1/tests/test_ml_loader_platform_controls.py +136 -0
  127. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_packaging.py +1 -1
  128. dataerai_sdk-0.3.0.dev1/tests/test_ml_review_followups.py +319 -0
  129. dataerai_sdk-0.3.0.dev1/tests/test_ml_training_frameworks.py +461 -0
  130. dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_audit_workflow.py +137 -0
  131. dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_groups.py +109 -0
  132. dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_integrity.py +249 -0
  133. dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_ledger.py +241 -0
  134. dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_ledger_validation.py +321 -0
  135. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_nn_pytorch.py +1 -1
  136. dataerai_sdk-0.3.0.dev1/tests/test_nn_weight_delta.py +350 -0
  137. dataerai_sdk-0.3.0.dev1/tests/test_nn_weight_delta_no_torch.py +57 -0
  138. dataerai_sdk-0.3.0.dev1/tests/test_notebook_execution_projection.py +1706 -0
  139. dataerai_sdk-0.3.0.dev1/tests/test_perf_w4_instrument_client_reuse.py +532 -0
  140. dataerai_sdk-0.3.0.dev1/tests/test_perf_w4_rest_cursor_and_slim.py +233 -0
  141. dataerai_sdk-0.3.0.dev1/tests/test_perf_w4_tree_keyset.py +376 -0
  142. dataerai_sdk-0.3.0.dev1/tests/test_pipeline_client.py +250 -0
  143. dataerai_sdk-0.3.0.dev1/tests/test_readme_install_pins_admit_shipped_sdk.py +79 -0
  144. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_rest_lifetime_5290.py +93 -0
  145. dataerai_sdk-0.3.0.dev1/tests/test_review_workload_rate_limit.py +32 -0
  146. dataerai_sdk-0.3.0.dev1/tests/test_sdk_demos.py +34 -0
  147. dataerai_sdk-0.3.0.dev1/tests/test_serve_image_pixel_cap.py +42 -0
  148. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_loader.py +1 -1
  149. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_runtime.py +4 -0
  150. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_runtime_hardening.py +6 -0
  151. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_session.py +23 -1
  152. dataerai_sdk-0.3.0.dev1/tests/test_train_reference_checkpoint_gate.py +99 -0
  153. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_tutorial_notebook.py +7 -5
  154. dataerai_sdk-0.3.0.dev1/tests/test_unsaved_rotation_5407.py +107 -0
  155. dataerai_sdk-0.3.0.dev1/tests/test_watermark_extract_binary_mode.py +97 -0
  156. dataerai_sdk-0.3.0.dev1/tests/test_watermark_extract_portable_chmod.py +109 -0
  157. dataerai_sdk-0.3.0b8/dataerai/runner/cli.py +0 -414
  158. dataerai_sdk-0.3.0b8/dataerai/runner/state.py +0 -157
  159. dataerai_sdk-0.3.0b8/tests/test_ml_review_followups.py +0 -164
  160. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/LICENSE +0 -0
  161. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_agent.py +0 -0
  162. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_daemon.py +0 -0
  163. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_darwin_acl_probe.py +0 -0
  164. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_endpoint.py +0 -0
  165. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_errors.py +0 -0
  166. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello.py +0 -0
  167. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_connection.py +0 -0
  168. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_exchange.py +0 -0
  169. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_key.py +0 -0
  170. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_key_location.py +0 -0
  171. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_timeparse.py +0 -0
  172. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_transport.py +0 -0
  173. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_windows_identity.py +0 -0
  174. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_windows_key.py +0 -0
  175. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_windows_key_acl.py +0 -0
  176. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/__init__.py +0 -0
  177. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/capture.py +0 -0
  178. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/cli.py +0 -0
  179. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/feature_access.py +0 -0
  180. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/integration.py +0 -0
  181. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/journal.py +0 -0
  182. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/models.py +0 -0
  183. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/recorder.py +0 -0
  184. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/api.py +0 -0
  185. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bases.py +0 -0
  186. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/__init__.py +0 -0
  187. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/alignment.py +0 -0
  188. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/fcs.py +0 -0
  189. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/gff.py +0 -0
  190. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/sequence.py +0 -0
  191. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/vcf.py +0 -0
  192. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/checksum.py +0 -0
  193. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/__init__.py +0 -0
  194. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/molfile.py +0 -0
  195. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/qchem_output.py +0 -0
  196. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/structure.py +0 -0
  197. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/xyz.py +0 -0
  198. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/__init__.py +0 -0
  199. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/_netcdf_reader.py +0 -0
  200. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/fits.py +0 -0
  201. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/hdf5.py +0 -0
  202. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/image.py +0 -0
  203. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/matlab.py +0 -0
  204. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/netcdf.py +0 -0
  205. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/nexus.py +0 -0
  206. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/numpy_array.py +0 -0
  207. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/parquet.py +0 -0
  208. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/zarr_store.py +0 -0
  209. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converter.py +0 -0
  210. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/AFM/__init__.py +0 -0
  211. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/AFM/oxfordAFM/__init__.py +0 -0
  212. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/AFM/oxfordAFM/ibw.py +0 -0
  213. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/RHEED/__init__.py +0 -0
  214. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/RHEED/ksa/__init__.py +0 -0
  215. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/RHEED/ksa/imm.py +0 -0
  216. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/Xray/__init__.py +0 -0
  217. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/Xray/panalytical/__init__.py +0 -0
  218. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/Xray/panalytical/xrdml.py +0 -0
  219. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/__init__.py +0 -0
  220. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/core.py +0 -0
  221. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/crystallography/__init__.py +0 -0
  222. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/crystallography/cif.py +0 -0
  223. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/crystallography/vasp.py +0 -0
  224. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/data_type.py +0 -0
  225. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/data_type_definitions.py +0 -0
  226. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/__init__.py +0 -0
  227. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/budget.py +0 -0
  228. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/execution_log.py +0 -0
  229. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/json_document.py +0 -0
  230. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/notebook.py +0 -0
  231. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/feature_access.py +0 -0
  232. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/__init__.py +0 -0
  233. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bandexcitation/__init__.py +0 -0
  234. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bandexcitation/h5.py +0 -0
  235. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bruker/__init__.py +0 -0
  236. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bruker/nanoscope.py +0 -0
  237. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/oxfordAFM/__init__.py +0 -0
  238. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/oxfordAFM/ibw.py +0 -0
  239. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/__init__.py +0 -0
  240. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/dm/__init__.py +0 -0
  241. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/dm/dm3.py +0 -0
  242. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/dm/dm4.py +0 -0
  243. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/MS/__init__.py +0 -0
  244. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/MS/hiden/__init__.py +0 -0
  245. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/MS/hiden/massoft_csv.py +0 -0
  246. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/RHEED/__init__.py +0 -0
  247. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/RHEED/ksa/__init__.py +0 -0
  248. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/RHEED/ksa/imm.py +0 -0
  249. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/Xray/__init__.py +0 -0
  250. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/Xray/panalytical/__init__.py +0 -0
  251. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/Xray/panalytical/xrdml.py +0 -0
  252. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/__init__.py +0 -0
  253. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/__init__.py +0 -0
  254. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/andi_ms.py +0 -0
  255. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/imzml.py +0 -0
  256. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/mzml.py +0 -0
  257. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/mzxml.py +0 -0
  258. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/thermo_raw.py +0 -0
  259. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/__init__.py +0 -0
  260. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/dicom.py +0 -0
  261. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/edf.py +0 -0
  262. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/nifti.py +0 -0
  263. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/nwb.py +0 -0
  264. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/__init__.py +0 -0
  265. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/czi.py +0 -0
  266. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/olympus.py +0 -0
  267. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/__init__.py +0 -0
  268. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/bruker_opus.py +0 -0
  269. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/jcamp.py +0 -0
  270. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/renishaw_wdf.py +0 -0
  271. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/thermo_spc.py +0 -0
  272. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/units.py +0 -0
  273. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/utils.py +0 -0
  274. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/__init__.py +0 -0
  275. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/Xray/__init__.py +0 -0
  276. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/Xray/panalytical/__init__.py +0 -0
  277. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/Xray/panalytical/xrd.py +0 -0
  278. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/__init__.py +0 -0
  279. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/__init__.py +0 -0
  280. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/__init__.py +0 -0
  281. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/afm.py +0 -0
  282. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/dart_pfm.py +0 -0
  283. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/single_frequency_pfm.py +0 -0
  284. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/vector_pfm.py +0 -0
  285. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/visualize.py +0 -0
  286. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/layout.py +0 -0
  287. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/maps.py +0 -0
  288. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata.py +0 -0
  289. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/__init__.py +0 -0
  290. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/_common.py +0 -0
  291. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/afm.py +0 -0
  292. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/bio.py +0 -0
  293. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/chemistry.py +0 -0
  294. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/clinical.py +0 -0
  295. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/containers.py +0 -0
  296. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/generic.py +0 -0
  297. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/imaging.py +0 -0
  298. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/microscopy.py +0 -0
  299. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/spectroscopy.py +0 -0
  300. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/xrd.py +0 -0
  301. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/router.py +0 -0
  302. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/ai_ready_reader.py +0 -0
  303. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/__init__.py +0 -0
  304. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/calibration.py +0 -0
  305. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/codes.py +0 -0
  306. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/hooks.py +0 -0
  307. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/sae.py +0 -0
  308. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/bench.py +0 -0
  309. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/hls4ml.py +0 -0
  310. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/io.py +0 -0
  311. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/keras_dataset.py +0 -0
  312. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/report.py +0 -0
  313. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/__init__.py +0 -0
  314. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/__main__.py +0 -0
  315. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/loader.py +0 -0
  316. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/__init__.py +0 -0
  317. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/_docs.py +0 -0
  318. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/errors.py +0 -0
  319. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/live.py +0 -0
  320. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/reader.py +0 -0
  321. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/session.py +0 -0
  322. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/timeseries.py +0 -0
  323. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/video.py +0 -0
  324. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/writer.py +0 -0
  325. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/_provenance.py +0 -0
  326. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/pytorch.py +0 -0
  327. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/system.py +0 -0
  328. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/tensorflow.py +0 -0
  329. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/notebook.py +0 -0
  330. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/pycroscopy/__init__.py +0 -0
  331. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/pycroscopy/feature_control.py +0 -0
  332. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/qick/__init__.py +0 -0
  333. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/qick/feature_control.py +0 -0
  334. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/_config.py +0 -0
  335. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/__init__.py +0 -0
  336. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/__main__.py +0 -0
  337. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/_winjob.py +0 -0
  338. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/artifacts.py +0 -0
  339. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/config.py +0 -0
  340. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/cpu_profile.py +0 -0
  341. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/csv_extract.py +0 -0
  342. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/device_auth.py +0 -0
  343. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/downloads.py +0 -0
  344. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/extract_csv.py +0 -0
  345. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/infer.py +0 -0
  346. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/serve.py +0 -0
  347. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/sigv4.py +0 -0
  348. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/telemetry.py +0 -0
  349. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/dependency_links.txt +0 -0
  350. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/top_level.txt +0 -0
  351. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/setup.cfg +0 -0
  352. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_agent.py +0 -0
  353. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ai_ready_croissant_external_mlc.py +0 -0
  354. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_feature_control.py +0 -0
  355. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_inference.py +0 -0
  356. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_sae.py +0 -0
  357. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_training.py +0 -0
  358. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_collection_sync.py +0 -0
  359. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_credentials_save_windows.py +0 -0
  360. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_daemon_startup_security.py +0 -0
  361. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_envelope.py +0 -0
  362. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_events.py +0 -0
  363. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_framing.py +0 -0
  364. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_client_security.py +0 -0
  365. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_exchange_security.py +0 -0
  366. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_key_location_security.py +0 -0
  367. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_key_security.py +0 -0
  368. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_proof_security.py +0 -0
  369. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ipc_endpoint_security.py +0 -0
  370. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_keras_hls4ml.py +0 -0
  371. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_access_ttl.py +0 -0
  372. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_ai_ready_croissant.py +0 -0
  373. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_ai_ready_reader.py +0 -0
  374. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_bench.py +0 -0
  375. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_cache.py +0 -0
  376. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_content_pinning.py +0 -0
  377. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_distributed.py +0 -0
  378. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_gpu.py +0 -0
  379. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_gpu_path.py +0 -0
  380. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_io.py +0 -0
  381. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_loader.py +0 -0
  382. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_read_path.py +0 -0
  383. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_review_followups_torch.py +0 -0
  384. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_sampler_correctness.py +0 -0
  385. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_staging.py +0 -0
  386. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_telemetry.py +0 -0
  387. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_nn_tensorflow.py +0 -0
  388. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_notebook.py +0 -0
  389. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_notebook_trace.py +0 -0
  390. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_notebook_trace_feature_control.py +0 -0
  391. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_pat_credentials_compatibility.py +0 -0
  392. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_provenance_tokens_feature_control.py +0 -0
  393. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_rest_auth.py +0 -0
  394. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_rest_client.py +0 -0
  395. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_inputs.py +0 -0
  396. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_loader_device.py +0 -0
  397. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_packaging.py +0 -0
  398. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_core.py +0 -0
  399. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_live.py +0 -0
  400. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_timeseries.py +0 -0
  401. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_video.py +0 -0
  402. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_terms_gate.py +0 -0
  403. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_timeparse.py +0 -0
  404. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_transport.py +0 -0
  405. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_verifiable_credentials.py +0 -0
  406. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_watermark.py +0 -0
  407. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_acl_security.py +0 -0
  408. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_native_security.py +0 -0
  409. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_refusal_boundary.py +0 -0
  410. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_storage_security.py +0 -0
  411. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_pipe_cancellation_security.py +0 -0
  412. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_pipe_identity_security.py +0 -0
  413. {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_zarr_dataset.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: dataerai-sdk
3
- Version: 0.3.0b8
3
+ Version: 0.3.0.dev1
4
4
  Summary: Python SDK for the Dataerai transfer daemon
5
5
  Author: Dataerai
6
6
  License: DATAERAI PROPRIETARY SOFTWARE LICENSE AGREEMENT
@@ -367,6 +367,16 @@ Classifier: Operating System :: OS Independent
367
367
  Requires-Python: >=3.10
368
368
  Description-Content-Type: text/markdown
369
369
  License-File: LICENSE
370
+ Provides-Extra: chat-capture
371
+ Requires-Dist: httpx>=0.27; extra == "chat-capture"
372
+ Requires-Dist: cryptography>=42; extra == "chat-capture"
373
+ Provides-Extra: instruments
374
+ Requires-Dist: numpy>=1.26; extra == "instruments"
375
+ Requires-Dist: h5py>=3.7; extra == "instruments"
376
+ Requires-Dist: netCDF4>=1.6; extra == "instruments"
377
+ Requires-Dist: dataerai-sdk[rest]; extra == "instruments"
378
+ Provides-Extra: prepare
379
+ Requires-Dist: pyarrow>=25.0.1; extra == "prepare"
370
380
  Provides-Extra: dev
371
381
  Requires-Dist: pytest>=8; extra == "dev"
372
382
  Requires-Dist: pytest-mock>=3; extra == "dev"
@@ -375,6 +385,9 @@ Requires-Dist: pyyaml>=6; extra == "dev"
375
385
  Provides-Extra: rest
376
386
  Requires-Dist: httpx>=0.27; extra == "rest"
377
387
  Requires-Dist: keyring>=25; extra == "rest"
388
+ Provides-Extra: ci
389
+ Requires-Dist: httpx>=0.27; extra == "ci"
390
+ Requires-Dist: requests>=2.31; extra == "ci"
378
391
  Provides-Extra: envelope
379
392
  Requires-Dist: cryptography>=42; extra == "envelope"
380
393
  Requires-Dist: blake3>=0.3; extra == "envelope"
@@ -390,7 +403,7 @@ Requires-Dist: psutil>=5.9; extra == "nn-tensorflow"
390
403
  Requires-Dist: nvidia-ml-py>=12; extra == "nn-tensorflow"
391
404
  Provides-Extra: nn-pytorch
392
405
  Requires-Dist: ipython>=8; extra == "nn-pytorch"
393
- Requires-Dist: torch>=2.6; extra == "nn-pytorch"
406
+ Requires-Dist: torch>=2.10; extra == "nn-pytorch"
394
407
  Requires-Dist: numpy>=1.26; extra == "nn-pytorch"
395
408
  Requires-Dist: psutil>=5.9; extra == "nn-pytorch"
396
409
  Requires-Dist: nvidia-ml-py>=12; extra == "nn-pytorch"
@@ -405,9 +418,16 @@ Requires-Dist: requests>=2.31; extra == "ml-io"
405
418
  Requires-Dist: s3fs>=2024.0; extra == "ml-io"
406
419
  Provides-Extra: ml
407
420
  Requires-Dist: dataerai-sdk[ml-io]; extra == "ml"
408
- Requires-Dist: torch>=2.4; extra == "ml"
421
+ Requires-Dist: torch>=2.10; extra == "ml"
409
422
  Requires-Dist: torchdata>=0.9; extra == "ml"
410
423
  Requires-Dist: safetensors>=0.4; extra == "ml"
424
+ Provides-Extra: ml-lightning
425
+ Requires-Dist: dataerai-sdk[ml]; extra == "ml-lightning"
426
+ Requires-Dist: lightning<3,>=2.4; extra == "ml-lightning"
427
+ Provides-Extra: ml-transformers
428
+ Requires-Dist: dataerai-sdk[ml]; extra == "ml-transformers"
429
+ Requires-Dist: transformers<6,>=4.46; extra == "ml-transformers"
430
+ Requires-Dist: accelerate<2,>=1.0; extra == "ml-transformers"
411
431
  Provides-Extra: croissant
412
432
  Requires-Dist: mlcroissant>=1.0; extra == "croissant"
413
433
  Provides-Extra: ml-gpu-cu12
@@ -448,6 +468,7 @@ Requires-Dist: torch; extra == "ml-stream-train"
448
468
  Provides-Extra: runner
449
469
  Requires-Dist: requests>=2; extra == "runner"
450
470
  Requires-Dist: nvidia-ml-py>=12.535; extra == "runner"
471
+ Requires-Dist: psutil>=5.9; extra == "runner"
451
472
  Provides-Extra: metaextract
452
473
  Requires-Dist: numpy>=1.23; extra == "metaextract"
453
474
  Requires-Dist: h5py>=3.7; extra == "metaextract"
@@ -513,7 +534,7 @@ resumable transfers; the optional REST client exposes every public API path.
513
534
  ## Installation
514
535
 
515
536
  ```bash
516
- pip install --pre "dataerai-sdk>=0.2.0b1,<0.3"
537
+ pip install --pre "dataerai-sdk>=0.3.0b1,<0.4"
517
538
  # or, from source:
518
539
  pip install -e sdk/python/
519
540
  ```
@@ -521,13 +542,13 @@ pip install -e sdk/python/
521
542
  Optional ML adapters are installed separately so the base SDK stays small:
522
543
 
523
544
  ```bash
524
- pip install --pre "dataerai-sdk[rest]>=0.2.0b1,<0.3" # Full public REST API
525
- pip install --pre "dataerai-sdk[ml]>=0.2.0b1,<0.3" # PyTorch Zarr datasets
526
- pip install --pre "dataerai-sdk[ml-keras]>=0.2.0b1,<0.3" # Keras batches
527
- pip install --pre "dataerai-sdk[ml-hls4ml]>=0.2.0b1,<0.3" # HLS4ML conversion
528
- pip install --pre "dataerai-sdk[notebook]>=0.2.0b1,<0.3" # IPython %dataerai magic
529
- pip install --pre "dataerai-sdk[nn-tensorflow]>=0.2.0b1,<0.3" # TensorFlow provenance
530
- pip install --pre "dataerai-sdk[envelope]>=0.2.0b1,<0.3" # Encrypted-envelope reader
545
+ pip install --pre "dataerai-sdk[rest]>=0.3.0b1,<0.4" # Full public REST API
546
+ pip install --pre "dataerai-sdk[ml]>=0.3.0b1,<0.4" # PyTorch Zarr datasets
547
+ pip install --pre "dataerai-sdk[ml-keras]>=0.3.0b1,<0.4" # Keras batches
548
+ pip install --pre "dataerai-sdk[ml-hls4ml]>=0.3.0b1,<0.4" # HLS4ML conversion
549
+ pip install --pre "dataerai-sdk[notebook]>=0.3.0b1,<0.4" # IPython %dataerai magic
550
+ pip install --pre "dataerai-sdk[nn-tensorflow]>=0.3.0b1,<0.4" # TensorFlow provenance
551
+ pip install --pre "dataerai-sdk[envelope]>=0.3.0b1,<0.4" # Encrypted-envelope reader
531
552
  ```
532
553
 
533
554
  ## Full public REST API
@@ -557,6 +578,24 @@ the configured Dataerai server. For headless jobs, set `DATAERAI_SERVER` and
557
578
  `DATAERAI_TOKEN`, or provide the CLI-compatible JSON credential object through
558
579
  `DATAERAI_CREDENTIALS_JSON`.
559
580
 
581
+ ### Listing helpers
582
+
583
+ `search_assets(...)` iterates every page of a search. Pass `slim=True` when ids,
584
+ titles, aliases and a file count are all you read: the console then sends its
585
+ minimum browse row (no `metadata`, no content `files`, a 280-character
586
+ `description` preview with `description_truncated`); `find_asset(alias=...)`
587
+ does. `list_collections(owner_type, owner_id, ...)` and
588
+ `list_projects(q=..., scope=...)` return the whole list, as before; pass
589
+ `limit` (1–500 rows per request) or `cursor` to walk the console's keyset pages
590
+ instead, as an iterator like `search_assets` (rows carry description previews,
591
+ and projects come by name rather than newest first).
592
+
593
+ ```python
594
+ with RestClient() as api:
595
+ for collection in api.list_collections("project", project_id, limit=500):
596
+ print(collection["title"])
597
+ ```
598
+
560
599
  ### Verifiable credentials
561
600
 
562
601
  The REST client provides typed convenience methods without accepting authority
@@ -763,6 +802,23 @@ If a traced cell fails, its source, outputs, error, and traceback are published
763
802
  immediately; an explicit `%dataerai --finish` is not required for that failed
764
803
  run.
765
804
 
805
+ The log asset also carries a bounded `notebook_execution` summary in its own,
806
+ searchable metadata: run identity and timing, the destination, the notebook's
807
+ filename and checksum, the Python version and package count, cell/error/product
808
+ counts with `failed_cell_indexes`, and for each of the first 200 cells its
809
+ `index`, `execution_count`, `duration_seconds`, `ok`, and `error_type`. The
810
+ block stays at or below 64 KiB; `cells_truncated` is always present: `false` for a
811
+ complete cell list and `true` for a shortened one.
812
+ It never contains cell source, output, error messages, or tracebacks: those
813
+ stay in the log file, because metadata can be readable by people who cannot
814
+ open the file. Any `.ipynb` file uploaded through the traced session also
815
+ gains a `notebook` summary, even without `--notebook` (`nbformat`,
816
+ `cell_count`, `code_cell_count`, `kernel`, `language`, `has_outputs`, marked with
817
+ `schema: dataerai.notebook-summary.v1` and the `sha256` of the file it
818
+ describes). The SDK only writes or replaces a `notebook` key it wrote itself, so
819
+ a value you set on the notebook asset is kept. Both are ordinary metadata, so a
820
+ search such as `notebook_execution.summary.error_count > 0` finds failed runs.
821
+
766
822
  Tracing is deliberately opt-in because cell source and output can contain
767
823
  secrets or sensitive research data. Review the notebook before enabling it.
768
824
  The recorder does not read environment-variable values or scan/upload arbitrary
@@ -834,6 +890,12 @@ final = tracker.save_checkpoint(
834
890
 
835
891
  ## PyTorch neural-network provenance
836
892
 
893
+ For ordered minibatch membership, exact sample exposure counts, optional
894
+ cryptographic snapshot verification and bounded selected-weight updates, see
895
+ [training batch audit](https://docs.dataerai.com/sdks/training-batch-audit).
896
+ The local example is `examples/training_batch_audit.py`; capture is opt-in and
897
+ has finite retention, batch, cardinality and disk limits.
898
+
837
899
  Install the PyTorch adapter when a training run must preserve native model and
838
900
  optimizer state:
839
901
 
@@ -1105,12 +1167,13 @@ fail at the point of cause — uploads are rejected, and a rejected upload can
1105
1167
  leave a contentless asset that surfaces much later as "no downloadable
1106
1168
  content".
1107
1169
 
1108
- > **`is_full` is necessary, not sufficient.** `True` means an upload will be
1109
- > rejected. `False` does *not* guarantee one succeeds: the console also
1110
- > hard-blocks on billing suspension, enforces a temporary grace ceiling instead
1111
- > of `data_volume_limit` during a grace window, and walks up parent
1112
- > allocations — none of which the daemon reports, so none are visible here.
1113
- > Read `False` as "the reported quota has room".
1170
+ > **`is_full` reports quota, not upload admission.** `True` means the reported quota
1171
+ > is exhausted — but an open grace window can still admit uploads, since the
1172
+ > console then enforces a temporary grace ceiling instead of
1173
+ > `data_volume_limit`. `False` does *not* guarantee one succeeds: the console
1174
+ > also hard-blocks on billing suspension and walks up parent allocations —
1175
+ > none of which the daemon reports, so none are visible here. Read `False` as
1176
+ > "the reported quota has room".
1114
1177
 
1115
1178
  A limit of `0` means zero capacity, not unlimited — the console's gate is a
1116
1179
  plain `current + incoming > limit` with no special case for zero. A missing limit
@@ -1140,13 +1203,15 @@ for asset in client.find_collection_assets(collection_id):
1140
1203
  if the server claims another page without a cursor or repeats one.
1141
1204
 
1142
1205
  > **`list_projects()` and `list_collections()` show what you can upload into,
1143
- > not everything you can read.** Both are projections of `list_tree()`, and the
1144
- > daemon omits any project you lack `WRITE_METADATA` on — so a project you can
1145
- > read but not write to is absent, and so are its collections. There is no
1146
- > SDK call that lists read-only projects today.
1206
+ > not everything you can read.** Both answer exactly what flattening
1207
+ > `list_tree()` would, and the tree omits any project you lack `WRITE_METADATA`
1208
+ > on — so a project you can read but not write to is absent, and so are its
1209
+ > collections. There is no SDK call that lists read-only projects today. They
1210
+ > read bounded keyset pages (`project.list` / `collection.list`) rather than
1211
+ > the whole tree, and fall back to `list_tree()` on a daemon without them.
1147
1212
 
1148
1213
  `list_projects()` populates only `project_id`, `name` and `root_collection_id`;
1149
- `tree.list` carries nothing else, so the remaining `Project` fields are `None`.
1214
+ the tree carries nothing else, so the remaining `Project` fields are `None`.
1150
1215
  Collections shared with you directly are attached to the personal node, so one
1151
1216
  returned under `owner_type="user"` may carry another project's
1152
1217
  `owner_project_id`.
@@ -1556,6 +1621,9 @@ def on_error(evt):
1556
1621
  def on_sync(evt):
1557
1622
  if evt.skipped_unverified:
1558
1623
  print(f"{evt.skipped_unverified} files skipped — no checksum offered")
1624
+ for failure in evt.failures:
1625
+ entry = failure.entry_id or "sync state"
1626
+ print(f"{entry}: {failure.path}: {failure.reason}")
1559
1627
  ```
1560
1628
 
1561
1629
  The daemon **broadcasts to every connected client**, so handlers also see work
@@ -1616,7 +1684,7 @@ lot with `logging.getLogger("dataerai.events").setLevel(logging.CRITICAL)`.
1616
1684
  | `asset.upload_failed` | `UploadFailedEvent` | |
1617
1685
  | `asset.download_failed` | `DownloadFailedEvent` | |
1618
1686
  | `collection.sync_progress` | `CollectionSyncProgressEvent` | Keyed by `sync_id`, not `transfer_id` |
1619
- | `collection.sync_complete` | `CollectionSyncCompleteEvent` | `skipped_unverified > 0` means files were **not** written |
1687
+ | `collection.sync_complete` | `CollectionSyncCompleteEvent` | `failures` lists up to 100 failed paths; `failed` counts all. `skipped_unverified > 0` means files were **not** written |
1620
1688
 
1621
1689
  Names are the daemon's own wire names, so the string here is the string in the
1622
1690
  protocol reference and in the daemon's logs. Porting from the Node SDK, which
@@ -1629,3 +1697,25 @@ spells them `transfer:fileComplete`: drop the camelCase and use `.` for `:`.
1629
1697
  | `DaemonError(code, message)` | Daemon returned a coded error (see `code` attribute) |
1630
1698
  | `DaemonTimeoutError` | Request or transfer exceeded the configured timeout |
1631
1699
  | `ConnectionError` | Daemon disconnected unexpectedly |
1700
+
1701
+ ## TrainKit framework adapters
1702
+
1703
+ Install `dataerai-sdk[ml-lightning]` for `dataerai.ml.lightning.TrainKitCallback`,
1704
+ or `dataerai-sdk[ml-transformers]` for `dataerai.ml.huggingface.TrainKitTrainer`.
1705
+ `dataerai.ml.integrations.ModelInputCollator` converts image/label sample pairs
1706
+ into named model inputs. The generic loader now accepts PyTorch collation,
1707
+ last-batch, generator, worker-initialization and multiprocessing controls.
1708
+
1709
+ Use one distributed partition owner: TrainKit for torchrun/Lightning;
1710
+ Accelerate for Hugging Face/custom Accelerate loops. GDS requires zero worker
1711
+ processes and disabled memory pinning. See the [framework recipes](https://docs.dataerai.com/sdks/ml-toolkit#training-framework-integrations)
1712
+ for complete examples and checkpoint behavior.
1713
+
1714
+ Lightning caches training batch limits. `TrainKitCallback` rejects an epoch whose
1715
+ shard reshuffle changes the loader batch count before consuming any batch in that
1716
+ epoch. For distributed multi-epoch Lightning, use full-sized shards or a shard
1717
+ count divisible by the world size; variable batch-count layouts remain unsupported.
1718
+
1719
+ ## Prepare scientific tables for random reads
1720
+
1721
+ Install `pip install "dataerai-sdk[prepare]"` and use `dataerai-prepare input.csv output.parquet` to create Parquet row groups or Arrow IPC file batches with embedded source provenance. See the [local preparation guide](docs/preparation.md) for explicit schemas, exact decimal conversion, compression, and indexed reader examples.
@@ -14,7 +14,7 @@ resumable transfers; the optional REST client exposes every public API path.
14
14
  ## Installation
15
15
 
16
16
  ```bash
17
- pip install --pre "dataerai-sdk>=0.2.0b1,<0.3"
17
+ pip install --pre "dataerai-sdk>=0.3.0b1,<0.4"
18
18
  # or, from source:
19
19
  pip install -e sdk/python/
20
20
  ```
@@ -22,13 +22,13 @@ pip install -e sdk/python/
22
22
  Optional ML adapters are installed separately so the base SDK stays small:
23
23
 
24
24
  ```bash
25
- pip install --pre "dataerai-sdk[rest]>=0.2.0b1,<0.3" # Full public REST API
26
- pip install --pre "dataerai-sdk[ml]>=0.2.0b1,<0.3" # PyTorch Zarr datasets
27
- pip install --pre "dataerai-sdk[ml-keras]>=0.2.0b1,<0.3" # Keras batches
28
- pip install --pre "dataerai-sdk[ml-hls4ml]>=0.2.0b1,<0.3" # HLS4ML conversion
29
- pip install --pre "dataerai-sdk[notebook]>=0.2.0b1,<0.3" # IPython %dataerai magic
30
- pip install --pre "dataerai-sdk[nn-tensorflow]>=0.2.0b1,<0.3" # TensorFlow provenance
31
- pip install --pre "dataerai-sdk[envelope]>=0.2.0b1,<0.3" # Encrypted-envelope reader
25
+ pip install --pre "dataerai-sdk[rest]>=0.3.0b1,<0.4" # Full public REST API
26
+ pip install --pre "dataerai-sdk[ml]>=0.3.0b1,<0.4" # PyTorch Zarr datasets
27
+ pip install --pre "dataerai-sdk[ml-keras]>=0.3.0b1,<0.4" # Keras batches
28
+ pip install --pre "dataerai-sdk[ml-hls4ml]>=0.3.0b1,<0.4" # HLS4ML conversion
29
+ pip install --pre "dataerai-sdk[notebook]>=0.3.0b1,<0.4" # IPython %dataerai magic
30
+ pip install --pre "dataerai-sdk[nn-tensorflow]>=0.3.0b1,<0.4" # TensorFlow provenance
31
+ pip install --pre "dataerai-sdk[envelope]>=0.3.0b1,<0.4" # Encrypted-envelope reader
32
32
  ```
33
33
 
34
34
  ## Full public REST API
@@ -58,6 +58,24 @@ the configured Dataerai server. For headless jobs, set `DATAERAI_SERVER` and
58
58
  `DATAERAI_TOKEN`, or provide the CLI-compatible JSON credential object through
59
59
  `DATAERAI_CREDENTIALS_JSON`.
60
60
 
61
+ ### Listing helpers
62
+
63
+ `search_assets(...)` iterates every page of a search. Pass `slim=True` when ids,
64
+ titles, aliases and a file count are all you read: the console then sends its
65
+ minimum browse row (no `metadata`, no content `files`, a 280-character
66
+ `description` preview with `description_truncated`); `find_asset(alias=...)`
67
+ does. `list_collections(owner_type, owner_id, ...)` and
68
+ `list_projects(q=..., scope=...)` return the whole list, as before; pass
69
+ `limit` (1–500 rows per request) or `cursor` to walk the console's keyset pages
70
+ instead, as an iterator like `search_assets` (rows carry description previews,
71
+ and projects come by name rather than newest first).
72
+
73
+ ```python
74
+ with RestClient() as api:
75
+ for collection in api.list_collections("project", project_id, limit=500):
76
+ print(collection["title"])
77
+ ```
78
+
61
79
  ### Verifiable credentials
62
80
 
63
81
  The REST client provides typed convenience methods without accepting authority
@@ -264,6 +282,23 @@ If a traced cell fails, its source, outputs, error, and traceback are published
264
282
  immediately; an explicit `%dataerai --finish` is not required for that failed
265
283
  run.
266
284
 
285
+ The log asset also carries a bounded `notebook_execution` summary in its own,
286
+ searchable metadata: run identity and timing, the destination, the notebook's
287
+ filename and checksum, the Python version and package count, cell/error/product
288
+ counts with `failed_cell_indexes`, and for each of the first 200 cells its
289
+ `index`, `execution_count`, `duration_seconds`, `ok`, and `error_type`. The
290
+ block stays at or below 64 KiB; `cells_truncated` is always present: `false` for a
291
+ complete cell list and `true` for a shortened one.
292
+ It never contains cell source, output, error messages, or tracebacks: those
293
+ stay in the log file, because metadata can be readable by people who cannot
294
+ open the file. Any `.ipynb` file uploaded through the traced session also
295
+ gains a `notebook` summary, even without `--notebook` (`nbformat`,
296
+ `cell_count`, `code_cell_count`, `kernel`, `language`, `has_outputs`, marked with
297
+ `schema: dataerai.notebook-summary.v1` and the `sha256` of the file it
298
+ describes). The SDK only writes or replaces a `notebook` key it wrote itself, so
299
+ a value you set on the notebook asset is kept. Both are ordinary metadata, so a
300
+ search such as `notebook_execution.summary.error_count > 0` finds failed runs.
301
+
267
302
  Tracing is deliberately opt-in because cell source and output can contain
268
303
  secrets or sensitive research data. Review the notebook before enabling it.
269
304
  The recorder does not read environment-variable values or scan/upload arbitrary
@@ -335,6 +370,12 @@ final = tracker.save_checkpoint(
335
370
 
336
371
  ## PyTorch neural-network provenance
337
372
 
373
+ For ordered minibatch membership, exact sample exposure counts, optional
374
+ cryptographic snapshot verification and bounded selected-weight updates, see
375
+ [training batch audit](https://docs.dataerai.com/sdks/training-batch-audit).
376
+ The local example is `examples/training_batch_audit.py`; capture is opt-in and
377
+ has finite retention, batch, cardinality and disk limits.
378
+
338
379
  Install the PyTorch adapter when a training run must preserve native model and
339
380
  optimizer state:
340
381
 
@@ -606,12 +647,13 @@ fail at the point of cause — uploads are rejected, and a rejected upload can
606
647
  leave a contentless asset that surfaces much later as "no downloadable
607
648
  content".
608
649
 
609
- > **`is_full` is necessary, not sufficient.** `True` means an upload will be
610
- > rejected. `False` does *not* guarantee one succeeds: the console also
611
- > hard-blocks on billing suspension, enforces a temporary grace ceiling instead
612
- > of `data_volume_limit` during a grace window, and walks up parent
613
- > allocations — none of which the daemon reports, so none are visible here.
614
- > Read `False` as "the reported quota has room".
650
+ > **`is_full` reports quota, not upload admission.** `True` means the reported quota
651
+ > is exhausted — but an open grace window can still admit uploads, since the
652
+ > console then enforces a temporary grace ceiling instead of
653
+ > `data_volume_limit`. `False` does *not* guarantee one succeeds: the console
654
+ > also hard-blocks on billing suspension and walks up parent allocations —
655
+ > none of which the daemon reports, so none are visible here. Read `False` as
656
+ > "the reported quota has room".
615
657
 
616
658
  A limit of `0` means zero capacity, not unlimited — the console's gate is a
617
659
  plain `current + incoming > limit` with no special case for zero. A missing limit
@@ -641,13 +683,15 @@ for asset in client.find_collection_assets(collection_id):
641
683
  if the server claims another page without a cursor or repeats one.
642
684
 
643
685
  > **`list_projects()` and `list_collections()` show what you can upload into,
644
- > not everything you can read.** Both are projections of `list_tree()`, and the
645
- > daemon omits any project you lack `WRITE_METADATA` on — so a project you can
646
- > read but not write to is absent, and so are its collections. There is no
647
- > SDK call that lists read-only projects today.
686
+ > not everything you can read.** Both answer exactly what flattening
687
+ > `list_tree()` would, and the tree omits any project you lack `WRITE_METADATA`
688
+ > on — so a project you can read but not write to is absent, and so are its
689
+ > collections. There is no SDK call that lists read-only projects today. They
690
+ > read bounded keyset pages (`project.list` / `collection.list`) rather than
691
+ > the whole tree, and fall back to `list_tree()` on a daemon without them.
648
692
 
649
693
  `list_projects()` populates only `project_id`, `name` and `root_collection_id`;
650
- `tree.list` carries nothing else, so the remaining `Project` fields are `None`.
694
+ the tree carries nothing else, so the remaining `Project` fields are `None`.
651
695
  Collections shared with you directly are attached to the personal node, so one
652
696
  returned under `owner_type="user"` may carry another project's
653
697
  `owner_project_id`.
@@ -1057,6 +1101,9 @@ def on_error(evt):
1057
1101
  def on_sync(evt):
1058
1102
  if evt.skipped_unverified:
1059
1103
  print(f"{evt.skipped_unverified} files skipped — no checksum offered")
1104
+ for failure in evt.failures:
1105
+ entry = failure.entry_id or "sync state"
1106
+ print(f"{entry}: {failure.path}: {failure.reason}")
1060
1107
  ```
1061
1108
 
1062
1109
  The daemon **broadcasts to every connected client**, so handlers also see work
@@ -1117,7 +1164,7 @@ lot with `logging.getLogger("dataerai.events").setLevel(logging.CRITICAL)`.
1117
1164
  | `asset.upload_failed` | `UploadFailedEvent` | |
1118
1165
  | `asset.download_failed` | `DownloadFailedEvent` | |
1119
1166
  | `collection.sync_progress` | `CollectionSyncProgressEvent` | Keyed by `sync_id`, not `transfer_id` |
1120
- | `collection.sync_complete` | `CollectionSyncCompleteEvent` | `skipped_unverified > 0` means files were **not** written |
1167
+ | `collection.sync_complete` | `CollectionSyncCompleteEvent` | `failures` lists up to 100 failed paths; `failed` counts all. `skipped_unverified > 0` means files were **not** written |
1121
1168
 
1122
1169
  Names are the daemon's own wire names, so the string here is the string in the
1123
1170
  protocol reference and in the daemon's logs. Porting from the Node SDK, which
@@ -1130,3 +1177,25 @@ spells them `transfer:fileComplete`: drop the camelCase and use `.` for `:`.
1130
1177
  | `DaemonError(code, message)` | Daemon returned a coded error (see `code` attribute) |
1131
1178
  | `DaemonTimeoutError` | Request or transfer exceeded the configured timeout |
1132
1179
  | `ConnectionError` | Daemon disconnected unexpectedly |
1180
+
1181
+ ## TrainKit framework adapters
1182
+
1183
+ Install `dataerai-sdk[ml-lightning]` for `dataerai.ml.lightning.TrainKitCallback`,
1184
+ or `dataerai-sdk[ml-transformers]` for `dataerai.ml.huggingface.TrainKitTrainer`.
1185
+ `dataerai.ml.integrations.ModelInputCollator` converts image/label sample pairs
1186
+ into named model inputs. The generic loader now accepts PyTorch collation,
1187
+ last-batch, generator, worker-initialization and multiprocessing controls.
1188
+
1189
+ Use one distributed partition owner: TrainKit for torchrun/Lightning;
1190
+ Accelerate for Hugging Face/custom Accelerate loops. GDS requires zero worker
1191
+ processes and disabled memory pinning. See the [framework recipes](https://docs.dataerai.com/sdks/ml-toolkit#training-framework-integrations)
1192
+ for complete examples and checkpoint behavior.
1193
+
1194
+ Lightning caches training batch limits. `TrainKitCallback` rejects an epoch whose
1195
+ shard reshuffle changes the loader batch count before consuming any batch in that
1196
+ epoch. For distributed multi-epoch Lightning, use full-sized shards or a shard
1197
+ count divisible by the world size; variable batch-count layouts remain unsupported.
1198
+
1199
+ ## Prepare scientific tables for random reads
1200
+
1201
+ Install `pip install "dataerai-sdk[prepare]"` and use `dataerai-prepare input.csv output.parquet` to create Parquet row groups or Arrow IPC file batches with embedded source provenance. See the [local preparation guide](docs/preparation.md) for explicit schemas, exact decimal conversion, compression, and indexed reader examples.
@@ -17,6 +17,7 @@ from ._events import (
17
17
  WILDCARD,
18
18
  event_name,
19
19
  CollectionSyncCompleteEvent,
20
+ CollectionSyncFailure,
20
21
  CollectionSyncProgressEvent,
21
22
  DownloadCompleteEvent,
22
23
  DownloadFailedEvent,
@@ -120,6 +121,7 @@ __all__ = [
120
121
  "DownloadFailedEvent",
121
122
  "CollectionSyncProgressEvent",
122
123
  "CollectionSyncCompleteEvent",
124
+ "CollectionSyncFailure",
123
125
  "AssetMetadata",
124
126
  "NotebookSession",
125
127
  "NotebookExecutionTrace",
@@ -15,7 +15,7 @@ Adding a new event is one edit here — a dataclass plus its row in
15
15
  :data:`EVENT_PARSERS` — and the client picks it up with no further changes.
16
16
  """
17
17
 
18
- from dataclasses import dataclass
18
+ from dataclasses import dataclass, field
19
19
  from typing import Any, Callable
20
20
 
21
21
  from ._types import ProgressEvent
@@ -168,6 +168,18 @@ class CollectionSyncProgressEvent:
168
168
  path: str
169
169
 
170
170
 
171
+ @dataclass
172
+ class CollectionSyncFailure:
173
+ """One file a collection sync could not write, and why.
174
+
175
+ An empty ``entry_id`` is the sync's own state file, which has no entry.
176
+ """
177
+
178
+ entry_id: str
179
+ path: str
180
+ reason: str
181
+
182
+
171
183
  @dataclass
172
184
  class CollectionSyncCompleteEvent:
173
185
  """A collection sync finished.
@@ -176,6 +188,9 @@ class CollectionSyncCompleteEvent:
176
188
  The daemon does **not** write those, so a run with a non-zero count is not
177
189
  a clean success however healthy ``downloaded`` looks — this is the shape of
178
190
  the "sync only fetched some of my files" reports.
191
+
192
+ ``failures`` names the files counted in ``failed`` and why (the first 100;
193
+ ``failed`` counts all). Empty when the daemon omits the field.
179
194
  """
180
195
 
181
196
  sync_id: str
@@ -187,6 +202,7 @@ class CollectionSyncCompleteEvent:
187
202
  pruned: int
188
203
  bytes_downloaded: int
189
204
  elapsed_ms: int
205
+ failures: list[CollectionSyncFailure] = field(default_factory=list)
190
206
 
191
207
 
192
208
  # ─── Wire name → parser ───────────────────────────────────────────────────────
@@ -287,6 +303,14 @@ EVENT_PARSERS: dict[str, Callable[[dict], Any]] = {
287
303
  pruned=p.get("pruned", 0),
288
304
  bytes_downloaded=p.get("bytes_downloaded", 0),
289
305
  elapsed_ms=p.get("elapsed_ms", 0),
306
+ failures=[
307
+ CollectionSyncFailure(
308
+ entry_id=f.get("entry_id", ""),
309
+ path=f.get("path", ""),
310
+ reason=f.get("reason", ""),
311
+ )
312
+ for f in (p.get("failures") or [])
313
+ ],
290
314
  ),
291
315
  }
292
316
 
@@ -18,9 +18,14 @@ DIR_MESSAGE: int = 0x02
18
18
  MAX_FRAME_BYTES: int = 32 * 1024 * 1024 # 32 MiB
19
19
 
20
20
 
21
+ def encode_json(payload: object) -> bytes:
22
+ """Serialise *payload* as a command frame carries it: compact JSON, UTF-8."""
23
+ return json.dumps(payload, separators=(",", ":")).encode("utf-8")
24
+
25
+
21
26
  def encode_frame(payload: dict) -> bytes:
22
27
  """Encode *payload* as a command frame (direction = DIR_COMMAND)."""
23
- data = json.dumps(payload, separators=(",", ":")).encode("utf-8")
28
+ data = encode_json(payload)
24
29
  if len(data) > MAX_FRAME_BYTES:
25
30
  raise ValueError(
26
31
  f"payload too large: {len(data):,} bytes (max {MAX_FRAME_BYTES:,})"
@@ -257,13 +257,15 @@ class Allocation:
257
257
  this covers both — a hand-written check almost always tests only bytes,
258
258
  and the record cap is the one that tends to bite first.
259
259
 
260
- **This is necessary, not sufficient.** ``is_full`` is ``True`` means an
261
- upload will be rejected. ``False`` does *not* guarantee one will
262
- succeed: the console also hard-blocks on billing suspension, enforces a
263
- temporary ``grace_bytes`` ceiling instead of ``data_volume_limit``
264
- during a grace window, and walks up parent allocations — and the daemon
265
- sends none of those, so they are invisible here. Treat a ``False`` as
266
- "the reported quota has room", not as a guarantee.
260
+ **This reports quota, not upload admission.** ``True`` means the
261
+ reported quota is exhausted — but an open grace window can still
262
+ admit uploads, since the console then enforces a temporary
263
+ ``grace_bytes`` ceiling instead of ``data_volume_limit``.
264
+ ``False`` does *not* guarantee one will succeed: the console also
265
+ hard-blocks on billing suspension and walks up parent allocations —
266
+ and the daemon sends none of those, so they are invisible here.
267
+ Treat a ``False`` as "the reported quota has room", not as a
268
+ guarantee.
267
269
  """
268
270
  return self.bytes_free == 0 or self.records_free == 0
269
271
 
@@ -296,9 +298,11 @@ class TransferSummary:
296
298
 
297
299
  Returned by :meth:`DataeraiClient.list_transfers`. ``status`` is the
298
300
  daemon's own lifecycle state — ``queued``, ``active``, ``paused``,
299
- ``completed`` or ``failed``; ``queued`` is real rather than notional,
300
- because the daemon runs a bounded number of transfers at once and queues
301
- the rest.
301
+ ``complete``, ``failed`` or ``cancelled``; ``queued`` is real rather than
302
+ notional, because the daemon runs a bounded number of transfers at once
303
+ and queues the rest. ``complete``, ``failed`` and ``cancelled`` are
304
+ terminal; a ``cancelled`` transfer (see
305
+ :meth:`DataeraiClient.cancel_transfer`) is never resumed.
302
306
  """
303
307
 
304
308
  transfer_id: str
@@ -9,4 +9,4 @@ See ``packaging/version.py`` (the ``compute_version`` brain) and
9
9
  ``doc/runbooks/20260616_SDK_CLI_PyPI_Release_Runbook.md``.
10
10
  """
11
11
 
12
- __version__ = "0.3.0b8"
12
+ __version__ = "0.3.0.dev1"
@@ -55,6 +55,17 @@ class HubTransport(Protocol):
55
55
  ) -> HubResponse: ...
56
56
 
57
57
 
58
+ class _RejectRedirects(urllib.request.HTTPRedirectHandler):
59
+ """Keep bearer credentials and client-certificate use on the configured hub."""
60
+
61
+ def redirect_request(self, request, response, code, message, headers, new_url):
62
+ # urllib otherwise forwards Authorization even across origins and from
63
+ # HTTPS to HTTP. Refuse same-origin redirects too: an API endpoint must
64
+ # not silently change the method or replay a credential-bearing request.
65
+ response.close()
66
+ raise FleetHubError("Fleet Hub redirects are not allowed", status=code)
67
+
68
+
58
69
  class UrlLibTransport:
59
70
  """Small mTLS transport kept behind a protocol for deterministic tests."""
60
71
 
@@ -77,7 +88,9 @@ class UrlLibTransport:
77
88
  self.timeout_s = timeout_s
78
89
  context = ssl.create_default_context(cafile=ca_cert)
79
90
  context.load_cert_chain(certfile=client_cert, keyfile=client_key)
80
- self._opener = urllib.request.build_opener(urllib.request.HTTPSHandler(context=context))
91
+ self._opener = urllib.request.build_opener(
92
+ urllib.request.HTTPSHandler(context=context), _RejectRedirects()
93
+ )
81
94
 
82
95
  def request(
83
96
  self,
@@ -0,0 +1 @@
1
+ """Opt-in conversation capture; provider SDKs are never monkey patched."""
@@ -0,0 +1,56 @@
1
+ """Observe Claude Messages create, preserving indexed block order and SDK values."""
2
+ import asyncio
3
+ import json
4
+ from .recorder import blocks, plain, safe, ObservedStream, AsyncObservedStream
5
+
6
+
7
+ def outcome(reason):
8
+ return {'end_turn':'ok','stop_sequence':'ok','tool_use':'ok','max_tokens':'truncated',
9
+ 'model_context_window_exceeded':'truncated','refusal':'refused'}.get(reason,'unknown')
10
+
11
+
12
+ class ClaudeState:
13
+ def __init__(self,run):self.run=run;self.parts={};self.arguments={};self.reason=None
14
+ def complete(self,response):
15
+ value=plain(response);self.run.output(0,blocks(value.get('content')),outcome(value.get('stop_reason')))
16
+ def consume(self,event):
17
+ value=plain(event);kind=value.get('type')
18
+ if kind=='message_start':return
19
+ if kind=='error':self.run.finish('error');return
20
+ if kind=='message_delta':self.reason=value.get('delta',{}).get('stop_reason',self.reason);return
21
+ if kind=='message_stop':self.run.output(0,self.content(),outcome(self.reason));return
22
+ index=value.get('index')
23
+ if kind=='content_block_start':
24
+ content=blocks([value['content_block']])
25
+ if content:self.parts[index]=content[0]
26
+ elif kind=='content_block_delta':
27
+ delta=value['delta'];block=self.parts.get(index)
28
+ if not block:return # hidden thinking/signature blocks have no entry
29
+ if delta['type']=='text_delta' and block['type']=='text':block['text']+=delta['text']
30
+ elif delta['type']=='input_json_delta' and block['type']=='tool_call':
31
+ self.arguments[index]=self.arguments.get(index,'')+delta['partial_json'];block['input']=self.arguments[index]
32
+ else:return
33
+ elif kind=='content_block_stop':
34
+ if index in self.arguments:
35
+ try:self.parts[index]['input']=json.loads(self.arguments[index])
36
+ except ValueError:self.parts[index]['input']={'raw_arguments':self.arguments[index]}
37
+ else:return # ping and future metadata events do not become content
38
+ self.run.output(0,self.content())
39
+ def content(self):return [self.parts[i] for i in sorted(self.parts)]
40
+
41
+
42
+ class ClaudeObserver:
43
+ def __init__(self,recorder):self.recorder=recorder
44
+ def messages(self,call,**kwargs):
45
+ run=self.recorder.start('anthropic',kwargs,'chat');state=ClaudeState(run)
46
+ try:result=call(**kwargs)
47
+ except BaseException:run.finish('error');raise
48
+ if kwargs.get('stream'):return ObservedStream(result,run,state.consume)
49
+ safe(run,state.complete,result);return result
50
+ async def amessages(self,call,**kwargs):
51
+ run=await asyncio.to_thread(self.recorder.start,'anthropic',kwargs,'chat');state=ClaudeState(run)
52
+ try:result=await call(**kwargs)
53
+ except asyncio.CancelledError:await asyncio.to_thread(run.finish,'cancelled');raise
54
+ except BaseException:await asyncio.to_thread(run.finish,'error');raise
55
+ if kwargs.get('stream'):return AsyncObservedStream(result,run,state.consume)
56
+ await asyncio.to_thread(safe,run,state.complete,result);return result