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.
Files changed (157) hide show
  1. {datamint-2.18.0 → datamint-2.18.2}/PKG-INFO +77 -13
  2. {datamint-2.18.0 → datamint-2.18.2}/README.md +73 -12
  3. {datamint-2.18.0 → datamint-2.18.2}/datamint/__init__.py +3 -1
  4. {datamint-2.18.0 → datamint-2.18.2}/datamint/__main__.py +23 -6
  5. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/client.py +20 -3
  6. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/annotations_api.py +66 -20
  7. datamint-2.18.2/datamint/api/endpoints/annotationsets_api.py +944 -0
  8. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/datasetsinfo_api.py +17 -4
  9. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/deploy_model_api.py +17 -3
  10. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/inference_api.py +53 -11
  11. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/projects_api.py +233 -70
  12. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/resources_api.py +16 -6
  13. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/users_api.py +32 -9
  14. {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/datamint_config.py +16 -8
  15. datamint-2.18.2/datamint/client_cmd_tools/datamint_example.py +77 -0
  16. datamint-2.18.2/datamint/client_cmd_tools/datamint_inference.py +233 -0
  17. {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/datamint_init.py +72 -13
  18. datamint-2.18.2/datamint/client_cmd_tools/datamint_train.py +446 -0
  19. {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/datamint_upload.py +8 -1
  20. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/base.py +26 -0
  21. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/factory.py +25 -8
  22. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/sliced_dataset.py +1 -0
  23. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/split_result.py +1 -1
  24. datamint-2.18.2/datamint/default_project.py +60 -0
  25. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/project.py +26 -1
  26. datamint-2.18.2/datamint/examples/__init__.py +2 -0
  27. datamint-2.18.2/datamint/examples/_common.py +41 -0
  28. datamint-2.18.2/datamint/examples/_download.py +55 -0
  29. datamint-2.18.2/datamint/examples/bccd_dataset.py +102 -0
  30. datamint-2.18.2/datamint/examples/busi_dataset.py +67 -0
  31. {datamint-2.18.0 → datamint-2.18.2}/datamint/examples/example_projects.py +1 -1
  32. datamint-2.18.2/datamint/examples/fracatlas_dataset.py +79 -0
  33. datamint-2.18.2/datamint/examples/synapse_dataset.py +106 -0
  34. {datamint-2.18.0 → datamint-2.18.2}/datamint/exceptions.py +24 -0
  35. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/datamodule.py +9 -2
  36. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/data_import.py +1 -1
  37. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/trainer.py +1 -0
  38. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/yolox.py +2 -0
  39. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/env_utils.py +2 -2
  40. datamint-2.18.2/datamint/mlflow/flavors/model_parser.py +141 -0
  41. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/models/datamint_model_store.py +23 -22
  42. datamint-2.18.2/datamint/utils/annotation_agreement.py +357 -0
  43. {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/env.py +7 -0
  44. {datamint-2.18.0 → datamint-2.18.2}/pyproject.toml +8 -2
  45. datamint-2.18.0/datamint/api/endpoints/annotationsets_api.py +0 -588
  46. datamint-2.18.0/datamint/examples/__init__.py +0 -1
  47. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/__init__.py +0 -0
  48. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/base_api.py +0 -0
  49. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/dto/__init__.py +0 -0
  50. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/dto/annotation_dto.py +0 -0
  51. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/__init__.py +0 -0
  52. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/channels_api.py +0 -0
  53. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/endpoints/models_api.py +0 -0
  54. {datamint-2.18.0 → datamint-2.18.2}/datamint/api/entity_base_api.py +0 -0
  55. {datamint-2.18.0 → datamint-2.18.2}/datamint/client_cmd_tools/__init__.py +0 -0
  56. {datamint-2.18.0 → datamint-2.18.2}/datamint/configs.py +0 -0
  57. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/__init__.py +0 -0
  58. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/annotation.py +0 -0
  59. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/annotation_processor.py +0 -0
  60. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/base_dataset.py +0 -0
  61. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/dataset.py +0 -0
  62. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/image_dataset.py +0 -0
  63. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/multiframe_dataset.py +0 -0
  64. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/sliced_video_dataset.py +0 -0
  65. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/video_dataset.py +0 -0
  66. {datamint-2.18.0 → datamint-2.18.2}/datamint/dataset/volume_dataset.py +0 -0
  67. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/__init__.py +0 -0
  68. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotation_worklist.py +0 -0
  69. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/__init__.py +0 -0
  70. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/annotation.py +0 -0
  71. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/annotation_spec.py +0 -0
  72. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/base_geometry.py +0 -0
  73. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/base_segmentation.py +0 -0
  74. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/box_annotation.py +0 -0
  75. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/geometry.py +0 -0
  76. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/image_classification.py +0 -0
  77. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/image_segmentation.py +0 -0
  78. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/line_annotation.py +0 -0
  79. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/types.py +0 -0
  80. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/annotations/volume_segmentation.py +0 -0
  81. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/base_entity.py +0 -0
  82. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/cache_manager.py +0 -0
  83. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/channel.py +0 -0
  84. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/datasetinfo.py +0 -0
  85. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/deployjob.py +0 -0
  86. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/inferencejob.py +0 -0
  87. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/project_resource_split.py +0 -0
  88. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resource.py +0 -0
  89. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/__init__.py +0 -0
  90. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/dicom_resource.py +0 -0
  91. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/image_resource.py +0 -0
  92. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/nifti_resource.py +0 -0
  93. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/video_resource.py +0 -0
  94. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/resources/volume_resource.py +0 -0
  95. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/sliced_resource.py +0 -0
  96. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/sliced_resource_base.py +0 -0
  97. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/sliced_video_resource.py +0 -0
  98. {datamint-2.18.0 → datamint-2.18.2}/datamint/entities/user.py +0 -0
  99. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/__init__.py +0 -0
  100. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/__init__.py +0 -0
  101. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/base_trainer.py +0 -0
  102. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/classification_trainer.py +0 -0
  103. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/detection_trainer.py +0 -0
  104. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/__init__.py +0 -0
  105. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/base.py +0 -0
  106. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/classification_module.py +0 -0
  107. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/detection_modules/__init__.py +0 -0
  108. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/detection_modules/yolox_module.py +0 -0
  109. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_module.py +0 -0
  110. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/__init__.py +0 -0
  111. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/deeplabv3plus.py +0 -0
  112. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/smp_module.py +0 -0
  113. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/transunet.py +0 -0
  114. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/unetpp.py +0 -0
  115. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/lightning_modules/segmentation_modules/unetrpp.py +0 -0
  116. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/seg2d_trainer.py +0 -0
  117. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/seg3d_trainer.py +0 -0
  118. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/segmentation_trainer.py +0 -0
  119. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/__init__.py +0 -0
  120. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/deeplabv3plus.py +0 -0
  121. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/efficientnetv2.py +0 -0
  122. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/__init__.py +0 -0
  123. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/_nnunet_trainer_bridge.py +0 -0
  124. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/data_export.py +0 -0
  125. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/nnunet/inference_model.py +0 -0
  126. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/transunet.py +0 -0
  127. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/unetpp.py +0 -0
  128. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/specialized/unetrpp.py +0 -0
  129. {datamint-2.18.0 → datamint-2.18.2}/datamint/lightning/trainers/vol_seg_trainer.py +0 -0
  130. {datamint-2.18.0 → datamint-2.18.2}/datamint/logging.yaml +0 -0
  131. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/__init__.py +0 -0
  132. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/artifact/__init__.py +0 -0
  133. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/artifact/datamint_artifacts_repo.py +0 -0
  134. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/data/__init__.py +0 -0
  135. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/data/datamint_dataset.py +0 -0
  136. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/env_vars.py +0 -0
  137. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/__init__.py +0 -0
  138. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/datamint_flavor.py +0 -0
  139. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/model.py +0 -0
  140. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/model_loader.py +0 -0
  141. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/prediction_modes.py +0 -0
  142. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/prediction_router.py +0 -0
  143. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/task_type.py +0 -0
  144. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/flavors/validation.py +0 -0
  145. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/lightning/callbacks/__init__.py +0 -0
  146. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/lightning/callbacks/modelcheckpoint.py +0 -0
  147. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/models/__init__.py +0 -0
  148. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/store_utils.py +0 -0
  149. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/tracking/datamint_store.py +0 -0
  150. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/tracking/default_experiment.py +0 -0
  151. {datamint-2.18.0 → datamint-2.18.2}/datamint/mlflow/tracking/fluent.py +0 -0
  152. {datamint-2.18.0 → datamint-2.18.2}/datamint/types.py +0 -0
  153. {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/collection_utils.py +0 -0
  154. {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/logging_utils.py +0 -0
  155. {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/nifti_utils.py +0 -0
  156. {datamint-2.18.0 → datamint-2.18.2}/datamint/utils/torchmetrics.py +0 -0
  157. {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.0
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
- From a project name to a deployed, validated model, patient-wise splitting, training, and deployment included:
144
+ **Create** a project, **split** the data, **train**, and **deploy**, all through the API:
87
145
 
88
146
  ![Datamint pipeline demo](assets/pipeline-demo.gif)
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-config
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-init
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
- | Resource | Description |
163
- |----------|-------------|
164
- | [🚀 Getting Started](https://sonanceai.github.io/datamint-python-api/getting_started.html) | Step-by-step setup and basic usage |
165
- | [📖 API Reference](https://sonanceai.github.io/datamint-python-api/client_api.html) | Complete API documentation |
166
- | [🔥 PyTorch Integration](https://sonanceai.github.io/datamint-python-api/pytorch_integration.html) | ML workflow integration |
167
- | [🧠 Trainer Guide](https://sonanceai.github.io/datamint-python-api/trainer_api.html) | Built-in trainers, trainer lifecycle, and custom model integration |
168
- | [🛠️ Command Line Tools](https://sonanceai.github.io/datamint-python-api/command_line_tools.html) | Full reference for `datamint-upload`, `datamint-init`, and `datamint-config` |
169
- | [🔒 SSL Troubleshooting](https://sonanceai.github.io/datamint-python-api/ssl_troubleshooting.html) | Fixing `SSLCertVerificationError` |
170
- | [📓 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 |
220
+ **Difficulty levels:**
221
+
222
+ - ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) no ML knowledge needed
223
+ - ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow)assumes SDK familiarity, introduces ML/dataset concepts
224
+ - ![Advanced](https://img.shields.io/badge/level-advanced-red) 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) | ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) | Step-by-step setup and basic usage |
229
+ | [📖 API Reference](https://sonanceai.github.io/datamint-python-api/client_api.html) | ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) | Complete API documentation |
230
+ | [🔥 PyTorch Integration](https://sonanceai.github.io/datamint-python-api/pytorch_integration.html) | ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) | ML workflow integration |
231
+ | [🧠 Trainer Guide](https://sonanceai.github.io/datamint-python-api/trainer_api.html) | ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) | Built-in trainers, trainer lifecycle, and custom model integration |
232
+ | [🛠️ Command Line Tools](https://sonanceai.github.io/datamint-python-api/command_line_tools.html) | ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) | 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/) | ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) ![Advanced](https://img.shields.io/badge/level-advanced-red) | 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
- From a project name to a deployed, validated model, patient-wise splitting, training, and deployment included:
79
+ **Create** a project, **split** the data, **train**, and **deploy**, all through the API:
25
80
 
26
81
  ![Datamint pipeline demo](assets/pipeline-demo.gif)
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-config
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-init
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
- | Resource | Description |
101
- |----------|-------------|
102
- | [🚀 Getting Started](https://sonanceai.github.io/datamint-python-api/getting_started.html) | Step-by-step setup and basic usage |
103
- | [📖 API Reference](https://sonanceai.github.io/datamint-python-api/client_api.html) | Complete API documentation |
104
- | [🔥 PyTorch Integration](https://sonanceai.github.io/datamint-python-api/pytorch_integration.html) | ML workflow integration |
105
- | [🧠 Trainer Guide](https://sonanceai.github.io/datamint-python-api/trainer_api.html) | Built-in trainers, trainer lifecycle, and custom model integration |
106
- | [🛠️ Command Line Tools](https://sonanceai.github.io/datamint-python-api/command_line_tools.html) | Full reference for `datamint-upload`, `datamint-init`, and `datamint-config` |
107
- | [🔒 SSL Troubleshooting](https://sonanceai.github.io/datamint-python-api/ssl_troubleshooting.html) | Fixing `SSLCertVerificationError` |
108
- | [📓 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 |
155
+ **Difficulty levels:**
156
+
157
+ - ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) no ML knowledge needed
158
+ - ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow)assumes SDK familiarity, introduces ML/dataset concepts
159
+ - ![Advanced](https://img.shields.io/badge/level-advanced-red) 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) | ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) | Step-by-step setup and basic usage |
164
+ | [📖 API Reference](https://sonanceai.github.io/datamint-python-api/client_api.html) | ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) | Complete API documentation |
165
+ | [🔥 PyTorch Integration](https://sonanceai.github.io/datamint-python-api/pytorch_integration.html) | ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) | ML workflow integration |
166
+ | [🧠 Trainer Guide](https://sonanceai.github.io/datamint-python-api/trainer_api.html) | ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) | Built-in trainers, trainer lifecycle, and custom model integration |
167
+ | [🛠️ Command Line Tools](https://sonanceai.github.io/datamint-python-api/command_line_tools.html) | ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) | 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/) | ![Beginner](https://img.shields.io/badge/level-beginner-brightgreen) ![Intermediate](https://img.shields.io/badge/level-intermediate-yellow) ![Advanced](https://img.shields.io/badge/level-advanced-red) | 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="python -m datamint",
27
+ prog="datamint",
25
28
  description="Datamint command-line interface.",
26
- epilog="Available commands: config, upload",
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
- # Parse only the first positional argument; leave the rest for the subcommand.
45
- args, remaining = parser.parse_known_args()
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
- sys.argv = [f"datamint-{args.command}", *remaining]
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
- if check_connection:
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
- endpoint = api_class(self.config, client=client)
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
- date_from: date | None = None,
79
- date_to: date | None = None,
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
- date_from: date | None = None,
94
- date_to: date | None = None,
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
- date_from: date | None = None,
110
- date_to: date | None = None,
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
- date_from: Filter annotations created on or after this date.
128
- date_to: Filter annotations created on or before this date.
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': date_from.isoformat() if date_from is not None else None,
175
- 'to': date_to.isoformat() if date_to is not None else None,
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
- ai_model_name: str | None = None,
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
- ai_model_name: The AI model name.
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(ai_model_name)
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
- ai_model_name: str | None = None,
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
- ai_model_name: Optional AI model name to associate with the segmentation.
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(ai_model_name)
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
- ai_model_name=model_name,
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
- ai_model_name=model_name,
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
- project_id: Optional project ID to associate with the annotation.
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
- payload = {'identifier': identifier, 'project_id': project_id}
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: