lightly-studio 0.3.1__py3-none-any.whl → 0.3.2__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 (133) hide show
  1. lightly_studio/__init__.py +4 -4
  2. lightly_studio/api/app.py +1 -1
  3. lightly_studio/api/routes/api/annotation.py +6 -16
  4. lightly_studio/api/routes/api/annotation_label.py +2 -5
  5. lightly_studio/api/routes/api/annotation_task.py +4 -5
  6. lightly_studio/api/routes/api/classifier.py +2 -5
  7. lightly_studio/api/routes/api/dataset.py +2 -3
  8. lightly_studio/api/routes/api/dataset_tag.py +2 -3
  9. lightly_studio/api/routes/api/metadata.py +2 -4
  10. lightly_studio/api/routes/api/metrics.py +2 -6
  11. lightly_studio/api/routes/api/sample.py +5 -13
  12. lightly_studio/api/routes/api/settings.py +2 -6
  13. lightly_studio/api/routes/images.py +6 -6
  14. lightly_studio/core/add_samples.py +383 -0
  15. lightly_studio/core/dataset.py +250 -362
  16. lightly_studio/core/dataset_query/__init__.py +0 -0
  17. lightly_studio/core/dataset_query/boolean_expression.py +67 -0
  18. lightly_studio/core/dataset_query/dataset_query.py +211 -0
  19. lightly_studio/core/dataset_query/field.py +113 -0
  20. lightly_studio/core/dataset_query/field_expression.py +79 -0
  21. lightly_studio/core/dataset_query/match_expression.py +23 -0
  22. lightly_studio/core/dataset_query/order_by.py +79 -0
  23. lightly_studio/core/dataset_query/sample_field.py +28 -0
  24. lightly_studio/core/dataset_query/tags_expression.py +46 -0
  25. lightly_studio/core/sample.py +159 -32
  26. lightly_studio/core/start_gui.py +35 -0
  27. lightly_studio/dataset/edge_embedding_generator.py +13 -8
  28. lightly_studio/dataset/embedding_generator.py +2 -3
  29. lightly_studio/dataset/embedding_manager.py +74 -6
  30. lightly_studio/dataset/fsspec_lister.py +275 -0
  31. lightly_studio/dataset/loader.py +49 -30
  32. lightly_studio/dataset/mobileclip_embedding_generator.py +6 -4
  33. lightly_studio/db_manager.py +145 -0
  34. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.BBm0IWdq.css +1 -0
  35. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.BNTuXSAe.css +1 -0
  36. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/2O287xak.js +3 -0
  37. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{O-EABkf9.js → 7YNGEs1C.js} +1 -1
  38. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BBoGk9hq.js +1 -0
  39. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BRnH9v23.js +92 -0
  40. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Bg1Y5eUZ.js +1 -0
  41. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{DOlTMNyt.js → BqBqV92V.js} +1 -1
  42. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C0JiMuYn.js +1 -0
  43. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{DjfY96ND.js → C98Hk3r5.js} +1 -1
  44. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{r64xT6ao.js → CG0dMCJi.js} +1 -1
  45. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{C8I8rFJQ.js → Ccq4ZD0B.js} +1 -1
  46. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cpy-nab_.js +1 -0
  47. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{Bu7uvVrG.js → Crk-jcvV.js} +1 -1
  48. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Cs31G8Qn.js +1 -0
  49. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CsKrY2zA.js +1 -0
  50. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{x9G_hzyY.js → Cur71c3O.js} +1 -1
  51. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CzgC3GFB.js +1 -0
  52. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D8GZDMNN.js +1 -0
  53. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DFRh-Spp.js +1 -0
  54. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{BylOuP6i.js → DRZO-E-T.js} +1 -1
  55. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{l7KrR96u.js → DcGCxgpH.js} +1 -1
  56. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{Bsi3UGy5.js → Df3aMO5B.js} +1 -1
  57. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{hQVEETDE.js → DkR_EZ_B.js} +1 -1
  58. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DqUGznj_.js +1 -0
  59. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/KpAtIldw.js +1 -0
  60. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/M1Q1F7bw.js +4 -0
  61. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{CDnpyLsT.js → OH7-C_mc.js} +1 -1
  62. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/{D6su9Aln.js → gLNdjSzu.js} +1 -1
  63. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/i0ZZ4z06.js +1 -0
  64. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.BI-EA5gL.js +2 -0
  65. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.CcsRl3cZ.js +1 -0
  66. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.BbO4Zc3r.js +1 -0
  67. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{1.B4rNYwVp.js → 1._I9GR805.js} +1 -1
  68. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.J2RBFrSr.js +1 -0
  69. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.Cmqj25a-.js +1 -0
  70. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.C45iKJHA.js +6 -0
  71. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{3.CWHpKonm.js → 3.w9g4AcAx.js} +1 -1
  72. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{4.OUWOLQeV.js → 4.BBI8KwnD.js} +1 -1
  73. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.huHuxdiF.js +1 -0
  74. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/6.CrbkRPam.js +1 -0
  75. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.FomEdhD6.js +1 -0
  76. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.Cb_ADSLk.js +1 -0
  77. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/{9.CPu3CiBc.js → 9.CajIG5ce.js} +1 -1
  78. lightly_studio/dist_lightly_studio_view_app/_app/version.json +1 -1
  79. lightly_studio/dist_lightly_studio_view_app/index.html +14 -14
  80. lightly_studio/examples/example.py +13 -12
  81. lightly_studio/examples/example_coco.py +13 -0
  82. lightly_studio/examples/example_metadata.py +83 -98
  83. lightly_studio/examples/example_selection.py +7 -19
  84. lightly_studio/examples/example_split_work.py +12 -36
  85. lightly_studio/examples/{example_v2.py → example_yolo.py} +3 -4
  86. lightly_studio/models/annotation/annotation_base.py +7 -8
  87. lightly_studio/models/annotation/instance_segmentation.py +8 -8
  88. lightly_studio/models/annotation/object_detection.py +4 -4
  89. lightly_studio/models/dataset.py +6 -2
  90. lightly_studio/models/sample.py +10 -3
  91. lightly_studio/resolvers/dataset_resolver.py +10 -0
  92. lightly_studio/resolvers/embedding_model_resolver.py +22 -0
  93. lightly_studio/resolvers/sample_resolver.py +53 -9
  94. lightly_studio/resolvers/tag_resolver.py +23 -0
  95. lightly_studio/selection/select.py +55 -46
  96. lightly_studio/selection/select_via_db.py +23 -19
  97. lightly_studio/selection/selection_config.py +6 -3
  98. lightly_studio/services/annotations_service/__init__.py +4 -0
  99. lightly_studio/services/annotations_service/update_annotation.py +21 -32
  100. lightly_studio/services/annotations_service/update_annotation_bounding_box.py +36 -0
  101. lightly_studio-0.3.2.dist-info/METADATA +689 -0
  102. {lightly_studio-0.3.1.dist-info → lightly_studio-0.3.2.dist-info}/RECORD +104 -91
  103. lightly_studio/api/db.py +0 -133
  104. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.OwPEPQZu.css +0 -1
  105. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/SelectableSvgGroup.b653GmVf.css +0 -1
  106. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/B2FVR0s0.js +0 -1
  107. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/B9zumHo5.js +0 -1
  108. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BJXwVxaE.js +0 -1
  109. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Bx1xMsFy.js +0 -1
  110. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CcaPhhk3.js +0 -1
  111. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CvOmgdoc.js +0 -93
  112. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CxtLVaYz.js +0 -3
  113. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D5-A_Ffd.js +0 -4
  114. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D6RI2Zrd.js +0 -1
  115. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D98V7j6A.js +0 -1
  116. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DIRAtgl0.js +0 -1
  117. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DjUWrjOv.js +0 -1
  118. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/XO7A28GO.js +0 -1
  119. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/nAHhluT7.js +0 -1
  120. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/vC4nQVEB.js +0 -1
  121. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.CjnvpsmS.js +0 -2
  122. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.0o1H7wM9.js +0 -1
  123. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.XRq_TUwu.js +0 -1
  124. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.DfBwOEhN.js +0 -1
  125. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.CwF2_8mP.js +0 -1
  126. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.CS4muRY-.js +0 -6
  127. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.Dm6t9F5W.js +0 -1
  128. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/6.Bw5ck4gK.js +0 -1
  129. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.CF0EDTR6.js +0 -1
  130. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.Cw30LEcV.js +0 -1
  131. lightly_studio-0.3.1.dist-info/METADATA +0 -520
  132. /lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/{OpenSans- → OpenSans-Medium.DVUZMR_6.ttf} +0 -0
  133. {lightly_studio-0.3.1.dist-info → lightly_studio-0.3.2.dist-info}/WHEEL +0 -0
