datamint 2.2.1__tar.gz → 2.3.0__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.

Potentially problematic release.


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

Files changed (50) hide show
  1. {datamint-2.2.1 → datamint-2.3.0}/PKG-INFO +1 -1
  2. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/client.py +13 -5
  3. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/endpoints/__init__.py +3 -1
  4. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/endpoints/annotations_api.py +21 -6
  5. datamint-2.3.0/datamint/api/endpoints/models_api.py +47 -0
  6. {datamint-2.2.1 → datamint-2.3.0}/datamint/exceptions.py +22 -1
  7. {datamint-2.2.1 → datamint-2.3.0}/pyproject.toml +1 -1
  8. {datamint-2.2.1 → datamint-2.3.0}/README.md +0 -0
  9. {datamint-2.2.1 → datamint-2.3.0}/datamint/__init__.py +0 -0
  10. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/__init__.py +0 -0
  11. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/base_api.py +0 -0
  12. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/dto/__init__.py +0 -0
  13. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/endpoints/channels_api.py +0 -0
  14. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/endpoints/datasetsinfo_api.py +0 -0
  15. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/endpoints/projects_api.py +0 -0
  16. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/endpoints/resources_api.py +0 -0
  17. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/endpoints/users_api.py +0 -0
  18. {datamint-2.2.1 → datamint-2.3.0}/datamint/api/entity_base_api.py +0 -0
  19. {datamint-2.2.1 → datamint-2.3.0}/datamint/apihandler/annotation_api_handler.py +0 -0
  20. {datamint-2.2.1 → datamint-2.3.0}/datamint/apihandler/api_handler.py +0 -0
  21. {datamint-2.2.1 → datamint-2.3.0}/datamint/apihandler/base_api_handler.py +0 -0
  22. {datamint-2.2.1 → datamint-2.3.0}/datamint/apihandler/dto/__init__.py +0 -0
  23. {datamint-2.2.1 → datamint-2.3.0}/datamint/apihandler/dto/annotation_dto.py +0 -0
  24. {datamint-2.2.1 → datamint-2.3.0}/datamint/apihandler/exp_api_handler.py +0 -0
  25. {datamint-2.2.1 → datamint-2.3.0}/datamint/apihandler/root_api_handler.py +0 -0
  26. {datamint-2.2.1 → datamint-2.3.0}/datamint/client_cmd_tools/__init__.py +0 -0
  27. {datamint-2.2.1 → datamint-2.3.0}/datamint/client_cmd_tools/datamint_config.py +0 -0
  28. {datamint-2.2.1 → datamint-2.3.0}/datamint/client_cmd_tools/datamint_upload.py +0 -0
  29. {datamint-2.2.1 → datamint-2.3.0}/datamint/configs.py +0 -0
  30. {datamint-2.2.1 → datamint-2.3.0}/datamint/dataset/__init__.py +0 -0
  31. {datamint-2.2.1 → datamint-2.3.0}/datamint/dataset/annotation.py +0 -0
  32. {datamint-2.2.1 → datamint-2.3.0}/datamint/dataset/base_dataset.py +0 -0
  33. {datamint-2.2.1 → datamint-2.3.0}/datamint/dataset/dataset.py +0 -0
  34. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/__init__.py +0 -0
  35. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/annotation.py +0 -0
  36. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/base_entity.py +0 -0
  37. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/channel.py +0 -0
  38. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/datasetinfo.py +0 -0
  39. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/project.py +0 -0
  40. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/resource.py +0 -0
  41. {datamint-2.2.1 → datamint-2.3.0}/datamint/entities/user.py +0 -0
  42. {datamint-2.2.1 → datamint-2.3.0}/datamint/examples/__init__.py +0 -0
  43. {datamint-2.2.1 → datamint-2.3.0}/datamint/examples/example_projects.py +0 -0
  44. {datamint-2.2.1 → datamint-2.3.0}/datamint/experiment/__init__.py +0 -0
  45. {datamint-2.2.1 → datamint-2.3.0}/datamint/experiment/_patcher.py +0 -0
  46. {datamint-2.2.1 → datamint-2.3.0}/datamint/experiment/experiment.py +0 -0
  47. {datamint-2.2.1 → datamint-2.3.0}/datamint/logging.yaml +0 -0
  48. {datamint-2.2.1 → datamint-2.3.0}/datamint/utils/logging_utils.py +0 -0
  49. {datamint-2.2.1 → datamint-2.3.0}/datamint/utils/torchmetrics.py +0 -0
  50. {datamint-2.2.1 → datamint-2.3.0}/datamint/utils/visualization.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: datamint
3
- Version: 2.2.1
3
+ Version: 2.3.0
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
@@ -1,10 +1,8 @@
1
1
  from typing import Optional
2
- import httpx
3
2
  from .base_api import ApiConfig
