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.
- lightly_studio/__init__.py +12 -0
- lightly_studio/api/__init__.py +0 -0
- lightly_studio/api/app.py +131 -0
- lightly_studio/api/cache.py +77 -0
- lightly_studio/api/db_tables.py +35 -0
- lightly_studio/api/features.py +5 -0
- lightly_studio/api/routes/api/annotation.py +305 -0
- lightly_studio/api/routes/api/annotation_label.py +87 -0
- lightly_studio/api/routes/api/annotations/__init__.py +7 -0
- lightly_studio/api/routes/api/annotations/create_annotation.py +52 -0
- lightly_studio/api/routes/api/caption.py +100 -0
- lightly_studio/api/routes/api/classifier.py +384 -0
- lightly_studio/api/routes/api/dataset.py +191 -0
- lightly_studio/api/routes/api/dataset_tag.py +266 -0
- lightly_studio/api/routes/api/embeddings2d.py +90 -0
- lightly_studio/api/routes/api/exceptions.py +114 -0
- lightly_studio/api/routes/api/export.py +114 -0
- lightly_studio/api/routes/api/features.py +17 -0
- lightly_studio/api/routes/api/frame.py +241 -0
- lightly_studio/api/routes/api/image.py +155 -0
- lightly_studio/api/routes/api/metadata.py +161 -0
- lightly_studio/api/routes/api/operator.py +75 -0
- lightly_studio/api/routes/api/sample.py +103 -0
- lightly_studio/api/routes/api/selection.py +87 -0
- lightly_studio/api/routes/api/settings.py +41 -0
- lightly_studio/api/routes/api/status.py +19 -0
- lightly_studio/api/routes/api/text_embedding.py +50 -0
- lightly_studio/api/routes/api/validators.py +17 -0
- lightly_studio/api/routes/api/video.py +133 -0
- lightly_studio/api/routes/healthz.py +13 -0
- lightly_studio/api/routes/images.py +104 -0
- lightly_studio/api/routes/video_frames_media.py +116 -0
- lightly_studio/api/routes/video_media.py +223 -0
- lightly_studio/api/routes/webapp.py +51 -0
- lightly_studio/api/server.py +94 -0
- lightly_studio/core/__init__.py +0 -0
- lightly_studio/core/add_samples.py +533 -0
- lightly_studio/core/add_videos.py +294 -0
- lightly_studio/core/dataset.py +780 -0
- lightly_studio/core/dataset_query/__init__.py +14 -0
- lightly_studio/core/dataset_query/boolean_expression.py +67 -0
- lightly_studio/core/dataset_query/dataset_query.py +317 -0
- lightly_studio/core/dataset_query/field.py +113 -0
- lightly_studio/core/dataset_query/field_expression.py +79 -0
- lightly_studio/core/dataset_query/match_expression.py +23 -0
- lightly_studio/core/dataset_query/order_by.py +79 -0
- lightly_studio/core/dataset_query/sample_field.py +37 -0
- lightly_studio/core/dataset_query/tags_expression.py +46 -0
- lightly_studio/core/image_sample.py +36 -0
- lightly_studio/core/loading_log.py +56 -0
- lightly_studio/core/sample.py +291 -0
- lightly_studio/core/start_gui.py +54 -0
- lightly_studio/core/video_sample.py +38 -0
- lightly_studio/dataset/__init__.py +0 -0
- lightly_studio/dataset/edge_embedding_generator.py +155 -0
- lightly_studio/dataset/embedding_generator.py +129 -0
- lightly_studio/dataset/embedding_manager.py +349 -0
- lightly_studio/dataset/env.py +20 -0
- lightly_studio/dataset/file_utils.py +49 -0
- lightly_studio/dataset/fsspec_lister.py +275 -0
- lightly_studio/dataset/mobileclip_embedding_generator.py +158 -0
- lightly_studio/dataset/perception_encoder_embedding_generator.py +260 -0
- lightly_studio/db_manager.py +166 -0
- lightly_studio/dist_lightly_studio_view_app/_app/env.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/0.GcXvs2l7.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/12.Dx6SXgAb.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/17.9X9_k6TP.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/18.BxiimdIO.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/2.CkOblLn7.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/ClassifierSamplesGrid.BJbCDlvs.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/LightlyLogo.BNjCIww-.png +0 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Bold.DGvYQtcs.ttf +0 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Italic-VariableFont_wdth_wght.B4AZ-wl6.ttf +0 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Medium.DVUZMR_6.ttf +0 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-Regular.DxJTClRG.ttf +0 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-SemiBold.D3TTYgdB.ttf +0 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/OpenSans-VariableFont_wdth_wght.BZBpG5Iz.ttf +0 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.CefECEWA.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_layout.D5tDcjY-.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_page.9X9_k6TP.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_page.BxiimdIO.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/_page.Dx6SXgAb.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/assets/transform._-1mPSEI.css +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/0dDyq72A.js +20 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/69_IOA4Y.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BK4An2kI.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BRmB-kJ9.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/B_1cpokE.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BiqpDEr0.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BpLiSKgx.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/BscxbINH.js +39 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C1FmrZbK.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C80h3dJx.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/C8mfFM-u.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CGY1p9L4.js +517 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/COfLknXM.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CWj6FrbW.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CYgJF_JY.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CmLg0ys7.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/CvGjimpO.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D3RDXHoj.js +39 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D4y7iiT3.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D9SC3jBb.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DCuAdx1Q.js +20 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DDBy-_jD.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DIeogL5L.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DL9a7v5o.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DSKECuqX.js +39 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/D_FFv0Oe.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DiZ5o5vz.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DkbXUtyG.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DmK2hulV.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DqnHaLTj.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DtWZc_tl.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DuUalyFS.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/DwIonDAZ.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/Il-mSPmK.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/KNLP4aJU.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/KjYeVjkE.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/MErlcOXj.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/VRI4prUD.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/VYb2dkNs.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/VqWvU2yF.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/dHC3otuL.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/da7Oy_lO.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/eAy8rZzC.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/erjNR5MX.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/f1oG3eFE.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/rsLi1iKv.js +20 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/rwuuBP9f.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/chunks/xGHZQ1pe.js +3 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/app.DrTRUgT3.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/entry/start.BK5EOJl2.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/0.CIvTuljF.js +4 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/1.UBvSzxdA.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/10.CQ_tiLJa.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/11.KqkAcaxW.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/12.DoYsmxQc.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/13.571n2LZA.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/14.DGs689M-.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/15.CWG1ehzT.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/16.Dpq6jbSh.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/17.B5AZbHUU.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/18.CBga8cnq.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/2.D2HXgz-8.js +1090 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/3.f4HAg-y3.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/4.BKF4xuKQ.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/5.BAE0Pm_f.js +39 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/6.CouWWpzA.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/7.UBHT0ktp.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/8.FiYNElcc.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/nodes/9.B3-UaT23.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/clustering.worker-DKqeLtG0.js +2 -0
- lightly_studio/dist_lightly_studio_view_app/_app/immutable/workers/search.worker-vNSty3B0.js +1 -0
- lightly_studio/dist_lightly_studio_view_app/_app/version.json +1 -0
- lightly_studio/dist_lightly_studio_view_app/apple-touch-icon-precomposed.png +0 -0
- lightly_studio/dist_lightly_studio_view_app/apple-touch-icon.png +0 -0
- lightly_studio/dist_lightly_studio_view_app/favicon.png +0 -0
- lightly_studio/dist_lightly_studio_view_app/index.html +45 -0
- lightly_studio/errors.py +5 -0
- lightly_studio/examples/example.py +25 -0
- lightly_studio/examples/example_coco.py +27 -0
- lightly_studio/examples/example_coco_caption.py +29 -0
- lightly_studio/examples/example_metadata.py +369 -0
- lightly_studio/examples/example_operators.py +111 -0
- lightly_studio/examples/example_selection.py +28 -0
- lightly_studio/examples/example_split_work.py +48 -0
- lightly_studio/examples/example_video.py +22 -0
- lightly_studio/examples/example_video_annotations.py +157 -0
- lightly_studio/examples/example_yolo.py +22 -0
- lightly_studio/export/coco_captions.py +69 -0
- lightly_studio/export/export_dataset.py +104 -0
- lightly_studio/export/lightly_studio_label_input.py +120 -0
- lightly_studio/export_schema.py +18 -0
- lightly_studio/export_version.py +57 -0
- lightly_studio/few_shot_classifier/__init__.py +0 -0
- lightly_studio/few_shot_classifier/classifier.py +80 -0
- lightly_studio/few_shot_classifier/classifier_manager.py +644 -0
- lightly_studio/few_shot_classifier/random_forest_classifier.py +495 -0
- lightly_studio/metadata/complex_metadata.py +47 -0
- lightly_studio/metadata/compute_similarity.py +84 -0
- lightly_studio/metadata/compute_typicality.py +67 -0
- lightly_studio/metadata/gps_coordinate.py +41 -0
- lightly_studio/metadata/metadata_protocol.py +17 -0
- lightly_studio/models/__init__.py +1 -0
- lightly_studio/models/annotation/__init__.py +0 -0
- lightly_studio/models/annotation/annotation_base.py +303 -0
- lightly_studio/models/annotation/instance_segmentation.py +56 -0
- lightly_studio/models/annotation/links.py +17 -0
- lightly_studio/models/annotation/object_detection.py +47 -0
- lightly_studio/models/annotation/semantic_segmentation.py +44 -0
- lightly_studio/models/annotation_label.py +47 -0
- lightly_studio/models/caption.py +49 -0
- lightly_studio/models/classifier.py +20 -0
- lightly_studio/models/dataset.py +70 -0
- lightly_studio/models/embedding_model.py +30 -0
- lightly_studio/models/image.py +96 -0
- lightly_studio/models/metadata.py +208 -0
- lightly_studio/models/range.py +17 -0
- lightly_studio/models/sample.py +154 -0
- lightly_studio/models/sample_embedding.py +36 -0
- lightly_studio/models/settings.py +69 -0
- lightly_studio/models/tag.py +96 -0
- lightly_studio/models/two_dim_embedding.py +16 -0
- lightly_studio/models/video.py +161 -0
- lightly_studio/plugins/__init__.py +0 -0
- lightly_studio/plugins/base_operator.py +60 -0
- lightly_studio/plugins/operator_registry.py +47 -0
- lightly_studio/plugins/parameter.py +70 -0
- lightly_studio/py.typed +0 -0
- lightly_studio/resolvers/__init__.py +0 -0
- lightly_studio/resolvers/annotation_label_resolver/__init__.py +22 -0
- lightly_studio/resolvers/annotation_label_resolver/create.py +27 -0
- lightly_studio/resolvers/annotation_label_resolver/delete.py +28 -0
- lightly_studio/resolvers/annotation_label_resolver/get_all.py +37 -0
- lightly_studio/resolvers/annotation_label_resolver/get_by_id.py +24 -0
- lightly_studio/resolvers/annotation_label_resolver/get_by_ids.py +25 -0
- lightly_studio/resolvers/annotation_label_resolver/get_by_label_name.py +24 -0
- lightly_studio/resolvers/annotation_label_resolver/names_by_ids.py +25 -0
- lightly_studio/resolvers/annotation_label_resolver/update.py +38 -0
- lightly_studio/resolvers/annotation_resolver/__init__.py +40 -0
- lightly_studio/resolvers/annotation_resolver/count_annotations_by_dataset.py +129 -0
- lightly_studio/resolvers/annotation_resolver/create_many.py +124 -0
- lightly_studio/resolvers/annotation_resolver/delete_annotation.py +87 -0
- lightly_studio/resolvers/annotation_resolver/delete_annotations.py +60 -0
- lightly_studio/resolvers/annotation_resolver/get_all.py +85 -0
- lightly_studio/resolvers/annotation_resolver/get_all_with_payload.py +179 -0
- lightly_studio/resolvers/annotation_resolver/get_by_id.py +34 -0
- lightly_studio/resolvers/annotation_resolver/get_by_id_with_payload.py +130 -0
- lightly_studio/resolvers/annotation_resolver/update_annotation_label.py +142 -0
- lightly_studio/resolvers/annotation_resolver/update_bounding_box.py +68 -0
- lightly_studio/resolvers/annotations/__init__.py +1 -0
- lightly_studio/resolvers/annotations/annotations_filter.py +88 -0
- lightly_studio/resolvers/caption_resolver.py +129 -0
- lightly_studio/resolvers/dataset_resolver/__init__.py +55 -0
- lightly_studio/resolvers/dataset_resolver/check_dataset_type.py +29 -0
- lightly_studio/resolvers/dataset_resolver/create.py +20 -0
- lightly_studio/resolvers/dataset_resolver/delete.py +20 -0
- lightly_studio/resolvers/dataset_resolver/export.py +267 -0
- lightly_studio/resolvers/dataset_resolver/get_all.py +19 -0
- lightly_studio/resolvers/dataset_resolver/get_by_id.py +16 -0
- lightly_studio/resolvers/dataset_resolver/get_by_name.py +12 -0
- lightly_studio/resolvers/dataset_resolver/get_dataset_details.py +27 -0
- lightly_studio/resolvers/dataset_resolver/get_hierarchy.py +31 -0
- lightly_studio/resolvers/dataset_resolver/get_or_create_child_dataset.py +58 -0
- lightly_studio/resolvers/dataset_resolver/get_parent_dataset_by_sample_id.py +27 -0
- lightly_studio/resolvers/dataset_resolver/get_parent_dataset_id.py +22 -0
- lightly_studio/resolvers/dataset_resolver/get_root_dataset.py +61 -0
- lightly_studio/resolvers/dataset_resolver/get_root_datasets_overview.py +41 -0
- lightly_studio/resolvers/dataset_resolver/update.py +25 -0
- lightly_studio/resolvers/embedding_model_resolver.py +120 -0
- lightly_studio/resolvers/image_filter.py +50 -0
- lightly_studio/resolvers/image_resolver/__init__.py +21 -0
- lightly_studio/resolvers/image_resolver/create_many.py +52 -0
- lightly_studio/resolvers/image_resolver/delete.py +20 -0
- lightly_studio/resolvers/image_resolver/filter_new_paths.py +23 -0
- lightly_studio/resolvers/image_resolver/get_all_by_dataset_id.py +117 -0
- lightly_studio/resolvers/image_resolver/get_by_id.py +14 -0
- lightly_studio/resolvers/image_resolver/get_dimension_bounds.py +75 -0
- lightly_studio/resolvers/image_resolver/get_many_by_id.py +22 -0
- lightly_studio/resolvers/image_resolver/get_samples_excluding.py +43 -0
- lightly_studio/resolvers/metadata_resolver/__init__.py +15 -0
- lightly_studio/resolvers/metadata_resolver/metadata_filter.py +163 -0
- lightly_studio/resolvers/metadata_resolver/sample/__init__.py +21 -0
- lightly_studio/resolvers/metadata_resolver/sample/bulk_update_metadata.py +46 -0
- lightly_studio/resolvers/metadata_resolver/sample/get_by_sample_id.py +24 -0
- lightly_studio/resolvers/metadata_resolver/sample/get_metadata_info.py +104 -0
- lightly_studio/resolvers/metadata_resolver/sample/get_value_for_sample.py +27 -0
- lightly_studio/resolvers/metadata_resolver/sample/set_value_for_sample.py +53 -0
- lightly_studio/resolvers/sample_embedding_resolver.py +132 -0
- lightly_studio/resolvers/sample_resolver/__init__.py +17 -0
- lightly_studio/resolvers/sample_resolver/count_by_dataset_id.py +16 -0
- lightly_studio/resolvers/sample_resolver/create.py +16 -0
- lightly_studio/resolvers/sample_resolver/create_many.py +25 -0
- lightly_studio/resolvers/sample_resolver/get_by_id.py +14 -0
- lightly_studio/resolvers/sample_resolver/get_filtered_samples.py +56 -0
- lightly_studio/resolvers/sample_resolver/get_many_by_id.py +22 -0
- lightly_studio/resolvers/sample_resolver/sample_filter.py +74 -0
- lightly_studio/resolvers/settings_resolver.py +62 -0
- lightly_studio/resolvers/tag_resolver.py +299 -0
- lightly_studio/resolvers/twodim_embedding_resolver.py +119 -0
- lightly_studio/resolvers/video_frame_resolver/__init__.py +23 -0
- lightly_studio/resolvers/video_frame_resolver/count_video_frames_annotations.py +83 -0
- lightly_studio/resolvers/video_frame_resolver/create_many.py +57 -0
- lightly_studio/resolvers/video_frame_resolver/get_all_by_dataset_id.py +63 -0
- lightly_studio/resolvers/video_frame_resolver/get_by_id.py +13 -0
- lightly_studio/resolvers/video_frame_resolver/get_table_fields_bounds.py +44 -0
- lightly_studio/resolvers/video_frame_resolver/video_frame_annotations_counter_filter.py +47 -0
- lightly_studio/resolvers/video_frame_resolver/video_frame_filter.py +57 -0
- lightly_studio/resolvers/video_resolver/__init__.py +27 -0
- lightly_studio/resolvers/video_resolver/count_video_frame_annotations_by_video_dataset.py +86 -0
- lightly_studio/resolvers/video_resolver/create_many.py +58 -0
- lightly_studio/resolvers/video_resolver/filter_new_paths.py +33 -0
- lightly_studio/resolvers/video_resolver/get_all_by_dataset_id.py +181 -0
- lightly_studio/resolvers/video_resolver/get_by_id.py +22 -0
- lightly_studio/resolvers/video_resolver/get_table_fields_bounds.py +72 -0
- lightly_studio/resolvers/video_resolver/get_view_by_id.py +52 -0
- lightly_studio/resolvers/video_resolver/video_count_annotations_filter.py +50 -0
- lightly_studio/resolvers/video_resolver/video_filter.py +98 -0
- lightly_studio/selection/__init__.py +1 -0
- lightly_studio/selection/mundig.py +143 -0
- lightly_studio/selection/select.py +203 -0
- lightly_studio/selection/select_via_db.py +273 -0
- lightly_studio/selection/selection_config.py +49 -0
- lightly_studio/services/annotations_service/__init__.py +33 -0
- lightly_studio/services/annotations_service/create_annotation.py +64 -0
- lightly_studio/services/annotations_service/delete_annotation.py +22 -0
- lightly_studio/services/annotations_service/get_annotation_by_id.py +31 -0
- lightly_studio/services/annotations_service/update_annotation.py +54 -0
- lightly_studio/services/annotations_service/update_annotation_bounding_box.py +36 -0
- lightly_studio/services/annotations_service/update_annotation_label.py +48 -0
- lightly_studio/services/annotations_service/update_annotations.py +29 -0
- lightly_studio/setup_logging.py +59 -0
- lightly_studio/type_definitions.py +31 -0
- lightly_studio/utils/__init__.py +3 -0
- lightly_studio/utils/download.py +94 -0
- lightly_studio/vendor/__init__.py +1 -0
- lightly_studio/vendor/mobileclip/ACKNOWLEDGEMENTS +422 -0
- lightly_studio/vendor/mobileclip/LICENSE +31 -0
- lightly_studio/vendor/mobileclip/LICENSE_weights_data +50 -0
- lightly_studio/vendor/mobileclip/README.md +5 -0
- lightly_studio/vendor/mobileclip/__init__.py +96 -0
- lightly_studio/vendor/mobileclip/clip.py +77 -0
- lightly_studio/vendor/mobileclip/configs/mobileclip_b.json +18 -0
- lightly_studio/vendor/mobileclip/configs/mobileclip_s0.json +18 -0
- lightly_studio/vendor/mobileclip/configs/mobileclip_s1.json +18 -0
- lightly_studio/vendor/mobileclip/configs/mobileclip_s2.json +18 -0
- lightly_studio/vendor/mobileclip/image_encoder.py +67 -0
- lightly_studio/vendor/mobileclip/logger.py +154 -0
- lightly_studio/vendor/mobileclip/models/__init__.py +10 -0
- lightly_studio/vendor/mobileclip/models/mci.py +933 -0
- lightly_studio/vendor/mobileclip/models/vit.py +433 -0
- lightly_studio/vendor/mobileclip/modules/__init__.py +4 -0
- lightly_studio/vendor/mobileclip/modules/common/__init__.py +4 -0
- lightly_studio/vendor/mobileclip/modules/common/mobileone.py +341 -0
- lightly_studio/vendor/mobileclip/modules/common/transformer.py +451 -0
- lightly_studio/vendor/mobileclip/modules/image/__init__.py +4 -0
- lightly_studio/vendor/mobileclip/modules/image/image_projection.py +113 -0
- lightly_studio/vendor/mobileclip/modules/image/replknet.py +188 -0
- lightly_studio/vendor/mobileclip/modules/text/__init__.py +4 -0
- lightly_studio/vendor/mobileclip/modules/text/repmixer.py +281 -0
- lightly_studio/vendor/mobileclip/modules/text/tokenizer.py +38 -0
- lightly_studio/vendor/mobileclip/text_encoder.py +245 -0
- lightly_studio/vendor/perception_encoder/LICENSE.PE +201 -0
- lightly_studio/vendor/perception_encoder/README.md +11 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/__init__.py +0 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/bpe_simple_vocab_16e6.txt.gz +0 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/config.py +205 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/config_src.py +264 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/pe.py +766 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/rope.py +352 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/tokenizer.py +347 -0
- lightly_studio/vendor/perception_encoder/vision_encoder/transforms.py +36 -0
- lightly_studio-0.4.6.dist-info/METADATA +88 -0
- lightly_studio-0.4.6.dist-info/RECORD +356 -0
- 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
|
lightly_studio/py.typed
ADDED
|
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}
|