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.
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/PKG-INFO +113 -23
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/README.md +89 -20
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/__init__.py +2 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_events.py +25 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_framing.py +6 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_types.py +14 -10
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_version.py +1 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/fleet_hub.py +14 -1
- dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/__init__.py +1 -0
- dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/anthropic.py +56 -0
- dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/openai.py +77 -0
- dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/recorder.py +168 -0
- dataerai_sdk-0.3.0.dev1/dataerai/chat_capture/transport.py +148 -0
- dataerai_sdk-0.3.0.dev1/dataerai/ci.py +123 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/client.py +268 -38
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/envelope.py +22 -3
- dataerai_sdk-0.3.0.dev1/dataerai/instruments/__init__.py +8 -0
- dataerai_sdk-0.3.0.dev1/dataerai/instruments/__main__.py +220 -0
- dataerai_sdk-0.3.0.dev1/dataerai/instruments/formats.py +326 -0
- dataerai_sdk-0.3.0.dev1/dataerai/instruments/pipeline.py +353 -0
- dataerai_sdk-0.3.0.dev1/dataerai/instruments/spool.py +177 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/magics.py +3 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/__init__.py +4 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/tiff.py +15 -5
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/__init__.py +1 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/_bounded.py +264 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/art.py +205 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/audio.py +155 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/cad.py +149 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/electronics.py +262 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/manufacturing.py +232 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/mesh.py +342 -0
- dataerai_sdk-0.3.0.dev1/dataerai/metaextract/domains/volumes.py +224 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/leica_lif.py +48 -4
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/nd2.py +13 -4
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/registry.py +238 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/safe_xml.py +58 -17
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/text_metadata.py +49 -15
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/__init__.py +3 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/access.py +291 -18
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/client.py +25 -18
- dataerai_sdk-0.3.0.dev1/dataerai/ml/attribution/evaluation.py +112 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/inference.py +14 -4
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/training.py +52 -16
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/cache.py +54 -3
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/croissant.py +5 -6
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/gpu.py +55 -13
- dataerai_sdk-0.3.0.dev1/dataerai/ml/huggingface.py +110 -0
- dataerai_sdk-0.3.0.dev1/dataerai/ml/integrations.py +40 -0
- dataerai_sdk-0.3.0.dev1/dataerai/ml/lightning.py +117 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/lineage.py +29 -19
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/loader.py +78 -10
- dataerai_sdk-0.3.0.dev1/dataerai/ml/marketplace.py +51 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/inputs.py +8 -5
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/runtime.py +18 -15
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/staging.py +11 -8
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/telemetry.py +12 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/train_reference.py +57 -3
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/zarr_dataset.py +7 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/__init__.py +16 -0
- dataerai_sdk-0.3.0.dev1/dataerai/nn/_batch_integrity.py +244 -0
- dataerai_sdk-0.3.0.dev1/dataerai/nn/batch_audit.py +130 -0
- dataerai_sdk-0.3.0.dev1/dataerai/nn/batch_ledger.py +318 -0
- dataerai_sdk-0.3.0.dev1/dataerai/nn/weight_delta.py +204 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/notebook_trace.py +327 -24
- dataerai_sdk-0.3.0.dev1/dataerai/prepare/__init__.py +341 -0
- dataerai_sdk-0.3.0.dev1/dataerai/prepare/__main__.py +50 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/__init__.py +2 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/auth.py +2 -0
- dataerai_sdk-0.3.0.dev1/dataerai/rest/ci_auth.py +407 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/client.py +246 -27
- dataerai_sdk-0.3.0.dev1/dataerai/rest/pipelines.py +176 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/agent.py +562 -65
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/api.py +140 -26
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/capabilities.py +49 -8
- dataerai_sdk-0.3.0.dev1/dataerai/runner/cli.py +694 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/executor.py +353 -36
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/__init__.py +25 -2
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/_harness.py +11 -10
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/bench.py +4 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/script.py +51 -16
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/stage.py +4 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/train.py +4 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/heartbeat.py +14 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/image_ref.py +8 -3
- dataerai_sdk-0.3.0.dev1/dataerai/runner/state.py +383 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/venvs.py +131 -10
- dataerai_sdk-0.3.0.dev1/dataerai/runner/workload.py +491 -0
- dataerai_sdk-0.3.0.dev1/dataerai/runner/workload_handler.py +101 -0
- dataerai_sdk-0.3.0.dev1/dataerai/runner/workload_http.py +212 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/watermark.py +34 -3
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/PKG-INFO +113 -23
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/SOURCES.txt +80 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/entry_points.txt +1 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/requires.txt +29 -2
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/pyproject.toml +25 -6
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ai_ready_croissant_external.py +1 -1
- dataerai_sdk-0.3.0.dev1/tests/test_ai_ready_preparation.py +374 -0
- dataerai_sdk-0.3.0.dev1/tests/test_attribution_finalize_seal.py +124 -0
- dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_anthropic.py +87 -0
- dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_connect_site_origin.py +78 -0
- dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_openai.py +99 -0
- dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_recorder.py +21 -0
- dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_sdk_message_inputs.py +57 -0
- dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_transport.py +136 -0
- dataerai_sdk-0.3.0.dev1/tests/test_chat_capture_transport_without_fchmod.py +41 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_client.py +8 -2
- dataerai_sdk-0.3.0.dev1/tests/test_collection_sync_failures.py +70 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_collections.py +26 -14
- dataerai_sdk-0.3.0.dev1/tests/test_croissant_original_content_url_fixture.py +37 -0
- dataerai_sdk-0.3.0.dev1/tests/test_dpb401_windows_runner.py +266 -0
- dataerai_sdk-0.3.0.dev1/tests/test_envelope_go_timestamp.py +73 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_infer_handler.py +2 -3
- dataerai_sdk-0.3.0.dev1/tests/test_instrument_formats.py +348 -0
- dataerai_sdk-0.3.0.dev1/tests/test_instrument_pipeline.py +246 -0
- dataerai_sdk-0.3.0.dev1/tests/test_instrument_spool.py +131 -0
- dataerai_sdk-0.3.0.dev1/tests/test_instrument_worker.py +195 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_lineage_client.py +14 -5
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_lineage_duplicate_policy.py +104 -3
- dataerai_sdk-0.3.0.dev1/tests/test_marketplace_sdk.py +49 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_cred_lifecycle.py +97 -0
- dataerai_sdk-0.3.0.dev1/tests/test_ml_docker_token_lifetime.py +262 -0
- dataerai_sdk-0.3.0.dev1/tests/test_ml_dpb347_nonowner_bypass.py +100 -0
- dataerai_sdk-0.3.0.dev1/tests/test_ml_dpb347_review_regressions.py +112 -0
- dataerai_sdk-0.3.0.dev1/tests/test_ml_gpu_capabilities.py +201 -0
- dataerai_sdk-0.3.0.dev1/tests/test_ml_loader_platform_controls.py +136 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_packaging.py +1 -1
- dataerai_sdk-0.3.0.dev1/tests/test_ml_review_followups.py +319 -0
- dataerai_sdk-0.3.0.dev1/tests/test_ml_training_frameworks.py +461 -0
- dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_audit_workflow.py +137 -0
- dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_groups.py +109 -0
- dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_integrity.py +249 -0
- dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_ledger.py +241 -0
- dataerai_sdk-0.3.0.dev1/tests/test_nn_batch_ledger_validation.py +321 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_nn_pytorch.py +1 -1
- dataerai_sdk-0.3.0.dev1/tests/test_nn_weight_delta.py +350 -0
- dataerai_sdk-0.3.0.dev1/tests/test_nn_weight_delta_no_torch.py +57 -0
- dataerai_sdk-0.3.0.dev1/tests/test_notebook_execution_projection.py +1706 -0
- dataerai_sdk-0.3.0.dev1/tests/test_perf_w4_instrument_client_reuse.py +532 -0
- dataerai_sdk-0.3.0.dev1/tests/test_perf_w4_rest_cursor_and_slim.py +233 -0
- dataerai_sdk-0.3.0.dev1/tests/test_perf_w4_tree_keyset.py +376 -0
- dataerai_sdk-0.3.0.dev1/tests/test_pipeline_client.py +250 -0
- dataerai_sdk-0.3.0.dev1/tests/test_readme_install_pins_admit_shipped_sdk.py +79 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_rest_lifetime_5290.py +93 -0
- dataerai_sdk-0.3.0.dev1/tests/test_review_workload_rate_limit.py +32 -0
- dataerai_sdk-0.3.0.dev1/tests/test_sdk_demos.py +34 -0
- dataerai_sdk-0.3.0.dev1/tests/test_serve_image_pixel_cap.py +42 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_loader.py +1 -1
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_runtime.py +4 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_runtime_hardening.py +6 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_session.py +23 -1
- dataerai_sdk-0.3.0.dev1/tests/test_train_reference_checkpoint_gate.py +99 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_tutorial_notebook.py +7 -5
- dataerai_sdk-0.3.0.dev1/tests/test_unsaved_rotation_5407.py +107 -0
- dataerai_sdk-0.3.0.dev1/tests/test_watermark_extract_binary_mode.py +97 -0
- dataerai_sdk-0.3.0.dev1/tests/test_watermark_extract_portable_chmod.py +109 -0
- dataerai_sdk-0.3.0b8/dataerai/runner/cli.py +0 -414
- dataerai_sdk-0.3.0b8/dataerai/runner/state.py +0 -157
- dataerai_sdk-0.3.0b8/tests/test_ml_review_followups.py +0 -164
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/LICENSE +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_agent.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_daemon.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_darwin_acl_probe.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_endpoint.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_errors.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_connection.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_exchange.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_key.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_hello_key_location.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_timeparse.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_transport.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_windows_identity.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_windows_key.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/_windows_key_acl.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/capture.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/cli.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/feature_access.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/integration.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/journal.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/models.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/bambu/recorder.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/api.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bases.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/alignment.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/fcs.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/gff.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/sequence.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/bio/vcf.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/checksum.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/molfile.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/qchem_output.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/structure.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/compchem/xyz.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/_netcdf_reader.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/fits.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/hdf5.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/image.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/matlab.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/netcdf.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/nexus.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/numpy_array.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/parquet.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/containers/zarr_store.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converter.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/AFM/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/AFM/oxfordAFM/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/AFM/oxfordAFM/ibw.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/RHEED/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/RHEED/ksa/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/RHEED/ksa/imm.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/Xray/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/Xray/panalytical/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/Xray/panalytical/xrdml.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/converters/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/core.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/crystallography/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/crystallography/cif.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/crystallography/vasp.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/data_type.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/data_type_definitions.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/budget.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/execution_log.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/json_document.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/documents/notebook.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/feature_access.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bandexcitation/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bandexcitation/h5.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bruker/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/bruker/nanoscope.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/oxfordAFM/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/AFM/oxfordAFM/ibw.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/dm/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/dm/dm3.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/EM/dm/dm4.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/MS/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/MS/hiden/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/MS/hiden/massoft_csv.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/RHEED/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/RHEED/ksa/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/RHEED/ksa/imm.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/Xray/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/Xray/panalytical/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/Xray/panalytical/xrdml.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/instruments/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/andi_ms.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/imzml.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/mzml.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/mzxml.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/massspec/thermo_raw.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/dicom.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/edf.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/nifti.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/medical/nwb.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/czi.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/microscopy/olympus.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/bruker_opus.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/jcamp.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/renishaw_wdf.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/spectroscopy/thermo_spc.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/units.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/utils.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/Xray/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/Xray/panalytical/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/Xray/panalytical/xrd.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/afm.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/dart_pfm.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/single_frequency_pfm.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/vector_pfm.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/instruments/oxford/afms/visualize.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/layout.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/maps.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/_common.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/afm.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/bio.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/chemistry.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/clinical.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/containers.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/generic.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/imaging.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/microscopy.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/spectroscopy.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/metadata_schemas/xrd.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/metaextract/viz/router.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/ai_ready_reader.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/calibration.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/codes.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/hooks.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/attribution/sae.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/bench.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/hls4ml.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/io.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/keras_dataset.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/report.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/__main__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/serve/loader.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/_docs.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/errors.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/live.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/reader.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/session.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/timeseries.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/video.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/ml/stream/writer.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/_provenance.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/pytorch.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/system.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/nn/tensorflow.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/notebook.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/pycroscopy/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/pycroscopy/feature_control.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/qick/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/qick/feature_control.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/rest/_config.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/__init__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/__main__.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/_winjob.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/artifacts.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/config.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/cpu_profile.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/csv_extract.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/device_auth.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/downloads.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/extract_csv.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/infer.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/handlers/serve.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/sigv4.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai/runner/telemetry.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/dependency_links.txt +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/dataerai_sdk.egg-info/top_level.txt +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/setup.cfg +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_agent.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ai_ready_croissant_external_mlc.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_feature_control.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_inference.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_sae.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_attribution_training.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_collection_sync.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_credentials_save_windows.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_daemon_startup_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_envelope.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_events.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_framing.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_client_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_exchange_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_key_location_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_key_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_hello_proof_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ipc_endpoint_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_keras_hls4ml.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_access_ttl.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_ai_ready_croissant.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_ai_ready_reader.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_bench.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_cache.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_content_pinning.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_distributed.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_gpu.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_gpu_path.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_io.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_loader.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_read_path.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_review_followups_torch.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_sampler_correctness.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_staging.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_ml_telemetry.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_nn_tensorflow.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_notebook.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_notebook_trace.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_notebook_trace_feature_control.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_pat_credentials_compatibility.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_provenance_tokens_feature_control.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_rest_auth.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_rest_client.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_inputs.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_loader_device.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_serve_packaging.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_core.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_live.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_timeseries.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_stream_video.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_terms_gate.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_timeparse.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_transport.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_verifiable_credentials.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_watermark.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_acl_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_native_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_refusal_boundary.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_key_storage_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_pipe_cancellation_security.py +0 -0
- {dataerai_sdk-0.3.0b8 → dataerai_sdk-0.3.0.dev1}/tests/test_windows_pipe_identity_security.py +0 -0
- {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.
|
|
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.
|
|
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.
|
|
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.
|
|
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.
|
|
525
|
-
pip install --pre "dataerai-sdk[ml]>=0.
|
|
526
|
-
pip install --pre "dataerai-sdk[ml-keras]>=0.
|
|
527
|
-
pip install --pre "dataerai-sdk[ml-hls4ml]>=0.
|
|
528
|
-
pip install --pre "dataerai-sdk[notebook]>=0.
|
|
529
|
-
pip install --pre "dataerai-sdk[nn-tensorflow]>=0.
|
|
530
|
-
pip install --pre "dataerai-sdk[envelope]>=0.
|
|
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`
|
|
1109
|
-
>
|
|
1110
|
-
>
|
|
1111
|
-
>
|
|
1112
|
-
>
|
|
1113
|
-
>
|
|
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
|
|
1144
|
-
>
|
|
1145
|
-
> read but not write to is absent, and so are its
|
|
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
|
-
|
|
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.
|
|
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.
|
|
26
|
-
pip install --pre "dataerai-sdk[ml]>=0.
|
|
27
|
-
pip install --pre "dataerai-sdk[ml-keras]>=0.
|
|
28
|
-
pip install --pre "dataerai-sdk[ml-hls4ml]>=0.
|
|
29
|
-
pip install --pre "dataerai-sdk[notebook]>=0.
|
|
30
|
-
pip install --pre "dataerai-sdk[nn-tensorflow]>=0.
|
|
31
|
-
pip install --pre "dataerai-sdk[envelope]>=0.
|
|
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`
|
|
610
|
-
>
|
|
611
|
-
>
|
|
612
|
-
>
|
|
613
|
-
>
|
|
614
|
-
>
|
|
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
|
|
645
|
-
>
|
|
646
|
-
> read but not write to is absent, and so are its
|
|
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
|
-
|
|
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 =
|
|
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
|
|
261
|
-
|
|
262
|
-
|
|
263
|
-
|
|
264
|
-
|
|
265
|
-
|
|
266
|
-
|
|
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
|
-
``
|
|
300
|
-
because the daemon runs a bounded number of transfers at once
|
|
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
|
|
@@ -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(
|
|
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
|