lightly-studio 0.4.6__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.
Files changed (356) hide show
  1. lightly_studio/__init__.py +12 -0
  2. lightly_studio/api/__init__.py +0 -0
  3. lightly_studio/api/app.py +131 -0
  4. lightly_studio/api/cache.py +77 -0
  5. lightly_studio/api/db_tables.py +35 -0
  6. lightly_studio/api/features.py +5 -0
  7. lightly_studio/api/routes/api/annotation.py +305 -0
  8. lightly_studio/api/routes/api/annotation_label.py +87 -0
  9. lightly_studio/api/routes/api/annotations/__init__.py +7 -0
  10. lightly_studio/api/routes/api/annotations/create_annotation.py +52 -0
  11. lightly_studio/api/routes/api/caption.py +100 -0
  12. lightly_studio/api/routes/api/classifier.py +384 -0
  13. lightly_studio/api/routes/api/dataset.py +191 -0
  14. lightly_studio/api/routes/api/dataset_tag.py +266 -0
  15. lightly_studio/api/routes/api/embeddings2d.py +90 -0
  16. lightly_studio/api/routes/api/exceptions.py +114 -0
  17. lightly_studio/api/routes/api/export.py +114 -0
  18. lightly_studio/api/routes/api/features.py +17 -0
  19. lightly_studio/api/routes/api/frame.py +241 -0
  20. lightly_studio/api/routes/api/image.py +155 -0
  21. lightly_studio/api/routes/api/metadata.py +161 -0
  22. lightly_studio/api/routes/api/operator.py +75 -0
  23. lightly_studio/api/routes/api/sample.py +103 -0
  24. lightly_studio/api/routes/api/selection.py +87 -0
  25. lightly_studio/api/routes/api/settings.py +41 -0
  26. lightly_studio/api/routes/api/status.py +19 -0
  27. lightly_studio/api/routes/api/text_embedding.py +50 -0
  28. lightly_studio/api/routes/api/validators.py +17 -0
  29. lightly_studio/api/routes/api/video.py +133 -0
  30. lightly_studio/api/routes/healthz.py +13 -0
  31. lightly_studio/api/routes/images.py +104 -0
  32. lightly_studio/api/routes/video_frames_media.py +116 -0
  33. lightly_studio/api/routes/video_media.py +223 -0
  34. lightly_studio/api/routes/webapp.py +51 -0
  35. lightly_studio/api/server.py +94 -0
  36. lightly_studio/core/__init__.py +0 -0
  37. lightly_studio/core/add_samples.py +533 -0
  38. lightly_studio/core/add_videos.py +294 -0
  39. lightly_studio/core/dataset.py +780 -0
  40. lightly_studio/core/dataset_query/__init__.py +14 -0
  41. lightly_studio/core/dataset_query/boolean_expression.py +67 -0
  42. lightly_studio/core/dataset_query/dataset_query.py +317 -0
  43. lightly_studio/core/dataset_query/field.py +113 -0
  44. lightly_studio/core/dataset_query/field_expression.py +79 -0
  45. lightly_studio/core/dataset_query/match_expression.py +23 -0
  46. lightly_studio/core/dataset_query/order_by.py +79 -0
  47. lightly_studio/core/dataset_query/sample_field.py +37 -0
  48. lightly_studio/core/dataset_query/tags_expression.py +46 -0
  49. lightly_studio/core/image_sample.py +36 -0
  50. lightly_studio/core/loading_log.py +56 -0
  51. lightly_studio/core/sample.py +291 -0
  52. lightly_studio/core/start_gui.py +54 -0
  53. lightly_studio/core/video_sample.py +38 -0
  54. lightly_studio/dataset/__init__.py +0 -0
  55. lightly_studio/dataset/edge_embedding_generator.py +155 -0
  56. lightly_studio/dataset/embedding_generator.py +129 -0
  57. lightly_studio/dataset/embedding_manager.py +349 -0
  58. lightly_studio/dataset/env.py +20 -0
  59. lightly_studio/dataset/file_utils.py +49 -0
  60. lightly_studio/dataset/fsspec_lister.py +275 -0
  61. lightly_studio/dataset/mobileclip_embedding_generator.py +158 -0
  62. lightly_studio/dataset/perception_encoder_embedding_generator.py +260 -0
  63. lightly_studio/db_manager.py +166 -0
  64. lightly_studio/dist_lightly_studio_view_app/_app/env.js +1 -0
  65. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/0.GcXvs2l7.css +1 -0
  66. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/12.Dx6SXgAb.css +1 -0
  67. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/17.9X9_k6TP.css +1 -0
  68. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/18.BxiimdIO.css +1 -0
  69. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/2.CkOblLn7.css +1 -0
  70. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/ClassifierSamplesGrid.BJbCDlvs.css +1 -0
  71. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/LightlyLogo.BNjCIww-.png +0 -0
  72. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Bold.DGvYQtcs.ttf +0 -0
  73. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Italic-VariableFont_wdth_wght.B4AZ-wl6.ttf +0 -0
  74. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Medium.DVUZMR_6.ttf +0 -0
  75. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Regular.DxJTClRG.ttf +0 -0
  76. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-SemiBold.D3TTYgdB.ttf +0 -0
  77. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-VariableFont_wdth_wght.BZBpG5Iz.ttf +0 -0
  78. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.CefECEWA.css +1 -0
  79. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.D5tDcjY-.css +1 -0
  80. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_page.9X9_k6TP.css +1 -0
  81. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_page.BxiimdIO.css +1 -0
  82. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_page.Dx6SXgAb.css +1 -0
  83. lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/transform._-1mPSEI.css +1 -0
  84. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/0dDyq72A.js +20 -0
  85. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/69_IOA4Y.js +1 -0
  86. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BK4An2kI.js +1 -0
  87. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BRmB-kJ9.js +1 -0
  88. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/B_1cpokE.js +1 -0
  89. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BiqpDEr0.js +1 -0
  90. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BpLiSKgx.js +1 -0
  91. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BscxbINH.js +39 -0
  92. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C1FmrZbK.js +1 -0
  93. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C80h3dJx.js +1 -0
  94. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C8mfFM-u.js +2 -0
  95. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CGY1p9L4.js +517 -0
  96. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/COfLknXM.js +1 -0
  97. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CWj6FrbW.js +1 -0
  98. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CYgJF_JY.js +1 -0
  99. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CmLg0ys7.js +1 -0
  100. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CvGjimpO.js +1 -0
  101. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D3RDXHoj.js +39 -0
  102. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D4y7iiT3.js +1 -0
  103. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D9SC3jBb.js +1 -0
  104. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DCuAdx1Q.js +20 -0
  105. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DDBy-_jD.js +1 -0
  106. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DIeogL5L.js +1 -0
  107. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DL9a7v5o.js +1 -0
  108. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DSKECuqX.js +39 -0
  109. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D_FFv0Oe.js +1 -0
  110. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DiZ5o5vz.js +1 -0
  111. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DkbXUtyG.js +1 -0
  112. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DmK2hulV.js +1 -0
  113. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DqnHaLTj.js +1 -0
  114. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DtWZc_tl.js +1 -0
  115. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DuUalyFS.js +1 -0
  116. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DwIonDAZ.js +1 -0
  117. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Il-mSPmK.js +1 -0
  118. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/KNLP4aJU.js +1 -0
  119. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/KjYeVjkE.js +1 -0
  120. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/MErlcOXj.js +1 -0
  121. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/VRI4prUD.js +1 -0
  122. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/VYb2dkNs.js +1 -0
  123. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/VqWvU2yF.js +1 -0
  124. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/dHC3otuL.js +1 -0
  125. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/da7Oy_lO.js +1 -0
  126. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/eAy8rZzC.js +2 -0
  127. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/erjNR5MX.js +1 -0
  128. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/f1oG3eFE.js +1 -0
  129. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/rsLi1iKv.js +20 -0
  130. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/rwuuBP9f.js +1 -0
  131. lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/xGHZQ1pe.js +3 -0
  132. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.DrTRUgT3.js +2 -0
  133. lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.BK5EOJl2.js +1 -0
  134. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.CIvTuljF.js +4 -0
  135. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/1.UBvSzxdA.js +1 -0
  136. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.CQ_tiLJa.js +1 -0
  137. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/11.KqkAcaxW.js +1 -0
  138. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.DoYsmxQc.js +1 -0
  139. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/13.571n2LZA.js +1 -0
  140. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/14.DGs689M-.js +1 -0
  141. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/15.CWG1ehzT.js +1 -0
  142. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/16.Dpq6jbSh.js +1 -0
  143. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/17.B5AZbHUU.js +1 -0
  144. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/18.CBga8cnq.js +1 -0
  145. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.D2HXgz-8.js +1090 -0
  146. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/3.f4HAg-y3.js +1 -0
  147. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/4.BKF4xuKQ.js +1 -0
  148. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.BAE0Pm_f.js +39 -0
  149. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/6.CouWWpzA.js +1 -0
  150. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.UBHT0ktp.js +1 -0
  151. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.FiYNElcc.js +1 -0
  152. lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/9.B3-UaT23.js +1 -0
  153. lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/clustering.worker-DKqeLtG0.js +2 -0
  154. lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/search.worker-vNSty3B0.js +1 -0
  155. lightly_studio/dist_lightly_studio_view_app/_app/version.json +1 -0
  156. lightly_studio/dist_lightly_studio_view_app/apple-touch-icon-precomposed.png +0 -0
  157. lightly_studio/dist_lightly_studio_view_app/apple-touch-icon.png +0 -0
  158. lightly_studio/dist_lightly_studio_view_app/favicon.png +0 -0
  159. lightly_studio/dist_lightly_studio_view_app/index.html +45 -0
  160. lightly_studio/errors.py +5 -0
  161. lightly_studio/examples/example.py +25 -0
  162. lightly_studio/examples/example_coco.py +27 -0
  163. lightly_studio/examples/example_coco_caption.py +29 -0
  164. lightly_studio/examples/example_metadata.py +369 -0
  165. lightly_studio/examples/example_operators.py +111 -0
  166. lightly_studio/examples/example_selection.py +28 -0
  167. lightly_studio/examples/example_split_work.py +48 -0
  168. lightly_studio/examples/example_video.py +22 -0
  169. lightly_studio/examples/example_video_annotations.py +157 -0
  170. lightly_studio/examples/example_yolo.py +22 -0
  171. lightly_studio/export/coco_captions.py +69 -0
  172. lightly_studio/export/export_dataset.py +104 -0
  173. lightly_studio/export/lightly_studio_label_input.py +120 -0
  174. lightly_studio/export_schema.py +18 -0
  175. lightly_studio/export_version.py +57 -0
  176. lightly_studio/few_shot_classifier/__init__.py +0 -0
  177. lightly_studio/few_shot_classifier/classifier.py +80 -0
  178. lightly_studio/few_shot_classifier/classifier_manager.py +644 -0
  179. lightly_studio/few_shot_classifier/random_forest_classifier.py +495 -0
  180. lightly_studio/metadata/complex_metadata.py +47 -0
  181. lightly_studio/metadata/compute_similarity.py +84 -0
  182. lightly_studio/metadata/compute_typicality.py +67 -0
  183. lightly_studio/metadata/gps_coordinate.py +41 -0
  184. lightly_studio/metadata/metadata_protocol.py +17 -0
  185. lightly_studio/models/__init__.py +1 -0
  186. lightly_studio/models/annotation/__init__.py +0 -0
  187. lightly_studio/models/annotation/annotation_base.py +303 -0
  188. lightly_studio/models/annotation/instance_segmentation.py +56 -0
  189. lightly_studio/models/annotation/links.py +17 -0
  190. lightly_studio/models/annotation/object_detection.py +47 -0
  191. lightly_studio/models/annotation/semantic_segmentation.py +44 -0
  192. lightly_studio/models/annotation_label.py +47 -0
  193. lightly_studio/models/caption.py +49 -0
  194. lightly_studio/models/classifier.py +20 -0
  195. lightly_studio/models/dataset.py +70 -0
  196. lightly_studio/models/embedding_model.py +30 -0
  197. lightly_studio/models/image.py +96 -0
  198. lightly_studio/models/metadata.py +208 -0
  199. lightly_studio/models/range.py +17 -0
  200. lightly_studio/models/sample.py +154 -0
  201. lightly_studio/models/sample_embedding.py +36 -0
  202. lightly_studio/models/settings.py +69 -0
  203. lightly_studio/models/tag.py +96 -0
  204. lightly_studio/models/two_dim_embedding.py +16 -0
  205. lightly_studio/models/video.py +161 -0
  206. lightly_studio/plugins/__init__.py +0 -0
  207. lightly_studio/plugins/base_operator.py +60 -0
  208. lightly_studio/plugins/operator_registry.py +47 -0
  209. lightly_studio/plugins/parameter.py +70 -0
  210. lightly_studio/py.typed +0 -0
  211. lightly_studio/resolvers/__init__.py +0 -0
  212. lightly_studio/resolvers/annotation_label_resolver/__init__.py +22 -0
  213. lightly_studio/resolvers/annotation_label_resolver/create.py +27 -0
  214. lightly_studio/resolvers/annotation_label_resolver/delete.py +28 -0
  215. lightly_studio/resolvers/annotation_label_resolver/get_all.py +37 -0
  216. lightly_studio/resolvers/annotation_label_resolver/get_by_id.py +24 -0
  217. lightly_studio/resolvers/annotation_label_resolver/get_by_ids.py +25 -0
  218. lightly_studio/resolvers/annotation_label_resolver/get_by_label_name.py +24 -0
  219. lightly_studio/resolvers/annotation_label_resolver/names_by_ids.py +25 -0
  220. lightly_studio/resolvers/annotation_label_resolver/update.py +38 -0
  221. lightly_studio/resolvers/annotation_resolver/__init__.py +40 -0
  222. lightly_studio/resolvers/annotation_resolver/count_annotations_by_dataset.py +129 -0
  223. lightly_studio/resolvers/annotation_resolver/create_many.py +124 -0
  224. lightly_studio/resolvers/annotation_resolver/delete_annotation.py +87 -0
  225. lightly_studio/resolvers/annotation_resolver/delete_annotations.py +60 -0
  226. lightly_studio/resolvers/annotation_resolver/get_all.py +85 -0
  227. lightly_studio/resolvers/annotation_resolver/get_all_with_payload.py +179 -0
  228. lightly_studio/resolvers/annotation_resolver/get_by_id.py +34 -0
  229. lightly_studio/resolvers/annotation_resolver/get_by_id_with_payload.py +130 -0
  230. lightly_studio/resolvers/annotation_resolver/update_annotation_label.py +142 -0
  231. lightly_studio/resolvers/annotation_resolver/update_bounding_box.py +68 -0
  232. lightly_studio/resolvers/annotations/__init__.py +1 -0
  233. lightly_studio/resolvers/annotations/annotations_filter.py +88 -0
  234. lightly_studio/resolvers/caption_resolver.py +129 -0
  235. lightly_studio/resolvers/dataset_resolver/__init__.py +55 -0
  236. lightly_studio/resolvers/dataset_resolver/check_dataset_type.py +29 -0
  237. lightly_studio/resolvers/dataset_resolver/create.py +20 -0
  238. lightly_studio/resolvers/dataset_resolver/delete.py +20 -0
  239. lightly_studio/resolvers/dataset_resolver/export.py +267 -0
  240. lightly_studio/resolvers/dataset_resolver/get_all.py +19 -0
  241. lightly_studio/resolvers/dataset_resolver/get_by_id.py +16 -0
  242. lightly_studio/resolvers/dataset_resolver/get_by_name.py +12 -0
  243. lightly_studio/resolvers/dataset_resolver/get_dataset_details.py +27 -0
  244. lightly_studio/resolvers/dataset_resolver/get_hierarchy.py +31 -0
  245. lightly_studio/resolvers/dataset_resolver/get_or_create_child_dataset.py +58 -0
  246. lightly_studio/resolvers/dataset_resolver/get_parent_dataset_by_sample_id.py +27 -0
  247. lightly_studio/resolvers/dataset_resolver/get_parent_dataset_id.py +22 -0
  248. lightly_studio/resolvers/dataset_resolver/get_root_dataset.py +61 -0
  249. lightly_studio/resolvers/dataset_resolver/get_root_datasets_overview.py +41 -0
  250. lightly_studio/resolvers/dataset_resolver/update.py +25 -0
  251. lightly_studio/resolvers/embedding_model_resolver.py +120 -0
  252. lightly_studio/resolvers/image_filter.py +50 -0
  253. lightly_studio/resolvers/image_resolver/__init__.py +21 -0
  254. lightly_studio/resolvers/image_resolver/create_many.py +52 -0
  255. lightly_studio/resolvers/image_resolver/delete.py +20 -0
  256. lightly_studio/resolvers/image_resolver/filter_new_paths.py +23 -0
  257. lightly_studio/resolvers/image_resolver/get_all_by_dataset_id.py +117 -0
  258. lightly_studio/resolvers/image_resolver/get_by_id.py +14 -0
  259. lightly_studio/resolvers/image_resolver/get_dimension_bounds.py +75 -0
  260. lightly_studio/resolvers/image_resolver/get_many_by_id.py +22 -0
  261. lightly_studio/resolvers/image_resolver/get_samples_excluding.py +43 -0
  262. lightly_studio/resolvers/metadata_resolver/__init__.py +15 -0
  263. lightly_studio/resolvers/metadata_resolver/metadata_filter.py +163 -0
  264. lightly_studio/resolvers/metadata_resolver/sample/__init__.py +21 -0
  265. lightly_studio/resolvers/metadata_resolver/sample/bulk_update_metadata.py +46 -0
  266. lightly_studio/resolvers/metadata_resolver/sample/get_by_sample_id.py +24 -0
  267. lightly_studio/resolvers/metadata_resolver/sample/get_metadata_info.py +104 -0
  268. lightly_studio/resolvers/metadata_resolver/sample/get_value_for_sample.py +27 -0
  269. lightly_studio/resolvers/metadata_resolver/sample/set_value_for_sample.py +53 -0
  270. lightly_studio/resolvers/sample_embedding_resolver.py +132 -0
  271. lightly_studio/resolvers/sample_resolver/__init__.py +17 -0
  272. lightly_studio/resolvers/sample_resolver/count_by_dataset_id.py +16 -0
  273. lightly_studio/resolvers/sample_resolver/create.py +16 -0
  274. lightly_studio/resolvers/sample_resolver/create_many.py +25 -0
  275. lightly_studio/resolvers/sample_resolver/get_by_id.py +14 -0
  276. lightly_studio/resolvers/sample_resolver/get_filtered_samples.py +56 -0
  277. lightly_studio/resolvers/sample_resolver/get_many_by_id.py +22 -0
  278. lightly_studio/resolvers/sample_resolver/sample_filter.py +74 -0
  279. lightly_studio/resolvers/settings_resolver.py +62 -0
  280. lightly_studio/resolvers/tag_resolver.py +299 -0
  281. lightly_studio/resolvers/twodim_embedding_resolver.py +119 -0
  282. lightly_studio/resolvers/video_frame_resolver/__init__.py +23 -0
  283. lightly_studio/resolvers/video_frame_resolver/count_video_frames_annotations.py +83 -0
  284. lightly_studio/resolvers/video_frame_resolver/create_many.py +57 -0
  285. lightly_studio/resolvers/video_frame_resolver/get_all_by_dataset_id.py +63 -0
  286. lightly_studio/resolvers/video_frame_resolver/get_by_id.py +13 -0
  287. lightly_studio/resolvers/video_frame_resolver/get_table_fields_bounds.py +44 -0
  288. lightly_studio/resolvers/video_frame_resolver/video_frame_annotations_counter_filter.py +47 -0
  289. lightly_studio/resolvers/video_frame_resolver/video_frame_filter.py +57 -0
  290. lightly_studio/resolvers/video_resolver/__init__.py +27 -0
  291. lightly_studio/resolvers/video_resolver/count_video_frame_annotations_by_video_dataset.py +86 -0
  292. lightly_studio/resolvers/video_resolver/create_many.py +58 -0
  293. lightly_studio/resolvers/video_resolver/filter_new_paths.py +33 -0
  294. lightly_studio/resolvers/video_resolver/get_all_by_dataset_id.py +181 -0
  295. lightly_studio/resolvers/video_resolver/get_by_id.py +22 -0
  296. lightly_studio/resolvers/video_resolver/get_table_fields_bounds.py +72 -0
  297. lightly_studio/resolvers/video_resolver/get_view_by_id.py +52 -0
  298. lightly_studio/resolvers/video_resolver/video_count_annotations_filter.py +50 -0
  299. lightly_studio/resolvers/video_resolver/video_filter.py +98 -0
  300. lightly_studio/selection/__init__.py +1 -0
  301. lightly_studio/selection/mundig.py +143 -0
  302. lightly_studio/selection/select.py +203 -0
  303. lightly_studio/selection/select_via_db.py +273 -0
  304. lightly_studio/selection/selection_config.py +49 -0
  305. lightly_studio/services/annotations_service/__init__.py +33 -0
  306. lightly_studio/services/annotations_service/create_annotation.py +64 -0
  307. lightly_studio/services/annotations_service/delete_annotation.py +22 -0
  308. lightly_studio/services/annotations_service/get_annotation_by_id.py +31 -0
  309. lightly_studio/services/annotations_service/update_annotation.py +54 -0
  310. lightly_studio/services/annotations_service/update_annotation_bounding_box.py +36 -0
  311. lightly_studio/services/annotations_service/update_annotation_label.py +48 -0
  312. lightly_studio/services/annotations_service/update_annotations.py +29 -0
  313. lightly_studio/setup_logging.py +59 -0
  314. lightly_studio/type_definitions.py +31 -0
  315. lightly_studio/utils/__init__.py +3 -0
  316. lightly_studio/utils/download.py +94 -0
  317. lightly_studio/vendor/__init__.py +1 -0
  318. lightly_studio/vendor/mobileclip/ACKNOWLEDGEMENTS +422 -0
  319. lightly_studio/vendor/mobileclip/LICENSE +31 -0
  320. lightly_studio/vendor/mobileclip/LICENSE_weights_data +50 -0
  321. lightly_studio/vendor/mobileclip/README.md +5 -0
  322. lightly_studio/vendor/mobileclip/__init__.py +96 -0
  323. lightly_studio/vendor/mobileclip/clip.py +77 -0
  324. lightly_studio/vendor/mobileclip/configs/mobileclip_b.json +18 -0
  325. lightly_studio/vendor/mobileclip/configs/mobileclip_s0.json +18 -0
  326. lightly_studio/vendor/mobileclip/configs/mobileclip_s1.json +18 -0
  327. lightly_studio/vendor/mobileclip/configs/mobileclip_s2.json +18 -0
  328. lightly_studio/vendor/mobileclip/image_encoder.py +67 -0
  329. lightly_studio/vendor/mobileclip/logger.py +154 -0
  330. lightly_studio/vendor/mobileclip/models/__init__.py +10 -0
  331. lightly_studio/vendor/mobileclip/models/mci.py +933 -0
  332. lightly_studio/vendor/mobileclip/models/vit.py +433 -0
  333. lightly_studio/vendor/mobileclip/modules/__init__.py +4 -0
  334. lightly_studio/vendor/mobileclip/modules/common/__init__.py +4 -0
  335. lightly_studio/vendor/mobileclip/modules/common/mobileone.py +341 -0
  336. lightly_studio/vendor/mobileclip/modules/common/transformer.py +451 -0
  337. lightly_studio/vendor/mobileclip/modules/image/__init__.py +4 -0
  338. lightly_studio/vendor/mobileclip/modules/image/image_projection.py +113 -0
  339. lightly_studio/vendor/mobileclip/modules/image/replknet.py +188 -0
  340. lightly_studio/vendor/mobileclip/modules/text/__init__.py +4 -0
  341. lightly_studio/vendor/mobileclip/modules/text/repmixer.py +281 -0
  342. lightly_studio/vendor/mobileclip/modules/text/tokenizer.py +38 -0
  343. lightly_studio/vendor/mobileclip/text_encoder.py +245 -0
  344. lightly_studio/vendor/perception_encoder/LICENSE.PE +201 -0
  345. lightly_studio/vendor/perception_encoder/README.md +11 -0
  346. lightly_studio/vendor/perception_encoder/vision_encoder/__init__.py +0 -0
  347. lightly_studio/vendor/perception_encoder/vision_encoder/bpe_simple_vocab_16e6.txt.gz +0 -0
  348. lightly_studio/vendor/perception_encoder/vision_encoder/config.py +205 -0
  349. lightly_studio/vendor/perception_encoder/vision_encoder/config_src.py +264 -0
  350. lightly_studio/vendor/perception_encoder/vision_encoder/pe.py +766 -0
  351. lightly_studio/vendor/perception_encoder/vision_encoder/rope.py +352 -0
  352. lightly_studio/vendor/perception_encoder/vision_encoder/tokenizer.py +347 -0
  353. lightly_studio/vendor/perception_encoder/vision_encoder/transforms.py +36 -0
  354. lightly_studio-0.4.6.dist-info/METADATA +88 -0
  355. lightly_studio-0.4.6.dist-info/RECORD +356 -0
  356. lightly_studio-0.4.6.dist-info/WHEEL +4 -0
