lightly-studio 0.3.1__py3-none-any.whl → 0.3.3__py3-none-any.whl

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 lightly-studio might be problematic. Click here for more details.

Files changed (169) hide show
  1. lightly_studio/__init__.py +4 -4
  2. lightly_studio/api/app.py +7 -5
  3. lightly_studio/api/db_tables.py +0 -3
  4. lightly_studio/api/routes/api/annotation.py +32 -16
  5. lightly_studio/api/routes/api/annotation_label.py +2 -5
  6. lightly_studio/api/routes/api/annotations/__init__.py +7 -0
  7. lightly_studio/api/routes/api/annotations/create_annotation.py +52 -0
  8. lightly_studio/api/routes/api/classifier.py +2 -5
  9. lightly_studio/api/routes/api/dataset.py +5 -8
  10. lightly_studio/api/routes/api/dataset_tag.py +2 -3
  11. lightly_studio/api/routes/api/embeddings2d.py +104 -0
  12. lightly_studio/api/routes/api/export.py +73 -0
  13. lightly_studio/api/routes/api/metadata.py +2 -4
  14. lightly_studio/api/routes/api/sample.py +5 -13
  15. lightly_studio/api/routes/api/selection.py +87 -0
  16. lightly_studio/api/routes/api/settings.py +2 -6
  17. lightly_studio/api/routes/images.py +6 -6
  18. lightly_studio/core/add_samples.py +374 -0
  19. lightly_studio/core/dataset.py +272 -400
  20. lightly_studio/core/dataset_query/boolean_expression.py +67 -0
  21. lightly_studio/core/dataset_query/dataset_query.py +216 -0
  22. lightly_studio/core/dataset_query/field.py +113 -0
  23. lightly_studio/core/dataset_query/field_expression.py +79 -0
  24. lightly_studio/core/dataset_query/match_expression.py +23 -0
  25. lightly_studio/core/dataset_query/order_by.py +79 -0
  26. lightly_studio/core/dataset_query/sample_field.py +28 -0
  27. lightly_studio/core/dataset_query/tags_expression.py +46 -0
  28. lightly_studio/core/sample.py +159 -32
  29. lightly_studio/core/start_gui.py +35 -0
  30. lightly_studio/dataset/edge_embedding_generator.py +13 -8
  31. lightly_studio/dataset/embedding_generator.py +2 -3
  32. lightly_studio/dataset/embedding_manager.py +74 -6
  33. lightly_studio/dataset/env.py +4 -0
  34. lightly_studio/dataset/file_utils.py +13 -2
  35. lightly_studio/dataset/fsspec_lister.py +275 -0
  36. lightly_studio/dataset/loader.py +49 -84
  37. lightly_studio/dataset/mobileclip_embedding_generator.py +9 -6
  38. lightly_studio/db_manager.py +145 -0
  39. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/0.CA_CXIBb.css +1 -0
  40. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.DS78jgNY.css +1 -0
  41. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/index.BVs_sZj9.css +1 -0
  42. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/transform.D487hwJk.css +1 -0
  43. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/6t3IJ0vQ.js +1 -0
  44. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{D6su9Aln.js → 8NsknIT2.js} +1 -1
  45. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{x9G_hzyY.js → BND_-4Kp.js} +1 -1
  46. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{BylOuP6i.js → BdfTHw61.js} +1 -1
  47. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{DOlTMNyt.js → BfHVnyNT.js} +1 -1
  48. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BjkP1AHA.js +1 -0
  49. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BuuNVL9G.js +1 -0
  50. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{O-EABkf9.js → BzKGpnl4.js} +1 -1
  51. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CCx7Ho51.js +1 -0
  52. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{l7KrR96u.js → CH6P3X75.js} +1 -1
  53. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{D5-A_Ffd.js → CR2upx_Q.js} +2 -2
  54. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CWPZrTTJ.js +1 -0
  55. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{C8I8rFJQ.js → Cs1XmhiF.js} +1 -1
  56. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{CDnpyLsT.js → CwPowJfP.js} +1 -1
  57. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CxFKfZ9T.js +1 -0
  58. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cxevwdid.js +1 -0
  59. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{DjfY96ND.js → D4whDBUi.js} +1 -1
  60. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D6r9vr07.js +1 -0
  61. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DA6bFLPR.js +1 -0
  62. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DEgUu98i.js +3 -0
  63. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DGTPl6Gk.js +1 -0
  64. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DKGxBSlK.js +1 -0
  65. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DQXoLcsF.js +1 -0
  66. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DQe_kdRt.js +92 -0
  67. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DcY4jgG3.js +1 -0
  68. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{Bu7uvVrG.js → RmD8FzRo.js} +1 -1
  69. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/V-MnMC1X.js +1 -0
  70. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{Bsi3UGy5.js → keKYsoph.js} +1 -1
  71. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.BVr6DYqP.js +2 -0
  72. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.u7zsVvqp.js +1 -0
  73. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.Da2agmdd.js +1 -0
  74. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{1.B4rNYwVp.js → 1.B11tVRJV.js} +1 -1
  75. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.l30Zud4h.js +1 -0
  76. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.CgKPGcAP.js +1 -0
  77. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.C8HLK8mj.js +857 -0
  78. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{3.CWHpKonm.js → 3.CLvg3QcJ.js} +1 -1
  79. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{4.OUWOLQeV.js → 4.BQhDtXUI.js} +1 -1
  80. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.-6XqWX5G.js +1 -0
  81. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/6.uBV1Lhat.js +1 -0
  82. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.BXsgoQZh.js +1 -0
  83. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.BkbcnUs8.js +1 -0
  84. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{9.CPu3CiBc.js → 9.Bkrv-Vww.js} +1 -1
  85. lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/clustering.worker-DKqeLtG0.js +2 -0
  86. lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/search.worker-vNSty3B0.js +1 -0
  87. lightly_studio/dist_lightly_studio_view_app/_app/version.json +1 -1
  88. lightly_studio/dist_lightly_studio_view_app/index.html +14 -14
  89. lightly_studio/examples/example.py +13 -12
  90. lightly_studio/examples/example_coco.py +13 -0
  91. lightly_studio/examples/example_metadata.py +83 -98
  92. lightly_studio/examples/example_selection.py +7 -19
  93. lightly_studio/examples/example_split_work.py +12 -36
  94. lightly_studio/examples/{example_v2.py → example_yolo.py} +3 -4
  95. lightly_studio/export/export_dataset.py +65 -0
  96. lightly_studio/export/lightly_studio_label_input.py +120 -0
  97. lightly_studio/few_shot_classifier/classifier_manager.py +5 -26
  98. lightly_studio/metadata/compute_typicality.py +67 -0
  99. lightly_studio/models/annotation/annotation_base.py +18 -20
  100. lightly_studio/models/annotation/instance_segmentation.py +8 -8
  101. lightly_studio/models/annotation/object_detection.py +4 -4
  102. lightly_studio/models/dataset.py +6 -2
  103. lightly_studio/models/sample.py +10 -3
  104. lightly_studio/resolvers/annotation_label_resolver/__init__.py +2 -1
  105. lightly_studio/resolvers/annotation_label_resolver/get_all.py +15 -0
  106. lightly_studio/resolvers/annotation_resolver/__init__.py +2 -3
  107. lightly_studio/resolvers/annotation_resolver/create_many.py +3 -3
  108. lightly_studio/resolvers/annotation_resolver/delete_annotation.py +1 -1
  109. lightly_studio/resolvers/annotation_resolver/delete_annotations.py +7 -3
  110. lightly_studio/resolvers/annotation_resolver/get_by_id.py +19 -1
  111. lightly_studio/resolvers/annotation_resolver/update_annotation_label.py +0 -1
  112. lightly_studio/resolvers/annotations/annotations_filter.py +1 -11
  113. lightly_studio/resolvers/dataset_resolver.py +10 -0
  114. lightly_studio/resolvers/embedding_model_resolver.py +22 -0
  115. lightly_studio/resolvers/sample_resolver.py +53 -9
  116. lightly_studio/resolvers/tag_resolver.py +23 -0
  117. lightly_studio/selection/mundig.py +7 -10
  118. lightly_studio/selection/select.py +55 -46
  119. lightly_studio/selection/select_via_db.py +23 -19
  120. lightly_studio/selection/selection_config.py +10 -4
  121. lightly_studio/services/annotations_service/__init__.py +12 -0
  122. lightly_studio/services/annotations_service/create_annotation.py +63 -0
  123. lightly_studio/services/annotations_service/delete_annotation.py +22 -0
  124. lightly_studio/services/annotations_service/update_annotation.py +21 -32
  125. lightly_studio/services/annotations_service/update_annotation_bounding_box.py +36 -0
  126. lightly_studio-0.3.3.dist-info/METADATA +814 -0
  127. {lightly_studio-0.3.1.dist-info → lightly_studio-0.3.3.dist-info}/RECORD +130 -113
  128. lightly_studio/api/db.py +0 -133
  129. lightly_studio/api/routes/api/annotation_task.py +0 -38
  130. lightly_studio/api/routes/api/metrics.py +0 -80
  131. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/0.DenzbfeK.css +0 -1
  132. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.OwPEPQZu.css +0 -1
  133. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.b653GmVf.css +0 -1
  134. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.T-zjSUd3.css +0 -1
  135. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/B2FVR0s0.js +0 -1
  136. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/B9zumHo5.js +0 -1
  137. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BJXwVxaE.js +0 -1
  138. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Bx1xMsFy.js +0 -1
  139. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CcaPhhk3.js +0 -1
  140. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CvOmgdoc.js +0 -93
  141. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CxtLVaYz.js +0 -3
  142. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D6RI2Zrd.js +0 -1
  143. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D98V7j6A.js +0 -1
  144. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DIRAtgl0.js +0 -1
  145. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DjUWrjOv.js +0 -1
  146. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/XO7A28GO.js +0 -1
  147. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/hQVEETDE.js +0 -1
  148. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/nAHhluT7.js +0 -1
  149. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/r64xT6ao.js +0 -1
  150. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/vC4nQVEB.js +0 -1
  151. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.CjnvpsmS.js +0 -2
  152. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.0o1H7wM9.js +0 -1
  153. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.XRq_TUwu.js +0 -1
  154. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.DfBwOEhN.js +0 -1
  155. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.CwF2_8mP.js +0 -1
  156. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.CS4muRY-.js +0 -6
  157. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.Dm6t9F5W.js +0 -1
  158. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/6.Bw5ck4gK.js +0 -1
  159. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.CF0EDTR6.js +0 -1
  160. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.Cw30LEcV.js +0 -1
  161. lightly_studio/metrics/detection/__init__.py +0 -0
  162. lightly_studio/metrics/detection/map.py +0 -268
  163. lightly_studio/models/annotation_task.py +0 -28
  164. lightly_studio/resolvers/annotation_resolver/create.py +0 -19
  165. lightly_studio/resolvers/annotation_task_resolver.py +0 -31
  166. lightly_studio-0.3.1.dist-info/METADATA +0 -520
  167. /lightly_studio/{metrics → core/dataset_query}/__init__.py +0 -0
  168. /lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/{OpenSans- → OpenSans-Medium.DVUZMR_6.ttf} +0 -0
  169. {lightly_studio-0.3.1.dist-info → lightly_studio-0.3.3.dist-info}/WHEEL +0 -0
@@ -2,21 +2,19 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
+ from typing import Literal, Sequence
5
6
  from uuid import UUID
6
7
 
7
8
  from pydantic import BaseModel
8
9
 
9
- from lightly_studio.resolvers.samples_filter import SampleFilter
10
-
11
10
 
12
11
  class SelectionConfig(BaseModel):
13
12
  """Configuration for the selection process."""
14
13
 
15
14
  dataset_id: UUID
16
- sample_filter: SampleFilter | None = None
17
15
  n_samples_to_select: int
18
16
  selection_result_tag_name: str
19
- strategies: list[SelectionStrategy]
17
+ strategies: Sequence[SelectionStrategy]
20
18
 
21
19
 
22
20
  class SelectionStrategy(BaseModel):
@@ -28,4 +26,12 @@ class SelectionStrategy(BaseModel):
28
26
  class EmbeddingDiversityStrategy(SelectionStrategy):
29
27
  """Selection strategy based on embedding diversity."""
30
28
 
29
+ strategy_name: Literal["diversity"] = "diversity"
31
30
  embedding_model_name: str | None
31
+
32
+
33
+ class MetadataWeightingStrategy(SelectionStrategy):
34
+ """Selection strategy based on metadata weighting."""
35
+
36
+ strategy_name: Literal["weights"] = "weights"
37
+ metadata_key: str
@@ -1,11 +1,20 @@
1
1
  """Services for annotations operations."""
2
2
 
3
+ from lightly_studio.services.annotations_service.create_annotation import (
4
+ create_annotation,
5
+ )
6
+ from lightly_studio.services.annotations_service.delete_annotation import (
7
+ delete_annotation,
8
+ )
3
9
  from lightly_studio.services.annotations_service.get_annotation_by_id import (
4
10
  get_annotation_by_id,
5
11
  )
6
12
  from lightly_studio.services.annotations_service.update_annotation import (
7
13
  update_annotation,
8
14
  )
15
+ from lightly_studio.services.annotations_service.update_annotation_bounding_box import (
16
+ update_annotation_bounding_box,
17
+ )
9
18
  from lightly_studio.services.annotations_service.update_annotation_label import (
10
19
  update_annotation_label,
11
20
  )
@@ -14,8 +23,11 @@ from lightly_studio.services.annotations_service.update_annotations import (
14
23
  )
15
24
 
16
25
  __all__ = [
26
+ "create_annotation",
27
+ "delete_annotation",
17
28
  "get_annotation_by_id",
18
29
  "update_annotation",
30
+ "update_annotation_bounding_box",
19
31
  "update_annotation_label",
20
32
  "update_annotations",
21
33
  ]
@@ -0,0 +1,63 @@
1
+ """Create annotation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from uuid import UUID
6
+
7
+ from pydantic import BaseModel
8
+ from sqlmodel import Session
9
+
10
+ from lightly_studio.models.annotation.annotation_base import (
11
+ AnnotationBaseTable,
12
+ AnnotationCreate,
13
+ AnnotationType,
14
+ )
15
+ from lightly_studio.resolvers import annotation_resolver
16
+
17
+
18
+ class AnnotationCreateParams(BaseModel):
19
+ """Input model for create annotation service."""
20
+
21
+ annotation_label_id: UUID
22
+ annotation_type: AnnotationType
23
+ dataset_id: UUID
24
+ sample_id: UUID
25
+
26
+ x: int | None = None
27
+ y: int | None = None
28
+ width: int | None = None
29
+ height: int | None = None
30
+
31
+ segmentation_mask: list[int] | None = None
32
+
33
+
34
+ def create_annotation(session: Session, annotation: AnnotationCreateParams) -> AnnotationBaseTable:
35
+ """Create a new annotation.
36
+
37
+ Args:
38
+ session: Database session for executing the operation.
39
+ annotation: Annotation data to create.
40
+
41
+ Returns:
42
+ The retrieved annotation.
43
+ """
44
+ annotation_create = AnnotationCreate(
45
+ **annotation.model_dump(),
46
+ )
47
+ new_annotation_ids = annotation_resolver.create_many(
48
+ session=session,
49
+ annotations=[annotation_create],
50
+ )
51
+
52
+ if not new_annotation_ids:
53
+ raise ValueError("Failed to create annotation.")
54
+
55
+ created_annotation = annotation_resolver.get_by_id(
56
+ session=session,
57
+ annotation_id=new_annotation_ids[0],
58
+ )
59
+
60
+ if created_annotation is None:
61
+ raise ValueError(f"Failed to create annotation: {annotation}")
62
+
63
+ return created_annotation
@@ -0,0 +1,22 @@
1
+ """Delete an annotation by its ID."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from uuid import UUID
6
+
7
+ from sqlmodel import Session
8
+
9
+ from lightly_studio.resolvers import annotation_resolver
10
+
11
+
12
+ def delete_annotation(session: Session, annotation_id: UUID) -> None:
13
+ """Delete an annotation by its ID.
14
+
15
+ Args:
16
+ session: Database session for executing the operation.
17
+ annotation_id: ID of the annotation to delete.
18
+
19
+ Raises:
20
+ ValueError: If the annotation with the given ID is not found.
21
+ """
22
+ annotation_resolver.delete_annotation(session=session, annotation_id=annotation_id)
@@ -10,6 +10,7 @@ from sqlmodel import Session
10
10
  from lightly_studio.models.annotation.annotation_base import (
11
11
  AnnotationBaseTable,
12
12
  )
