Annotations Subpackage

The datamint.entities.annotations subpackage contains all annotation-related entity classes for the Datamint platform.

class datamint.entities.annotations.Annotation(*, id=None, name, scope, annotation_type, confiability=1.0, frame_index=None, text_value=None, numeric_value=None, units=None, geometry=None, created_at=None, created_by=None, annotation_worklist_id=None, imported_from=None, import_author=None, status=None, approved_at=None, approved_by=None, resource_id=None, associated_file=None, deleted=False, deleted_at=None, deleted_by=None, created_by_model=None, is_model=None, model_id=None, set_name=None, resource_filename=None, resource_modality=None, annotation_worklist_name=None, user_info=None, values='MISSING_FIELD', file=None, **data)

Bases: AnnotationBase

Pydantic Model representing a DataMint annotation.

id

Unique identifier for the annotation.

identifier

User-friendly identifier or label for the annotation.

scope

Scope of the annotation (e.g., “frame”, “image”).

frame_index

Index of the frame if scope is frame-based.

annotation_type

Type of annotation (e.g., “segmentation”, “bbox”, “label”).

text_value

Optional text value associated with the annotation.

numeric_value

Optional numeric value associated with the annotation.

units

Optional units for numeric_value.

geometry

Optional geometry payload (e.g., polygons) as a list.

created_at

ISO timestamp for when the annotation was created.

created_by

Email or identifier of the creating user.

annotation_worklist_id

Optional worklist ID associated with the annotation.

status

Lifecycle status of the annotation (e.g., “new”, “approved”).

approved_at

Optional ISO timestamp for approval time.

approved_by

Optional identifier of the approver.

resource_id

ID of the resource this annotation belongs to.

associated_file

Path or identifier of any associated file artifact.

deleted

Whether the annotation is marked as deleted.

deleted_at

Optional ISO timestamp for deletion time.

deleted_by

Optional identifier of the user who deleted the annotation.

created_by_model

Optional identifier of the model that created this annotation.

old_geometry

Optional previous geometry payload for change tracking.

set_name

Optional set name this annotation belongs to.

resource_filename

Optional filename of the resource.

resource_modality

Optional modality of the resource (e.g., CT, MR).

annotation_worklist_name

Optional worklist name associated with the annotation.

user_info

Optional user information with keys like firstname and lastname.

values

Optional extra values payload for flexible schemas.

property added_by: str

Get the creator email (alias for created_by).

annotation_worklist_id: str | None
annotation_worklist_name: str | None
approved_at: str | None
approved_by: str | None
associated_file: str | None
created_at: str | None
created_by: str | None
created_by_model: str | None
deleted: bool
deleted_at: str | None
deleted_by: str | None
fetch_file_data(auto_convert=True, save_path=None, use_cache=False)
Overloads:
  • self, auto_convert (Literal[True]), save_path (str | None), use_cache (CacheMode) → ImagingData

  • self, auto_convert (Literal[False]), save_path (str | None), use_cache (CacheMode) → bytes

Get the file data for this annotation.

Parameters:
  • save_path (str | None) – Optional path to save the file locally. If use_cache=True, the file is saved to save_path and cache metadata points to that location (no duplication - only one file on disk).

  • auto_convert (bool) – If True, automatically converts to appropriate format

  • use_cache (bool | Literal['loadonly']) – Cache behavior for this call. Use False to bypass cache entirely, True to read from and save to cache, or "loadonly" to read from cache without saving cache misses.

Returns:

File data (format depends on auto_convert and file type)

Return type:

bytes | ImagingData

Example

>>> annotation = api.annotations.get_list(limit=1)[0]
>>> data = annotation.fetch_file_data(use_cache=True)
>>> data = annotation.fetch_file_data(use_cache="loadonly")
>>> annotation.fetch_file_data(save_path="annotation_file")
file: str | None
frame_index: int | None
classmethod from_dict(data)

Create an Annotation instance from a dictionary.

Parameters:

data (dict[str, Any]) – Dictionary containing annotation data from API

Return type:

Annotation

Returns:

Annotation instance

geometry: list | dict | None
get_created_datetime()