4
- from .endpoints import ProjectsApi, ResourcesApi, AnnotationsApi, ChannelsApi, UsersApi, DatasetsInfoApi
3
+ from .endpoints import ProjectsApi, ResourcesApi, AnnotationsApi, ChannelsApi, UsersApi, DatasetsInfoApi, ModelsApi
5
4
  import datamint.configs
6
5
  from datamint.exceptions import DatamintException
7
- import asyncio
8
6
 
9
7
 
10
8
  class Api:
@@ -18,7 +16,8 @@ class Api:
18
16
  'annotations': AnnotationsApi,
19
17
  'channels': ChannelsApi,
20
18
  'users': UsersApi,
21
- 'datasets': DatasetsInfoApi
19
+ 'datasets': DatasetsInfoApi,
20
+ 'models': ModelsApi
22
21
  }
23
22
 
24
23
  def __init__(self,
@@ -73,19 +72,28 @@ class Api:
73
72
  @property
74
73
  def projects(self) -> ProjectsApi:
75
74
  return self._get_endpoint('projects')
75
+
76
76
  @property
77
77
  def resources(self) -> ResourcesApi:
78
78
  return self._get_endpoint('resources')
79
+
79
80
  @property
80
81
  def annotations(self) -> AnnotationsApi:
81
82
  return self._get_endpoint('annotations')
83
+
82
84
  @property
83
85
  def channels(self) -> ChannelsApi:
84
86
  return self._get_endpoint('channels')
87
+
85
88
  @property
86
89
  def users(self) -> UsersApi:
87
90
  return self._get_endpoint('users')
91
+
88
92
  @property
89
93
  def _datasetsinfo(self) -> DatasetsInfoApi:
90
94
  """Internal property to access DatasetsInfoApi."""
91
- return self._get_endpoint('datasets')
95
+ return self._get_endpoint('datasets')
96
+
97
+ @property
98
+ def models(self) -> ModelsApi:
99
+ return self._get_endpoint('models')
@@ -6,6 +6,7 @@ from .projects_api import ProjectsApi
6
6
  from .resources_api import ResourcesApi
7
7
  from .users_api import UsersApi
8
8
  from .datasetsinfo_api import DatasetsInfoApi
9
+ from .models_api import ModelsApi
9
10
 
10
11
  __all__ = [
11
12
  'AnnotationsApi',
@@ -13,5 +14,6 @@ __all__ = [
13
14
  'ProjectsApi',
14
15
  'ResourcesApi',
15
16
  'UsersApi',
16
- 'DatasetsInfoApi'
17
+ 'DatasetsInfoApi',
18
+ 'ModelsApi',
17
19
  ]
@@ -3,9 +3,9 @@ import httpx
3
3
  from datetime import date
4
4
  import logging
5
5
  from ..entity_base_api import ApiConfig, CreatableEntityApi, DeletableEntityApi
6
+ from .models_api import ModelsApi
6
7
  from datamint.entities.annotation import Annotation
7
8
  from datamint.entities.resource import Resource
8
- from datamint.entities.project import Project
9
9
  from datamint.apihandler.dto.annotation_dto import AnnotationType, CreateAnnotationDto, LineGeometry, BoxGeometry, CoordinateSystem, Geometry
10
10
  import numpy as np
11
11
  import os
@@ -38,6 +38,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
38
38
  client: Optional HTTP client instance. If None, a new one will be created.
39
39
  """
40
40
  super().__init__(config, Annotation, 'annotations', client)
41
+ self._models_api = ModelsApi(config, client=client)
41
42
 
42
43
  def get_list(self,
43
44
  resource: str | Resource | None = None,
@@ -69,7 +70,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
69
70
 
70
71
  async def _upload_segmentations_async(self,
71
72
  resource: str | Resource,
72
- frame_index: int | Sequence [int] | None,
73
+ frame_index: int | Sequence[int] | None,
73
74
  file_path: str | np.ndarray,
74
75
  name: dict[int, str] | dict[tuple, str],
75
76
  imported_from: str | None = None,
@@ -78,7 +79,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
78
79
  worklist_id: str | None = None,
79
80
  model_id: str | None = None,
80
81
  transpose_segmentation: bool = False,
81
- upload_volume: bool | str = 'auto'
82
+ upload_volume: bool | str = 'auto',
82
83
  ) -> Sequence[str]:
83
84
  """
84
85
  Upload segmentations asynchronously.
@@ -397,6 +398,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
397
398
  worklist_id: str | None = None,
398
399
  model_id: str | None = None,
399
400
  transpose_segmentation: bool = False,
401
+ ai_model_name: str | None = None
400
402
  ) -> list[str]:
401
403
  """
402
404
  Upload segmentations to a resource.
@@ -425,6 +427,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
425
427
  worklist_id: The annotation worklist unique id.
426
428
  model_id: The model unique id.
427
429
  transpose_segmentation: Whether to transpose the segmentation or not.
430
+ ai_model_name: Optional AI model name to associate with the segmentation.
428
431
 
429
432
  Returns:
430
433
  List of segmentation unique ids.
@@ -453,6 +456,18 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
453
456
  if isinstance(file_path, str) and not os.path.exists(file_path):
454
457
  raise FileNotFoundError(f"File {file_path} not found.")
455
458
 
459
+ if ai_model_name is not None:
460
+ model_id = self._models_api.get_by_name(ai_model_name)
461
+ if model_id is None:
462
+ try:
463
+ available_models = [model['name'] for model in self._models_api.get_all()]
464
+ except Exception:
465
+ _LOGGER.warning("Could not fetch available AI models from the server.")
466
+ raise ValueError(f"AI model with name '{ai_model_name}' not found. ")
467
+ raise ValueError(f"AI model with name '{ai_model_name}' not found. " +
468
+ f"Available models: {available_models}")
469
+ model_id = model_id['id']
470
+
456
471
  # Handle NIfTI files specially - upload as single volume
457
472
  if isinstance(file_path, str) and (file_path.endswith('.nii') or file_path.endswith('.nii.gz')):
458
473
  _LOGGER.info(f"Uploading NIfTI segmentation file: {file_path}")
@@ -472,7 +487,7 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
472
487
  worklist_id=worklist_id,
473
488
  model_id=model_id,
474
489
  transpose_segmentation=transpose_segmentation,
475
- upload_volume=True
490
+ upload_volume=True,
476
491
  )
477
492
  return loop.run_until_complete(task)
478
493
 
@@ -486,8 +501,8 @@ class AnnotationsApi(CreatableEntityApi[Annotation], DeletableEntityApi[Annotati
486
501
  raise ValueError("frame_index list contains duplicate values.")
487
502
 
488
503
  if isinstance(frame_index, Sequence) and len(frame_index) == 1:
489
- frame_index = frame_index[0]
490
-
504
+ frame_index = frame_index[0]
505
+
491
506
  nest_asyncio.apply()
492
507
  loop = asyncio.get_event_loop()
493
508
  task = self._upload_segmentations_async(
@@ -0,0 +1,47 @@
1
+ from typing import Sequence
2
+ from ..entity_base_api import ApiConfig, BaseApi
3
+ import httpx
4
+ from datamint.exceptions import EntityAlreadyExistsError
5
+
6
+
7
+ class ModelsApi(BaseApi):
8
+ """API handler for project-related endpoints."""
9
+
10
+ def __init__(self,
11
+ config: ApiConfig,
12
+ client: httpx.Client | None = None) -> None:
13
+ """Initialize the projects API handler.
14
+
15
+ Args:
16
+ config: API configuration containing base URL, API key, etc.
17
+ client: Optional HTTP client instance. If None, a new one will be created.
18
+ """
19
+ super().__init__(config, client=client)
20
+
21
+ def create(self,
22
+ name: str) -> dict:
23
+ json = {
24
+ 'name': name
25
+ }
26
+
27
+ try:
28
+ response = self._make_request('POST',
29
+ 'ai-models',
30
+ json=json)
31
+ return response.json()
32
+ except httpx.HTTPStatusError as e:
33
+ if e.response.status_code == 409:
34
+ raise EntityAlreadyExistsError('ai-model', {'name': name})
35
+ raise
36
+
37
+ def get_all(self) -> Sequence[dict]:
38
+ response = self._make_request('GET',
39
+ 'ai-models')
40
+ return response.json()
41
+
42
+ def get_by_name(self, name: str) -> dict | None:
43
+ models = self.get_all()
44
+ for model in models:
45
+ if model['name'] == name:
46
+ return model
47
+ return None
@@ -28,4 +28,25 @@ class ResourceNotFoundError(DatamintException):
28
28
  self.params = params
29
29
 
30
30
  def __str__(self):
31
- return f"Resource '{self.resource_type}' not found for parameters: {self.params}"
31
+ return f"Resource '{self.resource_type}' not found for parameters: {self.params}"
32
+
33
+ # Already existing (e.g, creating a project with a name that already exists)
34
+ class EntityAlreadyExistsError(DatamintException):
35
+ """
36
+ Exception raised when trying to create an entity that already exists.
37
+ For instance, when creating a project with a name that already exists.
38
+ """
39
+
40
+ def __init__(self, entity_type: str, params: dict):
41
+ """Constructor.
42
+
43
+ Args:
44
+ entity_type: The type of entity that already exists.
45
+ params: Dict of params identifying the existing entity.
46
+ """
47
+ super().__init__()
48
+ self.entity_type = entity_type
49
+ self.params = params
50
+
51
+ def __str__(self) -> str:
52
+ return f"Entity '{self.entity_type}' already exists for parameters: {self.params}"
@@ -1,7 +1,7 @@
1
1
  [project]
2
2
  name = "datamint"
3
3
  description = "A library for interacting with the Datamint API, designed for efficient data management, processing and Deep Learning workflows."
4
- version = "2.2.1"
4
+ version = "2.3.0"
5
5
  dynamic = ["dependencies"]
6
6
  requires-python = ">=3.10"
7
7
  readme = "README.md"
File without changes
File without changes
File without changes
File without changes