datamint 2.18.0__tar.gz → 2.18.2__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.
- {datamint-2.18.0 → datamint-2.18.2}/PKG-INFO +77 -13
- {datamint-2.18.0 → datamint-2.18.2}/README.md +73 -12
- {datamint-2.18.0 → datamint-2.18.2}/datamint/__init__.py +3 -1
- {datamint-2.18.0 → datamint-2.18.2}/datamint/__main__.py +23 -6
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/client.py +20 -3
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/annotations_api.py +66 -20
- datamint-2.18.2/datamint/api/endpoints/annotationsets_api.py +944 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/datasetsinfo_api.py +17 -4
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/deploy_model_api.py +17 -3
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/inference_api.py +53 -11
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/projects_api.py +233 -70
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/resources_api.py +16 -6
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/users_api.py +32 -9
- {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/datamint_config.py +16 -8
- datamint-2.18.2/datamint/client_cmd_tools/datamint_example.py +77 -0
- datamint-2.18.2/datamint/client_cmd_tools/datamint_inference.py +233 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/datamint_init.py +72 -13
- datamint-2.18.2/datamint/client_cmd_tools/datamint_train.py +446 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/datamint_upload.py +8 -1
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/base.py +26 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/factory.py +25 -8
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/sliced_dataset.py +1 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/split_result.py +1 -1
- datamint-2.18.2/datamint/default_project.py +60 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/project.py +26 -1
- datamint-2.18.2/datamint/examples/__init__.py +2 -0
- datamint-2.18.2/datamint/examples/_common.py +41 -0
- datamint-2.18.2/datamint/examples/_download.py +55 -0
- datamint-2.18.2/datamint/examples/bccd_dataset.py +102 -0
- datamint-2.18.2/datamint/examples/busi_dataset.py +67 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/examples/example_projects.py +1 -1
- datamint-2.18.2/datamint/examples/fracatlas_dataset.py +79 -0
- datamint-2.18.2/datamint/examples/synapse_dataset.py +106 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/exceptions.py +24 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/datamodule.py +9 -2
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/data_import.py +1 -1
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/trainer.py +1 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/yolox.py +2 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/env_utils.py +2 -2
- datamint-2.18.2/datamint/mlflow/flavors/model_parser.py +141 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/models/datamint_model_store.py +23 -22
- datamint-2.18.2/datamint/utils/annotation_agreement.py +357 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/env.py +7 -0
- {datamint-2.18.0 → datamint-2.18.2}/pyproject.toml +8 -2
- datamint-2.18.0/datamint/api/endpoints/annotationsets_api.py +0 -588
- datamint-2.18.0/datamint/examples/__init__.py +0 -1
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/base_api.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/dto/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/dto/annotation_dto.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/channels_api.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/models_api.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/api/entity_base_api.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/configs.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/annotation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/annotation_processor.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/base_dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/image_dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/multiframe_dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/sliced_video_dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/video_dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/volume_dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotation_worklist.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/annotation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/annotation_spec.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/base_geometry.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/base_segmentation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/box_annotation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/geometry.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/image_classification.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/image_segmentation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/line_annotation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/types.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/volume_segmentation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/base_entity.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/cache_manager.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/channel.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/datasetinfo.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/deployjob.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/inferencejob.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/project_resource_split.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/dicom_resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/image_resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/nifti_resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/video_resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/volume_resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/sliced_resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/sliced_resource_base.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/sliced_video_resource.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/user.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/base_trainer.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/classification_trainer.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/detection_trainer.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/base.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/classification_module.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/detection_modules/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/detection_modules/yolox_module.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_module.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/deeplabv3plus.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/smp_module.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/transunet.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/unetpp.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/unetrpp.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/seg2d_trainer.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/seg3d_trainer.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/segmentation_trainer.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/deeplabv3plus.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/efficientnetv2.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/_nnunet_trainer_bridge.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/data_export.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/inference_model.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/transunet.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/unetpp.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/unetrpp.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/vol_seg_trainer.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/logging.yaml +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/artifact/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/artifact/datamint_artifacts_repo.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/data/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/data/datamint_dataset.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/env_vars.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/datamint_flavor.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/model.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/model_loader.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/prediction_modes.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/prediction_router.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/task_type.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/validation.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/lightning/callbacks/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/lightning/callbacks/modelcheckpoint.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/models/__init__.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/store_utils.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/tracking/datamint_store.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/tracking/default_experiment.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/tracking/fluent.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/types.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/collection_utils.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/logging_utils.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/nifti_utils.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/torchmetrics.py +0 -0
- {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/visualization.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.4
|
|
2
2
|
Name: datamint
|
|
3
|
-
Version: 2.18.
|
|
3
|
+
Version: 2.18.2
|
|
4
4
|
Summary: A library for interacting with the Datamint API, designed for efficient data management, processing and Deep Learning workflows.
|
|
5
5
|
Requires-Python: >=3.10
|
|
6
6
|
Classifier: Programming Language :: Python :: 3
|
|
@@ -12,6 +12,7 @@ Classifier: Programming Language :: Python :: 3.14
|
|
|
12
12
|
Provides-Extra: detection
|
|
13
13
|
Provides-Extra: dev
|
|
14
14
|
Provides-Extra: docs
|
|
15
|
+
Provides-Extra: examples
|
|
15
16
|
Provides-Extra: nnunet
|
|
16
17
|
Requires-Dist: Deprecated (>=1.2.0)
|
|
17
18
|
Requires-Dist: Flask (<4)
|
|
@@ -23,6 +24,7 @@ Requires-Dist: backports-strenum ; python_version < "3.11"
|
|
|
23
24
|
Requires-Dist: cachetools (>=6.0.0)
|
|
24
25
|
Requires-Dist: certifi (>=2025.0.0)
|
|
25
26
|
Requires-Dist: filelock (>=3.0) ; extra == "nnunet"
|
|
27
|
+
Requires-Dist: h5py (>=3.0) ; extra == "examples"
|
|
26
28
|
Requires-Dist: httpx
|
|
27
29
|
Requires-Dist: humanize (>=4.0.0,<5.0.0)
|
|
28
30
|
Requires-Dist: lazy-loader (>=0.3.0)
|
|
@@ -51,6 +53,7 @@ Requires-Dist: rich (>=10.0.0)
|
|
|
51
53
|
Requires-Dist: segmentation-models-pytorch (>=0.5.0)
|
|
52
54
|
Requires-Dist: setuptools (>=57.0) ; extra == "docs"
|
|
53
55
|
Requires-Dist: sphinx (>=5.0) ; extra == "docs"
|
|
56
|
+
Requires-Dist: sphinx-rtd-dark-mode (>=1.3.0) ; extra == "docs"
|
|
54
57
|
Requires-Dist: sphinx-tabs (>=3.0.0) ; extra == "docs"
|
|
55
58
|
Requires-Dist: sphinx_rtd_theme (>=2.0.0) ; extra == "docs"
|
|
56
59
|
Requires-Dist: torch (>=1.2.0,!=2.3.0)
|
|
@@ -73,6 +76,61 @@ Datamint turns medical imaging ML work. Dataset management, annotation, training
|
|
|
73
76
|
|
|
74
77
|
**Common use cases:** 🩻 Segmentation · 🏷️ Classification · 📦 Detection
|
|
75
78
|
|
|
79
|
+
Datamint handles the full journey from **raw files** to a **deployed model**:
|
|
80
|
+
|
|
81
|
+
```mermaid
|
|
82
|
+
flowchart LR
|
|
83
|
+
Files(["📁 Your Files"])
|
|
84
|
+
|
|
85
|
+
subgraph s1 [1 · Ingest]
|
|
86
|
+
Resource(["📦 Resource"])
|
|
87
|
+
end
|
|
88
|
+
|
|
89
|
+
subgraph s2 [2 · Organize & Annotate]
|
|
90
|
+
direction TB
|
|
91
|
+
Project(["🗂️ Project"])
|
|
92
|
+
Annotations(["🏷️ Annotations"])
|
|
93
|
+
Project -.->|annotate| Annotations
|
|
94
|
+
end
|
|
95
|
+
|
|
96
|
+
subgraph s3 [3 · Train]
|
|
97
|
+
direction LR
|
|
98
|
+
Dataset(["🧮 Dataset"])
|
|
99
|
+
Trainer(["🧠 Trainer"])
|
|
100
|
+
Model(["📈 Model"])
|
|
101
|
+
Dataset -->|train| Trainer -->|register| Model
|
|
102
|
+
end
|
|
103
|
+
|
|
104
|
+
subgraph s4 [4 · Deploy & Predict]
|
|
105
|
+
direction LR
|
|
106
|
+
DeployJob(["🚀 Deploy Job"])
|
|
107
|
+
Inference(["🔮 Inference"])
|
|
108
|
+
DeployJob -->|predict| Inference
|
|
109
|
+
end
|
|
110
|
+
|
|
111
|
+
Files -->|upload| Resource
|
|
112
|
+
Resource -->|organize| Project
|
|
113
|
+
Project -->|load| Dataset
|
|
114
|
+
Model -->|deploy| DeployJob
|
|
115
|
+
|
|
116
|
+
classDef ingestNode fill:#ffffff,stroke:#1f6feb,stroke-width:2px,color:#0b2b4c
|
|
117
|
+
classDef organizeNode fill:#ffffff,stroke:#1a7f37,stroke-width:2px,color:#0b3a1c
|
|
118
|
+
classDef mlNode fill:#ffffff,stroke:#8250df,stroke-width:2px,color:#2c1a4d
|
|
119
|
+
classDef deployNode fill:#ffffff,stroke:#d1720f,stroke-width:2px,color:#4d2b00
|
|
120
|
+
classDef fileNode fill:#f6f8fa,stroke:#57606a,stroke-width:2px,color:#24292f
|
|
121
|
+
|
|
122
|
+
class Files fileNode
|
|
123
|
+
class Resource ingestNode
|
|
124
|
+
class Project,Annotations organizeNode
|
|
125
|
+
class Dataset,Trainer,Model mlNode
|
|
126
|
+
class DeployJob,Inference deployNode
|
|
127
|
+
|
|
128
|
+
style s1 fill:#dceeff,stroke:#1f6feb,stroke-width:2px,color:#0b2b4c
|
|
129
|
+
style s2 fill:#dbf5df,stroke:#1a7f37,stroke-width:2px,color:#0b3a1c
|
|
130
|
+
style s3 fill:#ecdcff,stroke:#8250df,stroke-width:2px,color:#2c1a4d
|
|
131
|
+
style s4 fill:#ffe8c7,stroke:#d1720f,stroke-width:2px,color:#4d2b00
|
|
132
|
+
```
|
|
133
|
+
|
|
76
134
|
## 📋 Table of Contents
|
|
77
135
|
|
|
78
136
|
- [See it in action](#-see-it-in-action)
|
|
@@ -83,7 +141,7 @@ Datamint turns medical imaging ML work. Dataset management, annotation, training
|
|
|
83
141
|
|
|
84
142
|
## 🎬 See it in action
|
|
85
143
|
|
|
86
|
-
|
|
144
|
+
**Create** a project, **split** the data, **train**, and **deploy**, all through the API:
|
|
87
145
|
|
|
88
146
|

|
|
89
147
|
|
|
@@ -131,7 +189,7 @@ For instance, create the enviroment once with `python3 -m venv datamint-env` and
|
|
|
131
189
|
**2. Configure your API key**
|
|
132
190
|
|
|
133
191
|
```bash
|
|
134
|
-
datamint
|
|
192
|
+
datamint config
|
|
135
193
|
```
|
|
136
194
|
|
|
137
195
|
Follow the prompts (ask your administrator if you don't have a key yet). Environment variable and programmatic options are in the [Setup API Key guide](https://sonanceai.github.io/datamint-python-api/getting_started.html#setup-api-key).
|
|
@@ -139,7 +197,7 @@ Follow the prompts (ask your administrator if you don't have a key yet). Environ
|
|
|
139
197
|
**3. Scaffold a project — the fastest way to start**
|
|
140
198
|
|
|
141
199
|
```bash
|
|
142
|
-
datamint
|
|
200
|
+
datamint init
|
|
143
201
|
```
|
|
144
202
|
|
|
145
203
|
This is the recommended on-ramp: it asks for a project name and task type (**segmentation**, **classification**, or **detection**), then generates a ready-to-run, numbered set of scripts (`01_upload_data.py` → `06_deploy.py`) — upload data, train, and deploy by running them in order.
|
|
@@ -159,15 +217,21 @@ results = trainer.fit()
|
|
|
159
217
|
|
|
160
218
|
## 📚 Documentation
|
|
161
219
|
|
|
162
|
-
|
|
163
|
-
|
|
164
|
-
|
|
165
|
-
|
|
166
|
-
|
|
167
|
-
|
|
168
|
-
|
|
|
169
|
-
|
|
170
|
-
| [
|
|
220
|
+
**Difficulty levels:**
|
|
221
|
+
|
|
222
|
+
-  no ML knowledge needed
|
|
223
|
+
- assumes SDK familiarity, introduces ML/dataset concepts
|
|
224
|
+
-  full training pipelines, custom models, 3D data, multi-step workflows.
|
|
225
|
+
|
|
226
|
+
| Resource | Level | Description |
|
|
227
|
+
|----------|-------|-------------|
|
|
228
|
+
| [🚀 Getting Started](https://sonanceai.github.io/datamint-python-api/getting_started.html) |  | Step-by-step setup and basic usage |
|
|
229
|
+
| [📖 API Reference](https://sonanceai.github.io/datamint-python-api/client_api.html) |  | Complete API documentation |
|
|
230
|
+
| [🔥 PyTorch Integration](https://sonanceai.github.io/datamint-python-api/pytorch_integration.html) |  | ML workflow integration |
|
|
231
|
+
| [🧠 Trainer Guide](https://sonanceai.github.io/datamint-python-api/trainer_api.html) |  | Built-in trainers, trainer lifecycle, and custom model integration |
|
|
232
|
+
| [🛠️ Command Line Tools](https://sonanceai.github.io/datamint-python-api/command_line_tools.html) |  | Full reference for `datamint upload`, `datamint init`, and `datamint config` |
|
|
233
|
+
| [🔒 SSL Troubleshooting](https://sonanceai.github.io/datamint-python-api/ssl_troubleshooting.html) | — | Fixing `SSLCertVerificationError` |
|
|
234
|
+
| [📓 Notebooks](notebooks/) |    | Numbered, runnable tutorials. Start at `01_getting_started` and work through annotations, datasets, experiment tracking, deployment, and a full end-to-end example |
|
|
171
235
|
|
|
172
236
|
## 🆘 Support
|
|
173
237
|
|
|
@@ -11,6 +11,61 @@ Datamint turns medical imaging ML work. Dataset management, annotation, training
|
|
|
11
11
|
|
|
12
12
|
**Common use cases:** 🩻 Segmentation · 🏷️ Classification · 📦 Detection
|
|
13
13
|
|
|
14
|
+
Datamint handles the full journey from **raw files** to a **deployed model**:
|
|
15
|
+
|
|
16
|
+
```mermaid
|
|
17
|
+
flowchart LR
|
|
18
|
+
Files(["📁 Your Files"])
|
|
19
|
+
|
|
20
|
+
subgraph s1 [1 · Ingest]
|
|
21
|
+
Resource(["📦 Resource"])
|
|
22
|
+
end
|
|
23
|
+
|
|
24
|
+
subgraph s2 [2 · Organize & Annotate]
|
|
25
|
+
direction TB
|
|
26
|
+
Project(["🗂️ Project"])
|
|
27
|
+
Annotations(["🏷️ Annotations"])
|
|
28
|
+
Project -.->|annotate| Annotations
|
|
29
|
+
end
|
|
30
|
+
|
|
31
|
+
subgraph s3 [3 · Train]
|
|
32
|
+
direction LR
|
|
33
|
+
Dataset(["🧮 Dataset"])
|
|
34
|
+
Trainer(["🧠 Trainer"])
|
|
35
|
+
Model(["📈 Model"])
|
|
36
|
+
Dataset -->|train| Trainer -->|register| Model
|
|
37
|
+
end
|
|
38
|
+
|
|
39
|
+
subgraph s4 [4 · Deploy & Predict]
|
|
40
|
+
direction LR
|
|
41
|
+
DeployJob(["🚀 Deploy Job"])
|
|
42
|
+
Inference(["🔮 Inference"])
|
|
43
|
+
DeployJob -->|predict| Inference
|
|
44
|
+
end
|
|
45
|
+
|
|
46
|
+
Files -->|upload| Resource
|
|
47
|
+
Resource -->|organize| Project
|
|
48
|
+
Project -->|load| Dataset
|
|
49
|
+
Model -->|deploy| DeployJob
|
|
50
|
+
|
|
51
|
+
classDef ingestNode fill:#ffffff,stroke:#1f6feb,stroke-width:2px,color:#0b2b4c
|
|
52
|
+
classDef organizeNode fill:#ffffff,stroke:#1a7f37,stroke-width:2px,color:#0b3a1c
|
|
53
|
+
classDef mlNode fill:#ffffff,stroke:#8250df,stroke-width:2px,color:#2c1a4d
|
|
54
|
+
classDef deployNode fill:#ffffff,stroke:#d1720f,stroke-width:2px,color:#4d2b00
|
|
55
|
+
classDef fileNode fill:#f6f8fa,stroke:#57606a,stroke-width:2px,color:#24292f
|
|
56
|
+
|
|
57
|
+
class Files fileNode
|
|
58
|
+
class Resource ingestNode
|
|
59
|
+
class Project,Annotations organizeNode
|
|
60
|
+
class Dataset,Trainer,Model mlNode
|
|
61
|
+
class DeployJob,Inference deployNode
|
|
62
|
+
|
|
63
|
+
style s1 fill:#dceeff,stroke:#1f6feb,stroke-width:2px,color:#0b2b4c
|
|
64
|
+
style s2 fill:#dbf5df,stroke:#1a7f37,stroke-width:2px,color:#0b3a1c
|
|
65
|
+
style s3 fill:#ecdcff,stroke:#8250df,stroke-width:2px,color:#2c1a4d
|
|
66
|
+
style s4 fill:#ffe8c7,stroke:#d1720f,stroke-width:2px,color:#4d2b00
|
|
67
|
+
```
|
|
68
|
+
|
|
14
69
|
## 📋 Table of Contents
|
|
15
70
|
|
|
16
71
|
- [See it in action](#-see-it-in-action)
|
|
@@ -21,7 +76,7 @@ Datamint turns medical imaging ML work. Dataset management, annotation, training
|
|
|
21
76
|
|
|
22
77
|
## 🎬 See it in action
|
|
23
78
|
|
|
24
|
-
|
|
79
|
+
**Create** a project, **split** the data, **train**, and **deploy**, all through the API:
|
|
25
80
|
|
|
26
81
|

|
|
27
82
|
|
|
@@ -69,7 +124,7 @@ For instance, create the enviroment once with `python3 -m venv datamint-env` and
|
|
|
69
124
|
**2. Configure your API key**
|
|
70
125
|
|
|
71
126
|
```bash
|
|
72
|
-
datamint
|
|
127
|
+
datamint config
|
|
73
128
|
```
|
|
74
129
|
|
|
75
130
|
Follow the prompts (ask your administrator if you don't have a key yet). Environment variable and programmatic options are in the [Setup API Key guide](https://sonanceai.github.io/datamint-python-api/getting_started.html#setup-api-key).
|
|
@@ -77,7 +132,7 @@ Follow the prompts (ask your administrator if you don't have a key yet). Environ
|
|
|
77
132
|
**3. Scaffold a project — the fastest way to start**
|
|
78
133
|
|
|
79
134
|
```bash
|
|
80
|
-
datamint
|
|
135
|
+
datamint init
|
|
81
136
|
```
|
|
82
137
|
|
|
83
138
|
This is the recommended on-ramp: it asks for a project name and task type (**segmentation**, **classification**, or **detection**), then generates a ready-to-run, numbered set of scripts (`01_upload_data.py` → `06_deploy.py`) — upload data, train, and deploy by running them in order.
|
|
@@ -97,15 +152,21 @@ results = trainer.fit()
|
|
|
97
152
|
|
|
98
153
|
## 📚 Documentation
|
|
99
154
|
|
|
100
|
-
|
|
101
|
-
|
|
102
|
-
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
|
107
|
-
|
|
108
|
-
| [
|
|
155
|
+
**Difficulty levels:**
|
|
156
|
+
|
|
157
|
+
-  no ML knowledge needed
|
|
158
|
+
- assumes SDK familiarity, introduces ML/dataset concepts
|
|
159
|
+
-  full training pipelines, custom models, 3D data, multi-step workflows.
|
|
160
|
+
|
|
161
|
+
| Resource | Level | Description |
|
|
162
|
+
|----------|-------|-------------|
|
|
163
|
+
| [🚀 Getting Started](https://sonanceai.github.io/datamint-python-api/getting_started.html) |  | Step-by-step setup and basic usage |
|
|
164
|
+
| [📖 API Reference](https://sonanceai.github.io/datamint-python-api/client_api.html) |  | Complete API documentation |
|
|
165
|
+
| [🔥 PyTorch Integration](https://sonanceai.github.io/datamint-python-api/pytorch_integration.html) |  | ML workflow integration |
|
|
166
|
+
| [🧠 Trainer Guide](https://sonanceai.github.io/datamint-python-api/trainer_api.html) |  | Built-in trainers, trainer lifecycle, and custom model integration |
|
|
167
|
+
| [🛠️ Command Line Tools](https://sonanceai.github.io/datamint-python-api/command_line_tools.html) |  | Full reference for `datamint upload`, `datamint init`, and `datamint config` |
|
|
168
|
+
| [🔒 SSL Troubleshooting](https://sonanceai.github.io/datamint-python-api/ssl_troubleshooting.html) | — | Fixing `SSLCertVerificationError` |
|
|
169
|
+
| [📓 Notebooks](notebooks/) |    | Numbered, runnable tutorials. Start at `01_getting_started` and work through annotations, datasets, experiment tracking, deployment, and a full end-to-end example |
|
|
109
170
|
|
|
110
171
|
## 🆘 Support
|
|
111
172
|
|
|
@@ -10,13 +10,14 @@ if TYPE_CHECKING:
|
|
|
10
10
|
from .dataset.image_dataset import ImageDataset
|
|
11
11
|
from .dataset.volume_dataset import VolumeDataset
|
|
12
12
|
from .mlflow.flavors.validation import validate_model, ValidationReport, ValidationIssue, ModelValidationError
|
|
13
|
+
from .default_project import select_project
|
|
13
14
|
|
|
14
15
|
else:
|
|
15
16
|
import lazy_loader as lazy
|
|
16
17
|
|
|
17
18
|
__getattr__, __dir__, __all__ = lazy.attach(
|
|
18
19
|
__name__,
|
|
19
|
-
submodules=['dataset', "dataset.dataset"],
|
|
20
|
+
submodules=['dataset', "dataset.dataset", "examples"],
|
|
20
21
|
submod_attrs={
|
|
21
22
|
"api.client": ["Api"],
|
|
22
23
|
# New modular dataset classes
|
|
@@ -24,6 +25,7 @@ else:
|
|
|
24
25
|
"dataset.volume_dataset": ["VolumeDataset"],
|
|
25
26
|
"mlflow.flavors.validation": ["validate_model", "ValidationReport",
|
|
26
27
|
"ValidationIssue", "ModelValidationError"],
|
|
28
|
+
"default_project": ["select_project"],
|
|
27
29
|
},
|
|
28
30
|
)
|
|
29
31
|
|
|
@@ -8,7 +8,10 @@ import sys
|
|
|
8
8
|
_COMMANDS: dict[str, str] = {
|
|
9
9
|
"config": "datamint.client_cmd_tools.datamint_config",
|
|
10
10
|
"upload": "datamint.client_cmd_tools.datamint_upload",
|
|
11
|
-
"init": "datamint.client_cmd_tools.datamint_init"
|
|
11
|
+
"init": "datamint.client_cmd_tools.datamint_init",
|
|
12
|
+
"train": "datamint.client_cmd_tools.datamint_train",
|
|
13
|
+
"inference": "datamint.client_cmd_tools.datamint_inference",
|
|
14
|
+
"example": "datamint.client_cmd_tools.datamint_example",
|
|
12
15
|
}
|
|
13
16
|
|
|
14
17
|
|
|
@@ -21,9 +24,9 @@ def _resolve_version() -> str:
|
|
|
21
24
|
|
|
22
25
|
def _build_parser() -> argparse.ArgumentParser:
|
|
23
26
|
parser = argparse.ArgumentParser(
|
|
24
|
-
prog="
|
|
27
|
+
prog="datamint",
|
|
25
28
|
description="Datamint command-line interface.",
|
|
26
|
-
epilog="Available commands:
|
|
29
|
+
epilog=f"Available commands: {', '.join(_COMMANDS)}.",
|
|
27
30
|
)
|
|
28
31
|
parser.add_argument(
|
|
29
32
|
"command",
|
|
@@ -41,11 +44,25 @@ def _build_parser() -> argparse.ArgumentParser:
|
|
|
41
44
|
|
|
42
45
|
def main() -> None:
|
|
43
46
|
parser = _build_parser()
|
|
44
|
-
|
|
45
|
-
|
|
47
|
+
argv = sys.argv[1:]
|
|
48
|
+
|
|
49
|
+
if not argv:
|
|
50
|
+
# Bare "datamint" with no subcommand: show help instead of an argparse error
|
|
51
|
+
parser.print_help()
|
|
52
|
+
sys.exit(0)
|
|
53
|
+
|
|
54
|
+
# Parse only the first token (the command name) so that flags meant for the subcommand
|
|
55
|
+
# (e.g. "datamint upload --help") are forwarded untouched instead of being swallowed by
|
|
56
|
+
# this top-level parser's own -h/--help/--version handling, which would otherwise trigger
|
|
57
|
+
# as soon as it sees them anywhere in the argument list.
|
|
58
|
+
args = parser.parse_args(argv[:1])
|
|
59
|
+
remaining = argv[1:]
|
|
46
60
|
|
|
47
61
|
# Replace argv so the subcommand sees only its own arguments.
|
|
48
|
-
|
|
62
|
+
# Note: a space (not a hyphen) so nested argparse usage lines read "datamint <command>"
|
|
63
|
+
# (argparse's default prog is os.path.basename(sys.argv[0]), which is the string as-is
|
|
64
|
+
# when it has no path separator).
|
|
65
|
+
sys.argv = [f"datamint {args.command}", *remaining]
|
|
49
66
|
|
|
50
67
|
module_path = _COMMANDS[args.command]
|
|
51
68
|
try:
|
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
from typing import Any
|
|
2
|
+
|
|
1
3
|
from .base_api import ApiConfig, BaseApi
|
|
2
4
|
from .endpoints import (ProjectsApi, ResourcesApi, AnnotationsApi,
|
|
3
5
|
ChannelsApi, UsersApi, DatasetsInfoApi,
|
|
@@ -30,6 +32,13 @@ class Api:
|
|
|
30
32
|
'inference': InferenceApi,
|
|
31
33
|
}
|
|
32
34
|
|
|
35
|
+
# (server_url, api_key, verify_ssl) signatures already verified successfully in
|
|
36
|
+
# this process. Lets check_connection=True skip a redundant network round-trip
|
|
37
|
+
# (e.g. one per DataLoader worker or dataset auto-refresh) once a given
|
|
38
|
+
# configuration is known to work. A changed value simply misses the cache,
|
|
39
|
+
# forcing a fresh check.
|
|
40
|
+
_verified_connections: set[tuple[str, str | None, bool | str]] = set()
|
|
41
|
+
|
|
33
42
|
def __init__(self,
|
|
34
43
|
server_url: str | None = None,
|
|
35
44
|
api_key: str | None = None,
|
|
@@ -43,7 +52,9 @@ class Api:
|
|
|
43
52
|
api_key: Optional API key for authentication
|
|
44
53
|
timeout: Request timeout in seconds
|
|
45
54
|
max_retries: Maximum number of retry attempts
|
|
46
|
-
check_connection: Whether to check connection on initialization
|
|
55
|
+
check_connection: Whether to check connection on initialization. Skipped
|
|
56
|
+
automatically if this exact (server_url, api_key, verify_ssl) combination
|
|
57
|
+
already passed a check earlier in this process.
|
|
47
58
|
verify_ssl: Whether to verify SSL certificates. Default is True.
|
|
48
59
|
Set to False only in development environments with self-signed certificates.
|
|
49
60
|
Can also be a path to a CA bundle file for custom certificate verification.
|
|
@@ -87,7 +98,8 @@ class Api:
|
|
|
87
98
|
self._highclient = None
|
|
88
99
|
self._mlclient = None
|
|
89
100
|
self._endpoints: dict[str, BaseApi] = {}
|
|
90
|
-
|
|
101
|
+
self._connection_signature = (server_url, api_key, verify_ssl)
|
|
102
|
+
if check_connection and self._connection_signature not in Api._verified_connections:
|
|
91
103
|
self.check_connection()
|
|
92
104
|
|
|
93
105
|
def check_connection(self):
|
|
@@ -96,6 +108,7 @@ class Api:
|
|
|
96
108
|
except Exception as e:
|
|
97
109
|
raise NetworkError("Error connecting to the Datamint API."
|
|
98
110
|
" Please check your api_key and/or other configurations.") from e
|
|
111
|
+
Api._verified_connections.add(self._connection_signature)
|
|
99
112
|
|
|
100
113
|
def close(self) -> None:
|
|
101
114
|
"""Close underlying HTTP clients and any shared aiohttp sessions.
|
|
@@ -133,7 +146,11 @@ class Api:
|
|
|
133
146
|
client = self._client
|
|
134
147
|
if name not in self._endpoints:
|
|
135
148
|
api_class = self._API_MAP[name]
|
|
136
|
-
|
|
149
|
+
# Inject ProjectsApi into InferenceApi for project_name → project_id resolution
|
|
150
|
+
kwargs: dict[str, Any] = {}
|
|
151
|
+
if name == 'inference':
|
|
152
|
+
kwargs['projects_api'] = self.projects
|
|
153
|
+
endpoint = api_class(self.config, client=client, **kwargs)
|
|
137
154
|
# Inject this API instance into the endpoint so it can inject into entities
|
|
138
155
|
endpoint._api_instance = self
|
|
139
156
|
self._endpoints[name] = endpoint
|
|
@@ -7,6 +7,7 @@ import asyncio
|
|
|
7
7
|
import json
|
|
8
8
|
import logging
|
|
9
9
|
import os
|
|
10
|
+
import warnings
|
|
10
11
|
|
|
11
12
|
import aiohttp
|
|
12
13
|
import httpx
|
|
@@ -39,6 +40,7 @@ from ..entity_base_api import ApiConfig, CreatableEntityApi, DeletableEntityApi
|
|
|
39
40
|
if TYPE_CHECKING:
|
|
40
41
|
from .resources_api import ResourcesApi
|
|
41
42
|
from .models_api import ModelsApi
|
|
43
|
+
from datamint.entities import Project
|
|
42
44
|
|
|
43
45
|
|
|
44
46
|
_LOGGER = logging.getLogger(__name__)
|
|
@@ -75,8 +77,8 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
75
77
|
resource: str | Resource | Sequence[str | Resource] | None = None,
|
|
76
78
|
annotation_type: AnnotationType | str | None = None,
|
|
77
79
|
annotator_email: str | None = None,
|
|
78
|
-
|
|
79
|
-
|
|
80
|
+
from_date: date | None = None,
|
|
81
|
+
to_date: date | None = None,
|
|
80
82
|
dataset_id: str | None = None,
|
|
81
83
|
worklist_id: str | None = None,
|
|
82
84
|
status: Literal['new', 'published'] | None = None,
|
|
@@ -90,8 +92,8 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
90
92
|
resource: str | Resource | Sequence[str | Resource] | None = None,
|
|
91
93
|
annotation_type: AnnotationType | str | None = None,
|
|
92
94
|
annotator_email: str | None = None,
|
|
93
|
-
|
|
94
|
-
|
|
95
|
+
from_date: date | None = None,
|
|
96
|
+
to_date: date | None = None,
|
|
95
97
|
dataset_id: str | None = None,
|
|
96
98
|
worklist_id: str | None = None,
|
|
97
99
|
status: Literal['new', 'published'] | None = None,
|
|
@@ -106,14 +108,17 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
106
108
|
resource: str | Resource | Sequence[str | Resource] | None = None,
|
|
107
109
|
annotation_type: AnnotationType | str | None = None,
|
|
108
110
|
annotator_email: str | None = None,
|
|
109
|
-
|
|
110
|
-
|
|
111
|
+
from_date: date | None = None,
|
|
112
|
+
to_date: date | None = None,
|
|
111
113
|
dataset_id: str | None = None,
|
|
112
114
|
worklist_id: str | None = None,
|
|
113
115
|
status: Literal['new', 'published'] | None = None,
|
|
114
116
|
load_ai_segmentations: bool | None = None,
|
|
115
117
|
limit: int | None = None,
|
|
116
118
|
group_by_resource: bool = False,
|
|
119
|
+
*,
|
|
120
|
+
date_from: date | None = None,
|
|
121
|
+
date_to: date | None = None,
|
|
117
122
|
**kwargs: Any,
|
|
118
123
|
) -> Sequence[Annotation] | Sequence[Sequence[Annotation]]:
|
|
119
124
|
"""
|
|
@@ -124,8 +129,8 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
124
129
|
a list of resources, or None to retrieve annotations from all resources.
|
|
125
130
|
annotation_type: Filter by annotation type (e.g., 'segmentation', 'category').
|
|
126
131
|
annotator_email: Filter by annotator email address.
|
|
127
|
-
|
|
128
|
-
|
|
132
|
+
from_date: Filter annotations created on or after this date.
|
|
133
|
+
to_date: Filter annotations created on or before this date.
|
|
129
134
|
dataset_id: Filter by dataset unique id.
|
|
130
135
|
worklist_id: Filter by annotation worklist unique id.
|
|
131
136
|
status: Filter by annotation status ('new' or 'published').
|
|
@@ -133,6 +138,8 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
133
138
|
limit: Maximum number of annotations to return.
|
|
134
139
|
group_by_resource: If True, return results grouped by resource.
|
|
135
140
|
For instance, the first index of the returned list will contain all annotations for the first resource.
|
|
141
|
+
date_from: (DEPRECATED) Use ``from_date`` instead.
|
|
142
|
+
date_to: (DEPRECATED) Use ``to_date`` instead.
|
|
136
143
|
|
|
137
144
|
Returns:
|
|
138
145
|
Sequence[Annotation] | Sequence[Sequence[Annotation]]: List of annotations, or list of lists if grouped by resource.
|
|
@@ -167,12 +174,23 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
167
174
|
resource_annotations_map[ann.resource_id].append(ann)
|
|
168
175
|
return [resource_annotations_map[rid] for rid in resource_ids]
|
|
169
176
|
|
|
177
|
+
if date_from is not None:
|
|
178
|
+
warnings.warn("The 'date_from' parameter is deprecated. "
|
|
179
|
+
"Please use 'from_date' instead", DeprecationWarning)
|
|
180
|
+
if from_date is None:
|
|
181
|
+
from_date = date_from
|
|
182
|
+
if date_to is not None:
|
|
183
|
+
warnings.warn("The 'date_to' parameter is deprecated. "
|
|
184
|
+
"Please use 'to_date' instead", DeprecationWarning)
|
|
185
|
+
if to_date is None:
|
|
186
|
+
to_date = date_to
|
|
187
|
+
|
|
170
188
|
# Build search payload according to POST /annotations/search schema
|
|
171
189
|
payload = {
|
|
172
190
|
'annotation_type': annotation_type,
|
|
173
191
|
'annotatorEmail': annotator_email,
|
|
174
|
-
'from':
|
|
175
|
-
'to':
|
|
192
|
+
'from': from_date.isoformat() if from_date is not None else None,
|
|
193
|
+
'to': to_date.isoformat() if to_date is not None else None,
|
|
176
194
|
'dataset_id': dataset_id,
|
|
177
195
|
'annotation_worklist_id': worklist_id,
|
|
178
196
|
'status': status,
|
|
@@ -585,9 +603,11 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
585
603
|
imported_from: str | None = None,
|
|
586
604
|
author_email: str | None = None,
|
|
587
605
|
worklist_id: str | None = None,
|
|
588
|
-
|
|
606
|
+
model_name: str | None = None,
|
|
589
607
|
transpose_segmentation: bool = False,
|
|
590
608
|
source: str | None = 'imported',
|
|
609
|
+
*,
|
|
610
|
+
ai_model_name: str | None = None,
|
|
591
611
|
) -> list[str]:
|
|
592
612
|
"""
|
|
593
613
|
Upload a 3D volume segmentation to a resource.
|
|
@@ -603,8 +623,9 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
603
623
|
imported_from: The imported from value.
|
|
604
624
|
author_email: The author email.
|
|
605
625
|
worklist_id: The annotation worklist unique id.
|
|
606
|
-
|
|
626
|
+
model_name: The AI model name.
|
|
607
627
|
transpose_segmentation: Whether to transpose the segmentation before uploading.
|
|
628
|
+
ai_model_name: (DEPRECATED) Use ``model_name`` instead.
|
|
608
629
|
source: Annotation source tag. Defaults to 'imported' since this is a direct API
|
|
609
630
|
entry point; :meth:`upload_predictions` overrides it with 'model_pipeline'/'model_deploy'.
|
|
610
631
|
|
|
@@ -634,13 +655,19 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
634
655
|
"""
|
|
635
656
|
import nest_asyncio
|
|
636
657
|
|
|
658
|
+
if ai_model_name is not None:
|
|
659
|
+
warnings.warn("The 'ai_model_name' parameter is deprecated. "
|
|
660
|
+
"Please use 'model_name' instead", DeprecationWarning)
|
|
661
|
+
if model_name is None:
|
|
662
|
+
model_name = ai_model_name
|
|
663
|
+
|
|
637
664
|
if isinstance(file_path, Path):
|
|
638
665
|
file_path = str(file_path)
|
|
639
666
|
|
|
640
667
|
if isinstance(file_path, str) and not os.path.exists(file_path):
|
|
641
668
|
raise FileNotFoundError(f"File {file_path} not found.")
|
|
642
669
|
|
|
643
|
-
model_id = self._check_model(
|
|
670
|
+
model_id = self._check_model(model_name)
|
|
644
671
|
|
|
645
672
|
nest_asyncio.apply()
|
|
646
673
|
loop = asyncio.get_event_loop()
|
|
@@ -668,8 +695,10 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
668
695
|
discard_empty_segmentations: bool = True,
|
|
669
696
|
worklist_id: str | None = None,
|
|
670
697
|
transpose_segmentation: bool = False,
|
|
671
|
-
|
|
698
|
+
model_name: str | None = None,
|
|
672
699
|
source: str | None = 'imported',
|
|
700
|
+
*,
|
|
701
|
+
ai_model_name: str | None = None,
|
|
673
702
|
) -> list[str]:
|
|
674
703
|
"""
|
|
675
704
|
Upload frame-by-frame segmentations to a resource.
|
|
@@ -698,9 +727,10 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
698
727
|
worklist_id: The annotation worklist unique id.
|
|
699
728
|
model_id: The model unique id.
|
|
700
729
|
transpose_segmentation: Whether to transpose the segmentation or not.
|
|
701
|
-
|
|
730
|
+
model_name: Optional AI model name to associate with the segmentation.
|
|
702
731
|
source: Annotation source tag. Defaults to 'imported' since this is a direct API
|
|
703
732
|
entry point; :meth:`upload_predictions` overrides it with 'model_pipeline'/'model_deploy'.
|
|
733
|
+
ai_model_name: (DEPRECATED) Use ``model_name`` instead.
|
|
704
734
|
|
|
705
735
|
Returns:
|
|
706
736
|
List of segmentation unique ids.
|
|
@@ -729,6 +759,12 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
729
759
|
"""
|
|
730
760
|
import nest_asyncio
|
|
731
761
|
|
|
762
|
+
if ai_model_name is not None:
|
|
763
|
+
warnings.warn("The 'ai_model_name' parameter is deprecated. "
|
|
764
|
+
"Please use 'model_name' instead", DeprecationWarning)
|
|
765
|
+
if model_name is None:
|
|
766
|
+
model_name = ai_model_name
|
|
767
|
+
|
|
732
768
|
if isinstance(file_path, Path):
|
|
733
769
|
file_path = str(file_path)
|
|
734
770
|
|
|
@@ -740,7 +776,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
740
776
|
"NIfTI files are volume segmentations. Use `upload_volume_segmentation` instead."
|
|
741
777
|
)
|
|
742
778
|
|
|
743
|
-
model_id = self._check_model(
|
|
779
|
+
model_id = self._check_model(model_name)
|
|
744
780
|
|
|
745
781
|
standardized_name = self.standardize_segmentation_names(name)
|
|
746
782
|
_LOGGER.debug(f"Standardized segmentation names: {standardized_name}")
|
|
@@ -1149,7 +1185,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
1149
1185
|
resource=resource,
|
|
1150
1186
|
file_path=mask,
|
|
1151
1187
|
name=ann.class_map,
|
|
1152
|
-
|
|
1188
|
+
model_name=model_name,
|
|
1153
1189
|
source=source,
|
|
1154
1190
|
)
|
|
1155
1191
|
annotation_ids.extend(ids)
|
|
@@ -1166,7 +1202,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
1166
1202
|
file_path=mask,
|
|
1167
1203
|
name=ann.identifier,
|
|
1168
1204
|
frame_index=ann.frame_index,
|
|
1169
|
-
|
|
1205
|
+
model_name=model_name,
|
|
1170
1206
|
source=source,
|
|
1171
1207
|
)
|
|
1172
1208
|
annotation_ids.extend(ids)
|
|
@@ -1550,6 +1586,8 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
1550
1586
|
def patch(self,
|
|
1551
1587
|
annotation: str | Annotation,
|
|
1552
1588
|
identifier: str | None = None,
|
|
1589
|
+
project: 'str | Project | None' = None,
|
|
1590
|
+
*,
|
|
1553
1591
|
project_id: str | None = None) -> None:
|
|
1554
1592
|
"""
|
|
1555
1593
|
Partially update an annotation's metadata.
|
|
@@ -1557,14 +1595,22 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
|
|
|
1557
1595
|
Args:
|
|
1558
1596
|
annotation: The annotation unique id or Annotation instance.
|
|
1559
1597
|
identifier: Optional new identifier/label for the annotation.
|
|
1560
|
-
|
|
1598
|
+
project: Optional project ID or Project instance to associate with the annotation.
|
|
1599
|
+
project_id: (DEPRECATED) Use ``project`` instead.
|
|
1561
1600
|
|
|
1562
1601
|
Raises:
|
|
1563
1602
|
ServerError: If the update fails.
|
|
1564
1603
|
"""
|
|
1565
1604
|
annotation_id = self._entid(annotation)
|
|
1566
1605
|
|
|
1567
|
-
|
|
1606
|
+
if project_id is not None:
|
|
1607
|
+
warnings.warn("The 'project_id' parameter is deprecated. "
|
|
1608
|
+
"Please use 'project' instead", DeprecationWarning)
|
|
1609
|
+
if project is None:
|
|
1610
|
+
project = project_id
|
|
1611
|
+
|
|
1612
|
+
payload = {'identifier': identifier,
|
|
1613
|
+
'project_id': self._entid(project) if project is not None else None}
|
|
1568
1614
|
# remove None values
|
|
1569
1615
|
payload = {k: v for k, v in payload.items() if v is not None}
|
|
1570
1616
|
if len(payload) == 0:
|