Get the creation datetime as a datetime object.

Return type:

datetime | None

Returns:

datetime object or None if created_at is not set

id: str | None
identifier: str
import_author: str | None
imported_from: str | None
property index: int | None

Get the frame index (alias for frame_index).

invalidate_cache()

Invalidate all cached data for this annotation.

Return type:

None

is_cached()

Check if the resource’s file data is already cached locally and valid.

Return type:

bool

Returns:

True if valid cached data exists, False otherwise.

is_frame_scoped()

Check if this annotation is frame-scoped.

Return type:

bool

is_image_scoped()

Check if this annotation is image-scoped.

Return type:

bool

is_model: bool | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_id: str | None
model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

numeric_value: float | int | None
property resource: Resource

Lazily load and cache the associated Resource entity.

Example

>>> annotation = api.annotations.get_list(limit=1)[0]
>>> annotation.resource.filename
resource_filename: str | None
resource_id: str | None
resource_modality: str | None
scope: str
set_name: str | None
status: str | None
text_value: str | None
property type: str

Alias for annotation_type.

units: str | None
user_info: dict | None
property value: str | None

Get the annotation value (for category annotations).

values: list | None
class datamint.entities.annotations.AnnotationType(*values)

Bases: StrEnum

ANGLE = 'angle'
AREA = 'area'
CATEGORY = 'category'
CIRCLE = 'circle'
DISTANCE = 'distance'
LABEL = 'label'
LINE = 'line'
POINT = 'point'
REGION = 'region'
SEGMENTATION = 'segmentation'
SQUARE = 'square'
class datamint.entities.annotations.BoxAnnotation(geometry=None, **kwargs)

Bases: BaseGeometryAnnotation

Typed box annotation entity.

Parameters:
  • geometry (BoxGeometry | dict[str, Any] | None)

  • kwargs (Any)

classmethod from_points(point1, point2, *, identifier, frame_index=None, metadata=None, coords_system='pixel', **kwargs)
Parameters:
  • point1 (tuple[int, int] | tuple[float, float, float])

  • point2 (tuple[int, int] | tuple[float, float, float])

  • identifier (str)

  • frame_index (int | None)

  • metadata (Dataset | Nifti1Image | None)

  • coords_system (Literal['pixel', 'patient'])

  • kwargs (Any)

Return type:

BoxAnnotation

geometry: BoxGeometry | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

class datamint.entities.annotations.BoxGeometry(**data)

Bases: Geometry

Parameters:

data (Any)

classmethod from_coordinates(point1, point2, *, coords_system='pixel', slice_plane=None, frame_index=None, metadata=None)
Parameters:
  • point1 (tuple[int, int] | tuple[float, float, float])

  • point2 (tuple[int, int] | tuple[float, float, float])

  • coords_system (Literal['pixel', 'patient'])

  • slice_plane (Literal['axial', 'sagittal', 'coronal'] | None)

  • frame_index (int | None)

  • metadata (Dataset | Nifti1Image | None)

Return type:

BoxGeometry

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property point1: tuple[int | float, int | float, int | float]
property point2: tuple[int | float, int | float, int | float]
points: tuple[tuple[int | float, int | float, int | float], tuple[int | float, int | float, int | float], tuple[int | float, int | float, int | float], tuple[int | float, int | float, int | float]]
type: ClassVar[str] = 'square'
class datamint.entities.annotations.Geometry(**data)

Bases: BaseModel

Base geometry payload for annotation entities.

Parameters:

data (Any)

coordinate_system: Literal['pixel', 'patient']
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

to_dict()
Return type:

dict[str, Any]

type: ClassVar[str]
viewPlaneNormal: tuple[float, float, float] | None
viewUp: tuple[float, float, float] | None
class datamint.entities.annotations.ImageClassification(name=None, value=None, confiability=1.0, **kwargs)

Bases: Annotation

Parameters:
  • name (str | None)

  • value (str | None)

  • confiability (float)

  • kwargs (Any)

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

class datamint.entities.annotations.ImageSegmentation(segmentation_data=None, **kwargs)

Bases: BaseSegmentationAnnotation

Image-level (2-D) binary segmentation annotation entity.

Represents a binary segmentation mask (foreground / background) for a single image. The stored mask always contains only 0 and 1 values; any non-zero input pixel is normalised to 1.

Parameters:
  • segmentation_data (ndarray | Image | None) – The mask as a np.ndarray (dtype=uint8), PIL.Image.Image, or nibabel.nifti1.Nifti1Image. Automatically serialised/deserialised on persist/load.

  • name (str) – The annotation class label (stored in the inherited identifier field).

Example

>>> mask = np.zeros((256, 256), dtype=np.uint8)
>>> mask[100:150, 100:150] = 1  # foreground region
>>> img_seg = ImageSegmentation.from_mask(mask=mask, name='lesion')
>>> img_seg.name
'lesion'
get_area()

Return the number of foreground (non-zero) pixels in the mask.

Return type:

int | None

Returns:

Foreground pixel count or None if no mask is stored.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

to_pil_image()

Convert the mask to a PIL Image.

Return type:

Image | None

Returns:

PIL.Image.Image or None if no mask is stored.

class datamint.entities.annotations.LineAnnotation(geometry=None, **kwargs)

Bases: BaseGeometryAnnotation

Typed line annotation entity.

Parameters:
  • geometry (LineGeometry | dict[str, Any] | None)

  • kwargs (Any)

classmethod from_points(point1, point2, *, identifier, frame_index=None, slice_plane=None, metadata=None, coords_system='pixel', **kwargs)
Parameters:
  • point1 (tuple[int, int] | tuple[float, float, float])

  • point2 (tuple[int, int] | tuple[float, float, float])

  • identifier (str)

  • frame_index (int | None)

  • slice_plane (Literal['axial', 'sagittal', 'coronal'] | None)

  • metadata (Dataset | Nifti1Image | None)

  • coords_system (Literal['pixel', 'patient'])

  • kwargs (Any)

Return type:

LineAnnotation

geometry: LineGeometry | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

class datamint.entities.annotations.LineGeometry(**data)

Bases: _TwoPointGeometry

Parameters:

data (Any)

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

type: ClassVar[str] = 'line'
class datamint.entities.annotations.VolumeSegmentation(*, id=None, name, scope, annotation_type, confiability=1.0, frame_index=None, text_value=None, numeric_value=None, units=None, geometry=None, created_at=None, created_by=None, annotation_worklist_id=None, imported_from=None, import_author=None, status=None, approved_at=None, approved_by=None, resource_id=None, associated_file=None, deleted=False, deleted_at=None, deleted_by=None, created_by_model=None, is_model=None, model_id=None, set_name=None, resource_filename=None, resource_modality=None, annotation_worklist_name=None, user_info=None, values='MISSING_FIELD', file=None, mask=None, class_map=None, **kwargs)

Bases: BaseSegmentationAnnotation

Volume-level segmentation annotation entity.

Represents a 3-D segmentation mask for medical imaging volumes. Supports both semantic segmentation (class per voxel) and instance segmentation (unique ID per object).

This class provides factory methods to create annotations from numpy arrays or NIfTI images, which can then be uploaded via AnnotationsApi.

Example

>>> # From semantic segmentation
>>> seg_data = np.array([...])  # Shape: (H, W, D)
>>> class_map = {1: 'tumor', 2: 'edema'}
>>> vol_seg = VolumeSegmentation.from_semantic_segmentation(
...     segmentation=seg_data,
...     class_map=class_map
... )
>>>
>>> # Upload via API
>>> api.annotations.upload_segmentations(
...     resource='resource_id',
...     file_path=vol_seg.segmentation_data,
...     name=vol_seg.class_map
... )
class_map: dict[int, str] | None
property class_names: list[str] | None

Get list of class names from stored class_map.

Returns:

List of class names or None if no class_map stored

classmethod from_semantic_segmentation(segmentation, class_map, **kwargs)

Create VolumeSegmentation from semantic segmentation data.

Semantic segmentation: each voxel has a single integer label corresponding to its class.