@@ -1,11 +1,11 @@
1
1
  # Set up logging before importing any other modules.
2
2
  # Add noqa to silence unused import and unsorted imports linter warnings.
3
3
  from . import setup_logging # noqa: F401 I001
4
-
5
- # TODO (Jonas 08/25): This will be removed as soon as the new interface is used in the examples
6
- from lightly_studio.dataset.loader import DatasetLoader
7
4
  from lightly_studio.core.dataset import Dataset
8
5
  from lightly_studio.core.start_gui import start_gui
9
6
 
7
+ # TODO (Jonas 08/25): This will be removed as soon as the new interface is used in the examples
8
+ from lightly_studio.dataset.loader import DatasetLoader
9
+ from lightly_studio.models.annotation_task import AnnotationType
10
10
 
11
- __all__ = ["Dataset", "DatasetLoader", "start_gui"]
11
+ __all__ = ["AnnotationType", "Dataset", "DatasetLoader", "start_gui"]
lightly_studio/api/app.py CHANGED
@@ -11,7 +11,7 @@ from fastapi.routing import APIRoute
11
11
  from sqlmodel import Session
12
12
  from typing_extensions import Annotated
13
13
 
14
- from lightly_studio.api.db import db_manager
14
+ from lightly_studio import db_manager
15
15
  from lightly_studio.api.routes import healthz, images, webapp