@@ -0,0 +1,96 @@
1
+ """This module contains the Tag model and related enumerations."""
2
+
3
+ from datetime import datetime, timezone
4
+ from typing import TYPE_CHECKING, List, Literal, Optional
5
+ from uuid import UUID, uuid4
6
+
7
+ from sqlalchemy import UniqueConstraint
8
+ from sqlalchemy.orm import Mapped
9
+ from sqlmodel import Field, Relationship, SQLModel, String
10
+
11
+ from lightly_studio.models.annotation.links import AnnotationTagLinkTable
12
+ from lightly_studio.models.sample import SampleTagLinkTable
13
+
14
+ if TYPE_CHECKING:
15
+ from lightly_studio.models.annotation.annotation_base import (
16
+ AnnotationBaseTable,
17
+ )
18
+ from lightly_studio.models.sample import SampleTable
19
+
20
+ else:
21
+ SampleTable = object
22
+ TagTable = object
23
+ AnnotationBaseTable = object
24
+
25
+
26
+ # TagKind is the kind of tag we support.
27
+ TagKind = Literal[
28
+ "sample",
29
+ "annotation",
30
+ ]
31
+
32
+
33
+ class TagBase(SQLModel):
34
+ """Base class for the Tag model."""
35
+
36
+ name: str
37
+ description: Optional[str] = ""
38
+ kind: TagKind = "sample"
39
+
40
+
41
+ class TagCreate(TagBase):
42
+ """Tag model when creating."""
43
+
44
+ dataset_id: UUID
45
+
46
+
47
+ class TagCreateBody(TagBase):
48
+ """Tag model when creating."""
49
+
50
+
51
+ class TagUpdate(TagBase):
52
+ """Tag model when updating."""
53
+
54
+
55
+ class TagUpdateBody(TagBase):
56
+ """Tag model when updating."""
57
+
58
+ dataset_id: Optional[UUID] = None
59
+
60
+
61
+ class TagView(TagBase):
62
+ """Tag model when retrieving."""
63
+
64
+ tag_id: UUID
65
+ kind: TagKind
66
+ created_at: datetime
67
+ updated_at: datetime
68
+
69
+
70
+ class TagTable(TagBase, table=True):
71
+ """This class defines the Tag model."""
72
+
73
+ __tablename__ = "tag"
74
+ # ensure there can only be one tag named "lightly_studio" per dataset
75
+ __table_args__ = (
76
+ UniqueConstraint("dataset_id", "kind", "name", name="unique_name_constraint"),
77
+ )
78
+ tag_id: UUID = Field(default_factory=uuid4, primary_key=True)
79
+ dataset_id: UUID
80
+ kind: TagKind = Field(sa_type=String)
81
+ created_at: datetime = Field(default_factory=lambda: datetime.now(timezone.utc), index=True)
82
+ updated_at: datetime = Field(
83
+ default_factory=lambda: datetime.now(timezone.utc),
84
+ )
85
+
86
+ """The sample ids associated with the tag."""
87
+ samples: Mapped[List["SampleTable"]] = Relationship(
88
+ back_populates="tags",
89
+ link_model=SampleTagLinkTable,
90
+ )
91
+
92
+ """The annotation ids associated with the tag (legacy bounding box)."""
93
+ annotations: Mapped[List["AnnotationBaseTable"]] = Relationship(
94
+ back_populates="tags",
95
+ link_model=AnnotationTagLinkTable,
96
+ )
@@ -0,0 +1,16 @@
1
+ """Database table storing cached 2D embeddings."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from sqlalchemy import ARRAY, Float
6
+ from sqlmodel import Column, Field, SQLModel
7
+
8
+
9
+ class TwoDimEmbeddingTable(SQLModel, table=True):
10
+ """Persisted 2D embedding projection identified by a deterministic hash."""
11
+
12
+ __tablename__ = "two_dim_embeddings"
13
+
14
+ hash: str = Field(primary_key=True)
15
+ x: list[float] = Field(sa_column=Column(ARRAY(Float)))
16
+ y: list[float] = Field(sa_column=Column(ARRAY(Float)))
@@ -0,0 +1,161 @@
1
+ """This module defines the Video and VideoFrame model for the application."""
2
+
3
+ from typing import TYPE_CHECKING, List, Optional
4
+ from uuid import UUID
5
+
6
+ from pydantic import BaseModel, ConfigDict
7
+ from pydantic import Field as PydanticField
8
+ from sqlalchemy.orm import Mapped
9
+ from sqlmodel import Field, Relationship, SQLModel
10
+
11
+ from lightly_studio.models.range import FloatRange, IntRange
12
+
13
+ if TYPE_CHECKING:
14
+ from lightly_studio.models.annotation.annotation_base import (
15
+ AnnotationBaseTable,
16
+ )
17
+ from lightly_studio.models.sample import SampleTable, SampleView
18
+
19
+ else:
20
+ AnnotationBaseTable = object
21
+ SampleTable = object
22
+ SampleView = object
23
+
24
+
25
+ class VideoBase(SQLModel):
26
+ """Base class for the Video model."""
27
+
28
+ """The width of the video in pixels."""
29
+ width: int
30
+
31
+ """The height of the video in pixels."""
32
+ height: int
33
+
34
+ """The duration of the video in seconds."""
35
+ duration_s: Optional[float] = Field(default=None)
36
+
37
+ """The fps of the video."""
38
+ fps: float
39
+
40
+ """The file name of the video."""
41
+ file_name: str
42
+
43
+ """The path of the video."""
44
+ file_path_abs: str = Field(default=None)
45
+
46
+
47
+ class VideoCreate(VideoBase):
48
+ """Video class when inserting."""
49
+
50
+
51
+ class VideoTable(VideoBase, table=True):
52
+ """This class defines the Video ORM table."""
53
+
54
+ __tablename__ = "video"
55
+ sample_id: UUID = Field(foreign_key="sample.sample_id", primary_key=True)
56
+ frames: Mapped[List["VideoFrameTable"]] = Relationship(back_populates="video")
57
+ sample: Mapped["SampleTable"] = Relationship()
58
+
59
+
60
+ class VideoView(SQLModel):
61
+ """Video class when retrieving."""
62
+
63
+ width: int
64
+ height: int
65
+ duration_s: Optional[float] = None
66
+ fps: float
67
+ file_name: str
68
+ file_path_abs: str
69
+ sample_id: UUID
70
+ sample: SampleView
71
+ frame: Optional["FrameView"] = None
72
+
73
+
74
+ class VideoViewsWithCount(BaseModel):
75
+ """Response model for counted videos."""
76
+
77
+ model_config = ConfigDict(populate_by_name=True)
78
+
79
+ samples: List[VideoView] = PydanticField(..., alias="data")
80
+ total_count: int
81
+ next_cursor: Optional[int] = PydanticField(None, alias="nextCursor")
82
+
83
+
84
+ class VideoFrameBase(SQLModel):
85
+ """Base class for the VideoFrame model."""
86
+
87
+ """The frame number of the video frame."""
88
+ frame_number: int
89
+
90
+ """Presentation timestamp in the video's time_base and in seconds."""
91
+ frame_timestamp_pts: int
92
+ frame_timestamp_s: float
93
+
94
+ """The video ID to which the video frame belongs."""
95
+ parent_sample_id: UUID = Field(default=None, foreign_key="video.sample_id")
96
+
97
+ """The rotation of the encoded frame in degrees.
98
+
99
+ Valid values are 0, 90, 180, 270. This field is needed for video access with OpenCV
100
+ which does not read rotation metadata correctly."""
101
+ rotation_deg: int = 0
102
+
103
+
104
+ class VideoFrameCreate(VideoFrameBase):
105
+ """VideoFrame class when inserting."""
106
+
107
+
108
+ class VideoFrameTable(VideoFrameBase, table=True):
109
+ """This class defines the VideoFrame model."""
110
+
111
+ __tablename__ = "video_frame"
112
+ sample_id: UUID = Field(foreign_key="sample.sample_id", primary_key=True)
113
+
114
+ sample: Mapped["SampleTable"] = Relationship()
115
+ video: Mapped["VideoTable"] = Relationship(back_populates="frames")
116
+
117
+
118
+ class VideoFrameView(SQLModel):
119
+ """VideoFrame class when retrieving."""
120
+
121
+ frame_number: int
122
+ frame_timestamp_s: float
123
+ sample_id: UUID
124
+
125
+ # Video metadata routed from parent video
126
+ video: VideoView
127
+ sample: "SampleView"
128
+
129
+
130
+ class FrameView(SQLModel):
131
+ """VideoFrame class when retrieving."""
132
+
133
+ frame_number: int
134
+ frame_timestamp_s: float
135
+ sample_id: UUID
136
+ sample: SampleView
137
+
138
+
139
+ class VideoFrameViewsWithCount(BaseModel):
140
+ """Response model for counted video frames."""
141
+
142
+ model_config = ConfigDict(populate_by_name=True)
143
+
144
+ samples: List[VideoFrameView] = PydanticField(..., alias="data")
145
+ total_count: int
146
+ next_cursor: Optional[int] = PydanticField(None, alias="nextCursor")
147
+
148
+
149
+ class VideoFieldsBoundsView(BaseModel):
150
+ """Response model for the video fields bounds."""
151
+
152
+ width: IntRange
153
+ height: IntRange
154
+ duration_s: FloatRange
155
+ fps: FloatRange
156
+
157
+
158
+ class VideoFrameFieldsBoundsView(BaseModel):
159
+ """Response model for the video frame fields bounds."""
160
+
161
+ frame_number: IntRange
File without changes
@@ -0,0 +1,60 @@
1
+ """Base operator class for LightlyStudio plugins."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from dataclasses import dataclass
7
+ from typing import Any
8
+ from uuid import UUID
9
+
10
+ from sqlmodel import Session
11
+
12
+ from lightly_studio.plugins.parameter import BaseParameter
13
+
14
+
15
+ @dataclass
16
+ class OperatorResult:
17
+ """Result returned by operator execution."""
18
+
19
+ success: bool
20
+ message: str
21
+
22
+
23
+ class BaseOperator(ABC):
24
+ """Base class for all operators."""
25
+
26
+ @property
27
+ @abstractmethod
28
+ def name(self) -> str:
29
+ """Return the operator name."""
30
+
31
+ @property
32
+ @abstractmethod
33
+ def description(self) -> str:
34
+ """Return the description of the operator."""
35
+
36
+ @property
37
+ @abstractmethod
38
+ def parameters(self) -> list[BaseParameter]:
39
+ """Return the list of parameters this operator expects."""
40
+
41
+ @abstractmethod
42
+ def execute(
43
+ self,
44
+ *,
45
+ session: Session,
46
+ dataset_id: UUID,
47
+ parameters: dict[str, Any],
48
+ ) -> OperatorResult:
49
+ """Execute the operator with the given parameters.
50
+
51
+ Args:
52
+ session: Database session.
53
+ dataset_id: ID of the dataset to operate on.
54
+ parameters: Parameters passed to the operator.
55
+
56
+ Returns:
57
+ Dictionary with 'success' (bool) and 'message' (str) keys.
58
+ """
59
+ # TODO (Jonas 11/2025): The parameters dict should be validated against self.parameters,
60
+ # for now we leave it to the operator implementation.
@@ -0,0 +1,47 @@
1
+ """Operator registry for LightlyStudio plugins."""
2
+
3
+ from __future__ import annotations
4
+
5
+ import uuid
6
+ from dataclasses import dataclass
7
+
8
+ from .base_operator import BaseOperator
9
+
10
+
11
+ @dataclass
12
+ class RegisteredOperatorMetadata:
13
+ """Meta data for a registered operator."""
14
+
15
+ operator_id: str
16
+ name: str
17
+
18
+
19
+ class OperatorRegistry:
20
+ """Registry for managing operators."""
21
+
22
+ def __init__(self) -> None:
23
+ """Initialize the operator registry."""
24
+ self._operators: dict[str, BaseOperator] = {}
25
+
26
+ def register(self, operator: BaseOperator) -> None:
27
+ """Register an operator."""
28
+ operator_id = str(uuid.uuid4())
29
+ self._operators[operator_id] = operator
30
+
31
+ def get_all_metadata(self) -> list[RegisteredOperatorMetadata]:
32
+ """Get all registered operators with their names."""
33
+ return [
34
+ RegisteredOperatorMetadata(
35
+ operator_id=operator_id,
36
+ name=operator.name,
37
+ )
38
+ for operator_id, operator in self._operators.items()
39
+ ]
40
+
41
+ def get_by_id(self, operator_id: str) -> BaseOperator | None:
42
+ """Get an operator by its ID."""
43
+ return self._operators.get(operator_id)
44
+
45
+
46
+ # Global registry instance
47
+ operator_registry = OperatorRegistry()
@@ -0,0 +1,70 @@
1
+ """Parameter for operators for LightlyStudio plugins."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from abc import ABC, abstractmethod
6
+ from dataclasses import dataclass
7
+ from typing import Any, Generic, TypeVar, cast
8
+
9
+ T = TypeVar("T")
10
+
11
+
12
+ @dataclass
13
+ class BaseParameter(ABC):
14
+ """Base parameter definition shared across operator parameters."""
15
+
16
+ name: str
17
+ description: str = ""
18
+ default: Any = None
19
+ required: bool = True
20
+ param_type: str | None = None
21
+
22
+ def __post_init__(self) -> None:
23
+ """Run value validation once the dataclass is initialized."""
24
+ if self.default is not None:
25
+ self.default = self._validate(self.default)
26
+
27
+ @abstractmethod
28
+ def _validate(self, value: Any) -> Any:
29
+ """Validate the parameter value."""
30
+
31
+
32
+ class BuiltinParameter(BaseParameter, Generic[T]):
33
+ """Represents a built-in operator parameter."""
34
+
35
+ def __post_init__(self) -> None:
36
+ """Set up type information and validate default value."""
37
+ if not hasattr(self, "_parameter_type") or self._parameter_type is None:
38
+ raise NotImplementedError("Subclasses must define _parameter_type class attribute")
39
+ self._type = self._parameter_type
40
+ self.param_type = self._parameter_type.__name__
41
+ super().__post_init__()
42
+
43
+ def _validate(self, value: T) -> T:
44
+ if isinstance(value, self._type):
45
+ return cast(T, value)
46
+ raise TypeError(f"Expected value of type '{self._type.__name__}' but got {type(value)}'")
47
+
48
+
49
+ class IntParameter(BuiltinParameter[int]):
50
+ """Represents an integer operator parameter."""
51
+
52
+ _parameter_type = int
53
+
54
+
55
+ class FloatParameter(BuiltinParameter[float]):
56
+ """Represents a float operator parameter."""
57
+
58
+ _parameter_type = float
59
+
60
+
61
+ class BoolParameter(BuiltinParameter[bool]):
62
+ """Represents a boolean operator parameter."""
63
+
64
+ _parameter_type = bool
65
+
66
+
67
+ class StringParameter(BuiltinParameter[str]):
68
+ """Represents a string operator parameter."""
69
+
70
+ _parameter_type = str
File without changes
File without changes
@@ -0,0 +1,22 @@
1
+ """Handler for database operations related to annotation labels."""
2
+
3
+ from .create import create
4
+ from .delete import delete
5
+ from .get_all import get_all, get_all_sorted_alphabetically
6
+ from .get_by_id import get_by_id
7
+ from .get_by_ids import get_by_ids
8
+ from .get_by_label_name import get_by_label_name
9
+ from .names_by_ids import names_by_ids
10
+ from .update import update
11
+
12
+ __all__ = [
13
+ "create",
14
+ "delete",
15
+ "get_all",
16
+ "get_all_sorted_alphabetically",
17
+ "get_by_id",
18
+ "get_by_ids",
19
+ "get_by_label_name",
20
+ "names_by_ids",
21
+ "update",
22
+ ]
@@ -0,0 +1,27 @@
1
+ """Create annotation label functionality."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from sqlmodel import Session
6
+
7
+ from lightly_studio.models.annotation_label import (
8
+ AnnotationLabelCreate,
9
+ AnnotationLabelTable,
10
+ )
11
+
12
+
13
+ def create(session: Session, label: AnnotationLabelCreate) -> AnnotationLabelTable:
14
+ """Create a new annotation label in the database.
15
+
16
+ Args:
17
+ session (Session): The database session.
18
+ label (AnnotationLabelCreate): The annotation label data to be created.
19
+
20
+ Returns:
21
+ AnnotationLabelTable: The newly created annotation label record.
22
+ """
23
+ db_label = AnnotationLabelTable.model_validate(label)
24
+ session.add(db_label)
25
+ session.commit()
26
+ session.refresh(db_label)
27
+ return db_label
@@ -0,0 +1,28 @@
1
+ """Delete annotation label functionality."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from uuid import UUID
6
+
7
+ from sqlmodel import Session
8
+
9
+ from .get_by_id import get_by_id
10
+
11
+
12
+ def delete(session: Session, label_id: UUID) -> bool:
13
+ """Delete an annotation label.
14
+
15
+ Args:
16
+ session (Session): The database session.
17
+ label_id (UUID): The unique identifier of the annotation label.
18
+
19
+ Returns:
20
+ bool: True if the label was deleted, False if the label was not found.
21
+ """
22
+ label = get_by_id(session=session, label_id=label_id)
23
+ if not label:
24
+ return False
25
+
26
+ session.delete(label)
27
+ session.commit()
28
+ return True
@@ -0,0 +1,37 @@
1
+ """Get all annotation labels functionality."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from sqlmodel import Session, col, select
6
+
7
+ from lightly_studio.models.annotation_label import AnnotationLabelTable
8
+
9
+
10
+ def get_all(session: Session) -> list[AnnotationLabelTable]:
11
+ """Retrieve all annotation labels.
12
+
13
+ Args:
14
+ session (Session): The database session.
15
+
16
+ Returns:
17
+ list[AnnotationLabelTable]: A list of annotation labels.
18
+ """
19
+ labels = session.exec(
20
+ select(AnnotationLabelTable).order_by(col(AnnotationLabelTable.created_at).asc())
21
+ ).all()
22
+ return list(labels) if labels else []
23
+
24
+
25
+ def get_all_sorted_alphabetically(session: Session) -> list[AnnotationLabelTable]:
26
+ """Retrieve all annotation labels sorted alphabetically.
27
+
28
+ Args:
29
+ session (Session): The database session.
30
+
31
+ Returns:
32
+ list[AnnotationLabelTable]: A list of annotation labels.
33
+ """
34
+ labels = session.exec(
35
+ select(AnnotationLabelTable).order_by(col(AnnotationLabelTable.annotation_label_name).asc())
36
+ ).all()
37
+ return list(labels) if labels else []
@@ -0,0 +1,24 @@
1
+ """Get annotation label by ID functionality."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from uuid import UUID
6
+
7
+ from sqlmodel import Session, select
8
+
9
+ from lightly_studio.models.annotation_label import AnnotationLabelTable
10
+
11
+
12
+ def get_by_id(session: Session, label_id: UUID) -> AnnotationLabelTable | None:
13
+ """Retrieve a single annotation label by ID.
14
+
15
+ Args:
16
+ session (Session): The database session used to execute the query.
17
+ label_id (UUID): The unique identifier of the annotation label to get.
18
+
19
+ Returns:
20
+ AnnotationLabelTable | None: The annotation label if found, or None.
21
+ """
22
+ return session.exec(
23
+ select(AnnotationLabelTable).where(AnnotationLabelTable.annotation_label_id == label_id)
24
+ ).one_or_none()
@@ -0,0 +1,25 @@
1
+ """Get annotation labels by IDs functionality."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Sequence
6
+ from uuid import UUID
7
+
8
+ from sqlmodel import Session, col, select
9
+
10
+ from lightly_studio.models.annotation_label import AnnotationLabelTable
11
+
12
+
13
+ def get_by_ids(session: Session, ids: Sequence[UUID]) -> list[AnnotationLabelTable]:
14
+ """Retrieve annotation labels by their IDs.
15
+
16
+ Output order matches the input order.
17
+ """
18
+ results = session.exec(
19
+ select(AnnotationLabelTable).where(
20
+ col(AnnotationLabelTable.annotation_label_id).in_(list(ids))
21
+ )
22
+ ).all()
23
+ # Return labels in the same order as the input ids.
24
+ label_map = {label.annotation_label_id: label for label in results}
25
+ return [label_map[id_] for id_ in ids if id_ in label_map]
@@ -0,0 +1,24 @@
1
+ """Handler for database operations related to annotation labels."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from sqlmodel import Session, select
6
+
7
+ from lightly_studio.models.annotation_label import (
8
+ AnnotationLabelTable,
9
+ )
10
+
11
+
12
+ def get_by_label_name(session: Session, label_name: str) -> AnnotationLabelTable | None:
13
+ """Retrieve a single annotation label by its name.
14
+
15
+ Args:
16
+ session: The database session to use for the query.
17
+ label_name: The name of the annotation label to retrieve.
18
+
19
+ Returns:
20
+ The AnnotationLabelTable instance if found, None otherwise.
21
+ """
22
+ return session.exec(
23
+ select(AnnotationLabelTable).where(AnnotationLabelTable.annotation_label_name == label_name)
24
+ ).one_or_none()
@@ -0,0 +1,25 @@
1
+ """Get annotation label names by IDs functionality."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from typing import Sequence
6
+ from uuid import UUID
7
+
8
+ from sqlmodel import Session
9
+
10
+ from .get_by_ids import get_by_ids
11
+
12
+
13
+ def names_by_ids(session: Session, ids: Sequence[UUID]) -> dict[str, str]:
14
+ """Return a dictionary mapping annotation label IDs to their names.
15
+
16
+ Args:
17
+ session (Session): The database session used to query the labels.
18
+ ids (Sequence[UUID]): A sequence of UUIDs of the annotation label IDs.
19
+
20
+ Returns:
21
+ dict[str, str]: A dictionary with string representations of the UUIDs
22
+ and the values are the corresponding annotation label names.
23
+ """
24
+ labels = get_by_ids(session=session, ids=ids)
25
+ return {str(label.annotation_label_id): label.annotation_label_name for label in labels}