Parameters:
  • segmentation (ndarray | Nifti1Image) – 3D numpy array (H x W x D) or NIfTI image with integer labels representing classes

  • class_map (dict[int, str] | str) – Mapping from label integers to class names, or a single class name for binary segmentation (background=0, class=1)

  • **kwargs – Additional annotation fields (imported_from, model_id, etc.)

Return type:

VolumeSegmentation

Returns:

VolumeSegmentation instance ready for upload

Raises:

ValueError – If segmentation shape is invalid, class_map is incomplete, or data types are incorrect

Example

>>> seg = np.zeros((256, 256, 128), dtype=np.int32)
>>> seg[100:150, 100:150, 50:75] = 1  # tumor region
>>> vol_seg = VolumeSegmentation.from_semantic_segmentation(
...     segmentation=seg,
...     class_map={1: 'tumor'}, # or just ``class_map='tumor'``
... )
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

property num_classes: int | None

Get number of classes in this segmentation.

Returns:

Number of classes or None if no class_map stored

property volume_shape: tuple[int, int, int] | None

Get the shape of the stored segmentation volume.

Returns:

Shape tuple (H, W, D) or None if no data stored

datamint.entities.annotations.annotation_from_dict(data)

Factory: map a raw annotation dict to the appropriate Annotation subclass.

Dispatches on annotation_type:

segmentation_data dicts are automatically deserialised by the Pydantic BeforeValidator defined on BaseSegmentationAnnotation. class_map string keys (produced by JSON serialisation) are coerced to int by Pydantic’s lax validation.

Parameters:

data (dict) – Raw annotation dict as returned by the API.

Return type:

Annotation

Returns:

A concrete Annotation subclass instance.

Annotation Types

class datamint.entities.annotations.AnnotationType(*values)
ANGLE = 'angle'
AREA = 'area'
CATEGORY = 'category'
CIRCLE = 'circle'
DISTANCE = 'distance'
LABEL = 'label'
LINE = 'line'
POINT = 'point'
REGION = 'region'
SEGMENTATION = 'segmentation'
SQUARE = 'square'

Base Annotation

Annotation entity module for DataMint API.

This module defines the Annotation model used to represent annotation records returned by the DataMint API.

class datamint.entities.annotations.annotation.Annotation(*, id=None, name, scope, annotation_type, confiability=1.0, frame_index=None, text_value=None, numeric_value=None, units=None, geometry=None, created_at=None, created_by=None, annotation_worklist_id=None, imported_from=None, import_author=None, status=None, approved_at=None, approved_by=None, resource_id=None, associated_file=None, deleted=False, deleted_at=None, deleted_by=None, created_by_model=None, is_model=None, model_id=None, set_name=None, resource_filename=None, resource_modality=None, annotation_worklist_name=None, user_info=None, values='MISSING_FIELD', file=None, **data)

Bases: AnnotationBase

Pydantic Model representing a DataMint annotation.

id

Unique identifier for the annotation.

identifier

User-friendly identifier or label for the annotation.

scope

Scope of the annotation (e.g., “frame”, “image”).

frame_index

Index of the frame if scope is frame-based.

annotation_type

Type of annotation (e.g., “segmentation”, “bbox”, “label”).

text_value

Optional text value associated with the annotation.

numeric_value

Optional numeric value associated with the annotation.

units

Optional units for numeric_value.

geometry

Optional geometry payload (e.g., polygons) as a list.

created_at

ISO timestamp for when the annotation was created.

created_by

Email or identifier of the creating user.

annotation_worklist_id

Optional worklist ID associated with the annotation.

status

Lifecycle status of the annotation (e.g., “new”, “approved”).

approved_at

Optional ISO timestamp for approval time.

approved_by

Optional identifier of the approver.

resource_id

ID of the resource this annotation belongs to.

associated_file

Path or identifier of any associated file artifact.

deleted

Whether the annotation is marked as deleted.

deleted_at

Optional ISO timestamp for deletion time.

deleted_by

Optional identifier of the user who deleted the annotation.

created_by_model

Optional identifier of the model that created this annotation.

old_geometry

Optional previous geometry payload for change tracking.