16
16
  from lightly_studio.api.routes.api import (
17
17
  annotation,
@@ -7,16 +7,15 @@ from uuid import UUID
7
7
  from fastapi import APIRouter, Body, Depends, HTTPException, Path
8
8
  from fastapi.params import Query
9
9
  from pydantic import BaseModel
10
- from sqlmodel import Session
11
10
  from typing_extensions import Annotated
12
11
 
13
- from lightly_studio.api.db import get_session
14
12
  from lightly_studio.api.routes.api.dataset import get_and_validate_dataset_id
15
13
  from lightly_studio.api.routes.api.status import (
16
14
  HTTP_STATUS_CREATED,
17
15
  HTTP_STATUS_NOT_FOUND,
18
16
  )
19
17
  from lightly_studio.api.routes.api.validators import Paginated, PaginatedWithCursor
18
+ from lightly_studio.db_manager import SessionDep
20
19
  from lightly_studio.models.annotation.annotation_base import (
21
20
  AnnotationBaseTable,
22
21
  AnnotationDetailsView,
@@ -27,6 +26,7 @@ from lightly_studio.resolvers import annotation_resolver, tag_resolver
27
26
  from lightly_studio.resolvers.annotation_resolver.get_all import (
28
27
  GetAllAnnotationsResult,
29
28
  )
29
+ from lightly_studio.resolvers.annotation_resolver.update_bounding_box import BoundingBoxCoordinates
30
30
  from lightly_studio.resolvers.annotations.annotations_filter import (
31
31
  AnnotationsFilter,
32
32
  )
@@ -36,7 +36,6 @@ from lightly_studio.services.annotations_service.update_annotation import (
36
36
  )
37
37
 
38
38
  annotations_router = APIRouter(prefix="/datasets/{dataset_id}", tags=["annotations"])
39
- SessionDep = Annotated[Session, Depends(get_session)]
40
39
 
41
40
 
42
41
  @annotations_router.get("/annotations/count")
@@ -134,11 +133,8 @@ class AnnotationUpdateInput(BaseModel):
134
133
 
135
134
  annotation_id: UUID
136
135
  dataset_id: UUID
137
- label_name: str | None
138
- x: int | None = None
139
- y: int | None = None
140
- width: int | None = None
141
- height: int | None = None
136
+ label_name: str | None = None
137
+ bounding_box: BoundingBoxCoordinates | None = None
142
138
 
143
139
 
144
140
  @annotations_router.put("/annotations/{annotation_id}")
@@ -161,10 +157,7 @@ def update_annotation(
161
157
  annotation_id=annotation_id,
162
158
  dataset_id=dataset_id,
163
159
  label_name=annotation_update_input.label_name,
164
- x=annotation_update_input.x,
165
- y=annotation_update_input.y,
166
- width=annotation_update_input.width,
167
- height=annotation_update_input.height,
160
+ bounding_box=annotation_update_input.bounding_box,
168
161
  ),
169
162
  )
170
163
 
@@ -188,10 +181,7 @@ def update_annotations(
188
181
  annotation_id=annotation_update_input.annotation_id,
189
182
  dataset_id=dataset_id,
190
183
  label_name=annotation_update_input.label_name,
191
- x=annotation_update_input.x,
192
- y=annotation_update_input.y,
193
- width=annotation_update_input.width,
194
- height=annotation_update_input.height,
184
+ bounding_box=annotation_update_input.bounding_box,
195
185
  )
196
186
  for annotation_update_input in annotation_update_inputs
197
187
  ],