13
+ from lightly_studio.resolvers.annotation_resolver.update_bounding_box import BoundingBoxCoordinates
13
14
  from lightly_studio.services import annotations_service
14
15
 
15
16
 
@@ -18,11 +19,8 @@ class AnnotationUpdate(BaseModel):
18
19
 
19
20
  annotation_id: UUID
20
21
  dataset_id: UUID
21
- label_name: str | None
22
- x: int | None = None
23
- y: int | None = None
24
- width: int | None = None
25
- height: int | None = None
22
+ label_name: str | None = None
23
+ bounding_box: BoundingBoxCoordinates | None = None
26
24
 
27
25
 
28
26
  def update_annotation(session: Session, annotation_update: AnnotationUpdate) -> AnnotationBaseTable:
@@ -36,30 +34,21 @@ def update_annotation(session: Session, annotation_update: AnnotationUpdate) ->
36
34
  The updated annotation.
37
35
 
38
36
  """
39
- if annotation_update.label_name is None:
40
- raise ValueError("Label name must be provided for updating annotation")
41
-
42
- # comment this out for now so e2e tests will pass
43
- # todo: uncomment after passing bbox coordinates on update from frontend
44
- # annotation=get_annotation_by_id(session,annotation_update.annotation_id)
45
- # if annotation.annotation_type in (
46
- # AnnotationType.OBJECT_DETECTION,
47
- # AnnotationType.INSTANCE_SEGMENTATION,
48
- # ) and any(
49
- # [
50
- # annotation_update.x is None,
51
- # annotation_update.y is None,
52
- # annotation_update.width is None,
53
- # annotation_update.height is None,
54
- # ]
55
- # ):
56
- # raise ValueError(
57
- # "All bounding box coordinates (x, y, width, height) "
58
- # "must be provided for updating this annotation type"
59
- # )
60
-
61
- return annotations_service.update_annotation_label(
62
- session,
63
- annotation_update.annotation_id,
64
- annotation_update.label_name,
65
- )
37
+ result = None
38
+ if annotation_update.label_name is not None:
39
+ result = annotations_service.update_annotation_label(
40
+ session,
41
+ annotation_update.annotation_id,
42
+ annotation_update.label_name,
43
+ )
44
+
45
+ if annotation_update.bounding_box is not None:
46
+ result = annotations_service.update_annotation_bounding_box(
47
+ session,
48
+ annotation_update.annotation_id,
49
+ bounding_box=annotation_update.bounding_box,
50
+ )
51
+
52
+ if result is None:
53
+ raise ValueError("No updates provided for the annotation.")
54
+ return result
@@ -0,0 +1,36 @@
1
+ """Update the bounding box of an annotation."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from uuid import UUID
6
+
7
+ from sqlmodel import Session
8
+
9
+ from lightly_studio.models.annotation.annotation_base import (
10
+ AnnotationBaseTable,
11
+ )
12
+ from lightly_studio.resolvers import (
13
+ annotation_resolver,
14
+ )
15
+ from lightly_studio.resolvers.annotation_resolver.update_bounding_box import BoundingBoxCoordinates
16
+
17
+
18
+ def update_annotation_bounding_box(
19
+ session: Session, annotation_id: UUID, bounding_box: BoundingBoxCoordinates
20
+ ) -> AnnotationBaseTable:
21
+ """Update the bounding box of an annotation.
22
+
23
+ Args:
24
+ session: Database session for executing the operation.
25
+ annotation_id: UUID of the annotation to update.
26
+ bounding_box: New bounding box coordinates to assign to the annotation.
27
+
28
+ Returns:
29
+ The updated annotation with the new bounding box assigned.
30
+
31
+ """
32
+ return annotation_resolver.update_bounding_box(
33
+ session,
34
+ annotation_id,
35
+ bounding_box,
36
+ )