set_name

Optional set name this annotation belongs to.

resource_filename

Optional filename of the resource.

resource_modality

Optional modality of the resource (e.g., CT, MR).

annotation_worklist_name

Optional worklist name associated with the annotation.

user_info

Optional user information with keys like firstname and lastname.

values

Optional extra values payload for flexible schemas.

property added_by: str

Get the creator email (alias for created_by).

annotation_worklist_id: str | None
annotation_worklist_name: str | None
approved_at: str | None
approved_by: str | None
associated_file: str | None
created_at: str | None
created_by: str | None
created_by_model: str | None
deleted: bool
deleted_at: str | None
deleted_by: str | None
fetch_file_data(auto_convert=True, save_path=None, use_cache=False)
Overloads:
  • self, auto_convert (Literal[True]), save_path (str | None), use_cache (CacheMode) → ImagingData

  • self, auto_convert (Literal[False]), save_path (str | None), use_cache (CacheMode) → bytes

Get the file data for this annotation.

Parameters:
  • save_path (str | None) – Optional path to save the file locally. If use_cache=True, the file is saved to save_path and cache metadata points to that location (no duplication - only one file on disk).

  • auto_convert (bool) – If True, automatically converts to appropriate format

  • use_cache (bool | Literal['loadonly']) – Cache behavior for this call. Use False to bypass cache entirely, True to read from and save to cache, or "loadonly" to read from cache without saving cache misses.

Returns:

File data (format depends on auto_convert and file type)

Return type:

bytes | ImagingData

Example

>>> annotation = api.annotations.get_list(limit=1)[0]
>>> data = annotation.fetch_file_data(use_cache=True)
>>> data = annotation.fetch_file_data(use_cache="loadonly")
>>> annotation.fetch_file_data(save_path="annotation_file")
file: str | None
frame_index: int | None
classmethod from_dict(data)

Create an Annotation instance from a dictionary.

Parameters:

data (dict[str, Any]) – Dictionary containing annotation data from API

Return type:

Annotation

Returns:

Annotation instance

geometry: list | dict | None
get_created_datetime()

Get the creation datetime as a datetime object.

Return type:

datetime | None

Returns:

datetime object or None if created_at is not set

id: str | None
identifier: str
import_author: str | None
imported_from: str | None
property index: int | None

Get the frame index (alias for frame_index).

invalidate_cache()

Invalidate all cached data for this annotation.

Return type:

None

is_cached()

Check if the resource’s file data is already cached locally and valid.

Return type:

bool

Returns:

True if valid cached data exists, False otherwise.

is_frame_scoped()

Check if this annotation is frame-scoped.

Return type:

bool

is_image_scoped()

Check if this annotation is image-scoped.

Return type:

bool

is_model: bool | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_id: str | None
model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

numeric_value: float | int | None
property resource: Resource

Lazily load and cache the associated Resource entity.

Example

>>> annotation = api.annotations.get_list(limit=1)[0]
>>> annotation.resource.filename
resource_filename: str | None
resource_id: str | None
resource_modality: str | None
scope: str
set_name: str | None
status: str | None
text_value: str | None
property type: str

Alias for annotation_type.

units: str | None
user_info: dict | None
property value: str | None

Get the annotation value (for category annotations).

values: list | None

Annotation Specification

class datamint.entities.annotations.annotation_spec.AnnotationSpec(**data)

Bases: BaseModel

Base class for annotation specifications. Used by the API to define the expected structure of annotations for a given project.

Parameters:

data (Any)

asdict()

Convert the entity to a dictionary, including unknown fields.

asjson()

Convert the entity to a JSON string, including unknown fields.

Return type:

str

classmethod create(**kwargs)

Factory method to create the appropriate AnnotationSpec subclass based on type.

Return type:

AnnotationSpec