@@ -4,15 +4,13 @@ from __future__ import annotations
4
4
 
5
5
  from uuid import UUID
6
6
 
7
- from fastapi import APIRouter, Depends, HTTPException
8
- from sqlmodel import Session
9
- from typing_extensions import Annotated
7
+ from fastapi import APIRouter, HTTPException
10
8
 
11
- from lightly_studio.api.db import get_session
12
9
  from lightly_studio.api.routes.api.status import (
13
10
  HTTP_STATUS_CREATED,
14
11
  HTTP_STATUS_NOT_FOUND,
15
12
  )
13
+ from lightly_studio.db_manager import SessionDep
16
14
  from lightly_studio.models.annotation_label import (
17
15
  AnnotationLabelCreate,
18
16
  AnnotationLabelTable,
@@ -20,7 +18,6 @@ from lightly_studio.models.annotation_label import (
20
18
  from lightly_studio.resolvers import annotation_label_resolver
21
19
 
22
20
  annotations_label_router = APIRouter()
23
- SessionDep = Annotated[Session, Depends(get_session)]
24
21
 
25
22
 
26
23
  @annotations_label_router.post(
@@ -3,10 +3,9 @@
3
3
  from typing import List
4
4
  from uuid import UUID
5
5
 
6
- from fastapi import APIRouter, Depends, HTTPException, status
7
- from sqlmodel import Session
6
+ from fastapi import APIRouter, HTTPException, status
8
7
 
9
- from lightly_studio.api.db import get_session
8
+ from lightly_studio.db_manager import SessionDep
10
9
  from lightly_studio.models.annotation_task import AnnotationTaskTable
11
10
  from lightly_studio.resolvers import annotation_task_resolver
12
11
 
@@ -15,7 +14,7 @@ router = APIRouter(prefix="/annotationtasks", tags=["annotationtasks"])
15
14
 
16
15
  @router.get("/", response_model=List[AnnotationTaskTable])
17
16
  def get_annotation_tasks(
18
- session: Session = Depends(get_session), # noqa: B008
17
+ session: SessionDep,
19
18
  ) -> List[AnnotationTaskTable]:
20
19
  """Get all annotation tasks."""
21
20
  return annotation_task_resolver.get_all(session=session)
@@ -24,7 +23,7 @@ def get_annotation_tasks(
24
23
  @router.get("/{annotation_task_id}", response_model=AnnotationTaskTable)
25
24
  def get_annotation_task(
26
25
  annotation_task_id: UUID,
27
- session: Session = Depends(get_session), # noqa: B008
26
+ session: SessionDep,
28
27
  ) -> AnnotationTaskTable:
29
28
  """Get an annotation task by ID."""
30
29
  task = annotation_task_resolver.get_by_id(
@@ -6,13 +6,11 @@ import io
6
6
  from pathlib import Path
7
7
  from uuid import UUID
8
8
 
9
- from fastapi import APIRouter, Depends, UploadFile
9
+ from fastapi import APIRouter, UploadFile
10
10
  from fastapi.responses import StreamingResponse
11
11
  from pydantic import BaseModel
12
- from sqlmodel import Session
13
- from typing_extensions import Annotated
14
12
 
15
- from lightly_studio.api.db import get_session
13
+ from lightly_studio.db_manager import SessionDep
16
14
  from lightly_studio.few_shot_classifier.classifier import (
17
15
  ExportType,
18
16
  )
@@ -22,7 +20,6 @@ from lightly_studio.few_shot_classifier.classifier_manager import (
22
20
  from lightly_studio.models.classifier import EmbeddingClassifier
23
21
 
24
22
  classifier_router = APIRouter()
25
- SessionDep = Annotated[Session, Depends(get_session)]
26
23
 
27
24
 
28
25
  class GetNegativeSamplesRequest(BaseModel):
@@ -9,12 +9,12 @@ from uuid import UUID
9
9
  from fastapi import APIRouter, Depends, HTTPException, Path, Query
10
10
  from fastapi.responses import PlainTextResponse
11
11
  from pydantic import BaseModel
12
- from sqlmodel import Field, Session
12
+ from sqlmodel import Field
13
13
  from typing_extensions import Annotated
14
14
 
15
- from lightly_studio.api.db import get_session
16
15
  from lightly_studio.api.routes.api.status import HTTP_STATUS_NOT_FOUND
17
16
  from lightly_studio.api.routes.api.validators import Paginated
17
+ from lightly_studio.db_manager import SessionDep
18
18
  from lightly_studio.models.dataset import (
19
19
  DatasetCreate,
20
20
  DatasetTable,
@@ -26,7 +26,6 @@ from lightly_studio.resolvers.dataset_resolver import (
26
26
  )
27
27
 
28
28
  dataset_router = APIRouter()
29
- SessionDep = Annotated[Session, Depends(get_session)]
30
29
 
31
30
 
32
31
  def get_and_validate_dataset_id(
@@ -8,10 +8,9 @@ from uuid import UUID
8
8
  from fastapi import APIRouter, Depends, HTTPException, Path, Query
9
9
  from pydantic import BaseModel
10
10
  from sqlalchemy.exc import IntegrityError
11
- from sqlmodel import Field, Session
11
+ from sqlmodel import Field
12
12
  from typing_extensions import Annotated
13
13
 
14
- from lightly_studio.api.db import get_session
15
14
  from lightly_studio.api.routes.api.dataset import get_and_validate_dataset_id
16
15
  from lightly_studio.api.routes.api.status import (
17
16
  HTTP_STATUS_CONFLICT,
@@ -19,6 +18,7 @@ from lightly_studio.api.routes.api.status import (
19
18
  HTTP_STATUS_NOT_FOUND,
20
19
  )
21
20
  from lightly_studio.api.routes.api.validators import Paginated
21
+ from lightly_studio.db_manager import SessionDep
22
22
  from lightly_studio.models.dataset import DatasetTable
23
23
  from lightly_studio.models.tag import (
24
24
  TagCreate,
@@ -31,7 +31,6 @@ from lightly_studio.models.tag import (
31
31
  from lightly_studio.resolvers import tag_resolver
32
32
 
33
33
  tag_router = APIRouter()
34
- SessionDep = Annotated[Session, Depends(get_session)]
35
34
 
36
35
 
37
36
  @tag_router.post(
@@ -5,18 +5,16 @@ from __future__ import annotations
5
5
  from typing import List
6
6
  from uuid import UUID
7
7
 
8
- from fastapi import APIRouter, Depends, Path
9
- from sqlmodel import Session
8
+ from fastapi import APIRouter, Path
10
9
  from typing_extensions import Annotated
11
10
 
12
- from lightly_studio.api.db import get_session
11
+ from lightly_studio.db_manager import SessionDep
13
12
  from lightly_studio.models.metadata import MetadataInfoView
14
13
  from lightly_studio.resolvers.metadata_resolver.sample.get_metadata_info import (
15
14
  get_all_metadata_keys_and_schema,
16
15
  )
17
16
 
18
17
  metadata_router = APIRouter(prefix="/datasets/{dataset_id}", tags=["metadata"])
19
- SessionDep = Annotated[Session, Depends(get_session)]
20
18
 
21
19
 
22
20
  @metadata_router.get("/metadata/info", response_model=List[MetadataInfoView])
@@ -4,12 +4,10 @@ from __future__ import annotations
4
4
 
5
5
  from uuid import UUID
6
6
 
7
- from fastapi import APIRouter, Depends
7
+ from fastapi import APIRouter
8
8
  from pydantic import BaseModel
9
- from sqlmodel import Session
10
- from typing_extensions import Annotated
11
9
 
12
- from lightly_studio.api.db import get_session
10
+ from lightly_studio.db_manager import SessionDep
13
11
  from lightly_studio.metrics.detection.map import (
14
12
  DetectionMetricsMAP,
15
13
  calculate_map_metric,
@@ -24,8 +22,6 @@ from lightly_studio.resolvers.annotations.annotations_filter import (
24
22
 
25
23
  metrics_router = APIRouter()
26
24
 
27
- SessionDep = Annotated[Session, Depends(get_session)]
28
-
29
25
 
30
26
  class DetectionMetricsMAPRequest(BaseModel):
31
27
  """Request for computing the MAP detection metric."""
@@ -6,16 +6,15 @@ from uuid import UUID
6
6
 
7
7
  from fastapi import APIRouter, Depends, HTTPException, Path, Query
8
8
  from pydantic import BaseModel, Field
9
- from sqlmodel import Session
10
9
  from typing_extensions import Annotated
11
10
 
12
- from lightly_studio.api.db import get_session
13
11
  from lightly_studio.api.routes.api.dataset import get_and_validate_dataset_id
14
12
  from lightly_studio.api.routes.api.status import (
15
13
  HTTP_STATUS_CREATED,
16
14
  HTTP_STATUS_NOT_FOUND,
17
15
  )
18
16
  from lightly_studio.api.routes.api.validators import Paginated
17
+ from lightly_studio.db_manager import SessionDep
19
18
  from lightly_studio.models.dataset import DatasetTable
20
19
  from lightly_studio.models.sample import (
21
20
  SampleCreate,
@@ -27,12 +26,12 @@ from lightly_studio.resolvers import (
27
26
  sample_resolver,
28
27
  tag_resolver,
29
28
  )
29
+ from lightly_studio.resolvers.sample_resolver import GetAllSamplesByDatasetIdResult
30
30
  from lightly_studio.resolvers.samples_filter import (
31
31
  SampleFilter,
32
32
  )
33
33
 
34
34
  samples_router = APIRouter(prefix="/datasets/{dataset_id}", tags=["samples"])
35
- SessionDep = Annotated[Session, Depends(get_session)]
36
35
 
37
36
 
38
37
  @samples_router.post("/samples", response_model=SampleView)
@@ -60,7 +59,7 @@ def read_samples(
60
59
  session: SessionDep,
61
60
  dataset_id: Annotated[UUID, Path(title="Dataset Id")],
62
61
  body: ReadSamplesRequest,
63
- ) -> SampleViewsWithCount:
62
+ ) -> GetAllSamplesByDatasetIdResult:
64
63
  """Retrieve a list of samples from the database with optional filtering.
65
64
 
66
65
  Args:
@@ -71,22 +70,15 @@ def read_samples(
71
70
  Returns:
72
71
  A list of filtered samples.
73
72
  """
74
- result = sample_resolver.get_all_by_dataset_id(
73
+ return sample_resolver.get_all_by_dataset_id(
75
74
  session=session,
76
75
  dataset_id=dataset_id,
77
- # TODO(Michal, 06/2025): Pass the Paginated object directly.
78
- offset=body.pagination.offset if body.pagination else 0,
79
- limit=body.pagination.limit if body.pagination else 10,
76
+ pagination=body.pagination,
80
77
  filters=body.filters,
81
78
  text_embedding=body.text_embedding,
82
79
  sample_ids=body.sample_ids,
83
80
  )
84
81
 
85
- return SampleViewsWithCount(
86
- data=result.samples,
87
- total_count=result.total_count,
88
- )
89
-
90
82
 
91
83
  @samples_router.get("/samples/dimensions")
92
84
  def get_sample_dimensions(
@@ -1,17 +1,13 @@
1
1
  """This module contains the API routes for user settings."""
2
2
 
3
- from fastapi import APIRouter, Depends
4
- from sqlmodel import Session
5
- from typing_extensions import Annotated
3
+ from fastapi import APIRouter
6
4
 
7
- from lightly_studio.api.db import get_session
5
+ from lightly_studio.db_manager import SessionDep
8
6
  from lightly_studio.models.settings import SettingView
9
7
  from lightly_studio.resolvers import settings_resolver
10
8
 
11
9
  settings_router = APIRouter(tags=["settings"])
12
10
 
13
- SessionDep = Annotated[Session, Depends(get_session)]
14
-
15
11
 
16
12
  @settings_router.get("/settings")
17
13
  def get_settings(
@@ -5,12 +5,12 @@ from __future__ import annotations
5
5
  import os
6
6
  from collections.abc import Generator
7
7
 
8
- from fastapi import APIRouter, Depends, HTTPException
8
+ import fsspec
9
+ from fastapi import APIRouter, HTTPException
9
10
  from fastapi.responses import StreamingResponse
10
- from sqlmodel import Session
11
11
 
12
- from lightly_studio.api import db
13
12
  from lightly_studio.api.routes.api import status
13
+ from lightly_studio.db_manager import SessionDep
14
14
  from lightly_studio.models import sample
15
15
 
16
16
  app_router = APIRouter()
@@ -19,7 +19,7 @@ app_router = APIRouter()
19
19
  @app_router.get("/sample/{sample_id}")
20
20
  async def serve_image_by_sample_id(
21
21
  sample_id: str,
22
- session: Session = Depends(db.get_session), # noqa: B008
22
+ session: SessionDep,
23
23
  ) -> StreamingResponse:
24
24
  """Serve an image by sample ID.
25
25
 
@@ -45,8 +45,8 @@ async def serve_image_by_sample_id(
45
45
 
46
46
  try:
47
47
  # Open the file.
48
- with open(file_path, "rb") as file:
49
- content = file.read()
48
+ fs, fs_path = fsspec.core.url_to_fs(file_path)
49
+ content = fs.cat_file(fs_path)
50
50
 
51
51
  # Determine content type based on file extension.
52
52
  content_type = _get_content_type(file_path)