identifier: str
model_config: ClassVar[ConfigDict] = {'extra': 'allow', 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

required: bool
scope: str
type: AnnotationType

Segmentation Annotations

Base segmentation annotation module for DataMint API.

Provides shared serialisation helpers and BaseSegmentationAnnotation that is extended by ImageSegmentation and VolumeSegmentation.

class datamint.entities.annotations.base_segmentation.BaseSegmentationAnnotation(segmentation_data=None, mask=None, **kwargs)

Bases: Annotation

Common base for 2-D and 3-D segmentation annotation entities.

Provides:

  • A Pydantic-native segmentation_data field with automatic serialisation/deserialisation for np.ndarray, PIL.Image.Image and nibabel.nifti1.Nifti1Image.

  • An overridden fetch_file_data() that short-circuits the network call when segmentation_data is already populated in memory.

  • Static helpers _to_raw_bytes() and _from_raw_bytes() for subclasses that need to convert to/from bytes.

Parameters:
  • segmentation_data (ndarray | Image | None)

  • mask (ndarray | Image | None)

fetch_file_data(auto_convert=True, save_path=None, use_cache=False)
Overloads:
  • self, auto_convert (Literal[True]), save_path (str | None), use_cache (CacheMode) → ImagingData

  • self, auto_convert (Literal[False]), save_path (str | None), use_cache (CacheMode) → bytes

Return segmentation file data.

If segmentation_data is already loaded (e.g. created via a factory class-method) the data is returned directly without hitting the network. Otherwise the parent Annotation implementation downloads the file from the server.

Parameters:
  • auto_convert (bool) – When True return the native Python / numpy object; when False return raw bytes (NIfTI-encoded for volumes, PNG-encoded for 2-D images).

  • save_path (str | None) – Optional path to persist the data on disk.

  • use_cache (CacheMode) – Cache behavior for this call. Use False to bypass cache entirely, True to read from and save to cache, or "loadonly" to read from cache without saving cache misses.

Returns:

Segmentation data as a native object (when auto_convert is True) or bytes.

Return type:

bytes | ImagingData

property mask: ndarray | Image | Any | None

Alias for segmentation_data.

property mask_shape: tuple[int, ...] | None

Shape of the stored mask.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

segmentation_data: Annotated[ndarray | Image | Any | None, BeforeValidator(func=_deserialize_segmentation_data, json_schema_input_type=PydanticUndefined), PlainSerializer(func=_serialize_segmentation_data, return_type=dict | None, when_used=always), FieldInfo(annotation=NoneType, required=True, alias='mask', alias_priority=2)]

Image segmentation annotation entity module for DataMint API.

This module defines the ImageSegmentation class for representing 2D binary segmentation annotations in medical images.

class datamint.entities.annotations.image_segmentation.ImageSegmentation(segmentation_data=None, **kwargs)

Bases: BaseSegmentationAnnotation

Image-level (2-D) binary segmentation annotation entity.

Represents a binary segmentation mask (foreground / background) for a single image. The stored mask always contains only 0 and 1 values; any non-zero input pixel is normalised to 1.

Parameters:
  • segmentation_data (ndarray | Image | None) – The mask as a np.ndarray (dtype=uint8), PIL.Image.Image, or nibabel.nifti1.Nifti1Image. Automatically serialised/deserialised on persist/load.

  • name (str) – The annotation class label (stored in the inherited identifier field).

Example

>>> mask = np.zeros((256, 256), dtype=np.uint8)
>>> mask[100:150, 100:150] = 1  # foreground region
>>> img_seg = ImageSegmentation.from_mask(mask=mask, name='lesion')
>>> img_seg.name
'lesion'
get_area()

Return the number of foreground (non-zero) pixels in the mask.

Return type:

int | None

Returns:

Foreground pixel count or None if no mask is stored.

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

to_pil_image()

Convert the mask to a PIL Image.

Return type:

Image | None

Returns:

PIL.Image.Image or None if no mask is stored.

Volume segmentation annotation entity module for DataMint API.

This module defines the VolumeSegmentation class for representing 3D segmentation annotations in medical imaging volumes.

class datamint.entities.annotations.volume_segmentation.VolumeSegmentation(*, id=None, name, scope, annotation_type, confiability=1.0, frame_index=None, text_value=None, numeric_value=None, units=None, geometry=None, created_at=None, created_by=None, annotation_worklist_id=None, imported_from=None, import_author=None, status=None, approved_at=None, approved_by=None, resource_id=None, associated_file=None, deleted=False, deleted_at=None, deleted_by=None, created_by_model=None, is_model=None, model_id=None, set_name=None, resource_filename=None, resource_modality=None, annotation_worklist_name=None, user_info=None, values='MISSING_FIELD', file=None, mask=None, class_map=None, **kwargs)

Bases: BaseSegmentationAnnotation

Volume-level segmentation annotation entity.

Represents a 3-D segmentation mask for medical imaging volumes. Supports both semantic segmentation (class per voxel) and instance segmentation (unique ID per object).

This class provides factory methods to create annotations from numpy arrays or NIfTI images, which can then be uploaded via AnnotationsApi.

Example

>>> # From semantic segmentation
>>> seg_data = np.array([...])  # Shape: (H, W, D)
>>> class_map = {1: 'tumor', 2: 'edema'}
>>> vol_seg = VolumeSegmentation.from_semantic_segmentation(
...     segmentation=seg_data,
...     class_map=class_map
... )
>>>
>>> # Upload via API
>>> api.annotations.upload_segmentations(
...     resource='resource_id',
...     file_path=vol_seg.segmentation_data,
...     name=vol_seg.class_map
... )
class_map: dict[int, str] | None
property class_names: list[str] | None

Get list of class names from stored class_map.

Returns:

List of class names or None if no class_map stored

classmethod from_semantic_segmentation(segmentation, class_map, **kwargs)

Create VolumeSegmentation from semantic segmentation data.

Semantic segmentation: each voxel has a single integer label corresponding to its class.

Parameters:
  • segmentation (ndarray | Nifti1Image) – 3D numpy array (H x W x D) or NIfTI image with integer labels representing classes

  • class_map (dict[int, str] | str) – Mapping from label integers to class names, or a single class name for binary segmentation (background=0, class=1)

  • **kwargs – Additional annotation fields (imported_from, model_id, etc.)

Return type:

VolumeSegmentation

Returns:

VolumeSegmentation instance ready for upload

Raises:

ValueError – If segmentation shape is invalid, class_map is incomplete, or data types are incorrect

Example

>>> seg = np.zeros((256, 256, 128), dtype=np.int32)
>>> seg[100:150, 100:150, 50:75] = 1  # tumor region
>>> vol_seg = VolumeSegmentation.from_semantic_segmentation(
...     segmentation=seg,
...     class_map={1: 'tumor'}, # or just ``class_map='tumor'``
... )
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

property num_classes: int | None

Get number of classes in this segmentation.

Returns:

Number of classes or None if no class_map stored

property volume_shape: tuple[int, int, int] | None

Get the shape of the stored segmentation volume.

Returns:

Shape tuple (H, W, D) or None if no data stored

Geometry Annotations

class datamint.entities.annotations.base_geometry.BaseGeometryAnnotation(geometry=None, **kwargs)

Bases: Annotation

Base entity for typed geometry annotations.

Parameters:
  • geometry (Geometry | dict[str, Any] | None)

  • kwargs (Any)

geometry: Geometry | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

class datamint.entities.annotations.box_annotation.BoxAnnotation(geometry=None, **kwargs)

Bases: BaseGeometryAnnotation

Typed box annotation entity.

Parameters:
  • geometry (BoxGeometry | dict[str, Any] | None)

  • kwargs (Any)

classmethod from_points(point1, point2, *, identifier, frame_index=None, metadata=None, coords_system='pixel', **kwargs)
Parameters:
  • point1 (tuple[int, int] | tuple[float, float, float])

  • point2 (tuple[int, int] | tuple[float, float, float])

  • identifier (str)

  • frame_index (int | None)

  • metadata (Dataset | Nifti1Image | None)

  • coords_system (Literal['pixel', 'patient'])

  • kwargs (Any)

Return type:

BoxAnnotation

geometry: BoxGeometry | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

class datamint.entities.annotations.box_annotation.BoxGeometry(**data)

Bases: Geometry

Parameters:

data (Any)

classmethod from_coordinates(point1, point2, *, coords_system='pixel', slice_plane=None, frame_index=None, metadata=None)
Parameters:
  • point1 (tuple[int, int] | tuple[float, float, float])

  • point2 (tuple[int, int] | tuple[float, float, float])

  • coords_system (Literal['pixel', 'patient'])

  • slice_plane (Literal['axial', 'sagittal', 'coronal'] | None)

  • frame_index (int | None)

  • metadata (Dataset | Nifti1Image | None)

Return type:

BoxGeometry

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

property point1: tuple[int | float, int | float, int | float]
property point2: tuple[int | float, int | float, int | float]
points: tuple[tuple[int | float, int | float, int | float], tuple[int | float, int | float, int | float], tuple[int | float, int | float, int | float], tuple[int | float, int | float, int | float]]
type: ClassVar[str] = 'square'
class datamint.entities.annotations.line_annotation.LineAnnotation(geometry=None, **kwargs)

Bases: BaseGeometryAnnotation

Typed line annotation entity.

Parameters:
  • geometry (LineGeometry | dict[str, Any] | None)

  • kwargs (Any)

classmethod from_points(point1, point2, *, identifier, frame_index=None, slice_plane=None, metadata=None, coords_system='pixel', **kwargs)
Parameters:
  • point1 (tuple[int, int] | tuple[float, float, float])

  • point2 (tuple[int, int] | tuple[float, float, float])

  • identifier (str)

  • frame_index (int | None)

  • slice_plane (Literal['axial', 'sagittal', 'coronal'] | None)

  • metadata (Dataset | Nifti1Image | None)

  • coords_system (Literal['pixel', 'patient'])

  • kwargs (Any)

Return type:

LineAnnotation

geometry: LineGeometry | None
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

class datamint.entities.annotations.line_annotation.LineGeometry(**data)

Bases: _TwoPointGeometry

Parameters:

data (Any)

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

type: ClassVar[str] = 'line'
class datamint.entities.annotations.geometry.Geometry(**data)

Bases: BaseModel

Base geometry payload for annotation entities.

Parameters:

data (Any)

coordinate_system: Literal['pixel', 'patient']
model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'ignore'}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

to_dict()
Return type:

dict[str, Any]

type: ClassVar[str]
viewPlaneNormal: tuple[float, float, float] | None
viewUp: tuple[float, float, float] | None

Classification Annotations

class datamint.entities.annotations.image_classification.ImageClassification(name=None, value=None, confiability=1.0, **kwargs)

Bases: Annotation

Parameters:
  • name (str | None)

  • value (str | None)

  • confiability (float)

  • kwargs (Any)

model_config: ClassVar[ConfigDict] = {'arbitrary_types_allowed': True, 'extra': 'allow', 'populate_by_name': True, 'ser_json_bytes': 'base64', 'val_json_bytes': 'base64', 'validate_by_alias': True, 'validate_by_name': True}

Configuration for the model, should be a dictionary conforming to [ConfigDict][pydantic.config.ConfigDict].

model_post_init(_BaseEntityModel__context)

Handle unknown fields by logging a warning once per class/field combination in debug mode.

Parameters:

_BaseEntityModel__context (Any)

Return type:

None

Annotation Types

class datamint.entities.annotations.types.AnnotationType(*values)
ANGLE = 'angle'
AREA = 'area'
CATEGORY = 'category'
CIRCLE = 'circle'
DISTANCE = 'distance'
LABEL = 'label'
LINE = 'line'
POINT = 'point'
REGION = 'region'
SEGMENTATION = 'segmentation'
SQUARE = 'square'

Factory Function

datamint.entities.annotations.annotation_from_dict(data)

Factory: map a raw annotation dict to the appropriate Annotation subclass.

Dispatches on annotation_type:

segmentation_data dicts are automatically deserialised by the Pydantic BeforeValidator defined on BaseSegmentationAnnotation. class_map string keys (produced by JSON serialisation) are coerced to int by Pydantic’s lax validation.

Parameters:

data (dict) – Raw annotation dict as returned by the API.

Return type:

Annotation

Returns:

A concrete Annotation subclass instance.