├── .fernignore ├── .github ├── CODEOWNERS ├── autolabeler.yml ├── dependabot.yml ├── pr-title-checker-config.json ├── release.yml └── workflows │ ├── build_pypi.yml │ ├── codeql.yml │ ├── docs.yml │ ├── fm-command.yml │ ├── follow-merge-dispatch.yml │ ├── follow-merge-upstream-repo-sync-v2.yml │ ├── git-command.yml │ ├── gitleaks.yml │ ├── jira-command.yml │ ├── pr-labeler.yml │ ├── release-cut-off-release-branch.yml │ ├── release-pipeline.yml │ ├── release-set-version.yml │ ├── slash-command-dispatch.yml │ ├── tests.yml │ ├── update-draft-release.yml │ ├── validator-dependencies.yml │ ├── zendesk_issue_commented.yml │ ├── zendesk_issue_created.yml │ ├── zendesk_task_comment.yml │ └── zendesk_task_solve.yml ├── .gitignore ├── .mock ├── definition │ ├── __package__.yml │ ├── actions.yml │ ├── annotations.yml │ ├── api.yml │ ├── comments.yml │ ├── dataManager.yml │ ├── exportStorage.yml │ ├── exportStorage │ │ ├── azure.yml │ │ ├── gcs.yml │ │ ├── local.yml │ │ ├── redis.yml │ │ ├── s3.yml │ │ └── s3S.yml │ ├── files.yml │ ├── importStorage.yml │ ├── importStorage │ │ ├── azure.yml │ │ ├── gcs.yml │ │ ├── local.yml │ │ ├── redis.yml │ │ ├── s3.yml │ │ └── s3S.yml │ ├── jwtSettings.yml │ ├── labels.yml │ ├── ml.yml │ ├── modelProviders.yml │ ├── organizations.yml │ ├── organizations │ │ └── members.yml │ ├── predictions.yml │ ├── projects.yml │ ├── projects │ │ ├── exports.yml │ │ ├── labels.yml │ │ └── pauses.yml │ ├── prompts.yml │ ├── prompts │ │ ├── indicators.yml │ │ ├── runs.yml │ │ └── versions.yml │ ├── tasks.yml │ ├── tokens.yml │ ├── users.yml │ ├── versions.yml │ ├── views.yml │ ├── webhooks.yml │ ├── workspaces.yml │ └── workspaces │ │ └── members.yml ├── fern.config.json └── openapi │ └── openapi.yaml ├── LICENSE ├── README.md ├── examples ├── README.md ├── active_learning │ ├── active_learning.ipynb │ └── active_learning.py ├── adding_new_labels_to_project.ipynb ├── annotate_data_from_gcs │ ├── annotate_data_from_gcs.ipynb │ └── annotate_data_from_gcs.py ├── cloud_storages │ └── cloud_storage_guide.ipynb ├── export_snapshots.py ├── export_with_filters.py ├── export_yolo_with_images.py ├── getting_started.ipynb ├── import_data │ └── import_from_json.ipynb ├── import_preannotations │ ├── data │ │ └── images.csv │ ├── import_brush_predictions.py │ ├── import_preannotations.ipynb │ └── import_preannotations.py ├── label_studio_enterprise │ ├── assign_10_percent_of_tasks.py │ ├── assigner.py │ ├── assignment.ipynb │ └── user_management.ipynb ├── mensuration_and_polling │ ├── README.md │ ├── data │ │ ├── 666dbadcf1cf8e0001fb2f51_cropped.png │ │ ├── Screenshot from 2024-06-14 09-18-21.png │ │ ├── e9b9661bcbd97b67f45364aafd82f9d6 │ │ │ ├── request.json │ │ │ └── response.tiff │ │ ├── oam │ │ │ └── 666dbadcf1cf8e0001fb2f51_cropped.tif │ │ └── response.png │ ├── grab_georeferenced_image.py │ ├── poll_for_tasks.py │ └── requirements.txt ├── migrate_ls_to_ls │ ├── README.md │ └── migrate-ls-to-ls.py ├── view_management.ipynb └── weak_supervision │ ├── data │ └── amazon_cells_labelled.tsv │ ├── weak_supervision.ipynb │ └── weak_supervision.py ├── poetry.lock ├── pyproject.toml ├── reference.md ├── src └── label_studio_sdk │ ├── __init__.py │ ├── _extensions │ ├── __init__.py │ ├── eval │ │ └── categorical.py │ ├── label_studio_tools │ │ ├── __init__.py │ │ ├── core │ │ │ ├── __init__.py │ │ │ ├── label_config.py │ │ │ └── utils │ │ │ │ ├── __init__.py │ │ │ │ ├── exceptions.py │ │ │ │ ├── io.py │ │ │ │ ├── json_schema.py │ │ │ │ └── params.py │ │ ├── etl │ │ │ ├── __init__.py │ │ │ ├── beam.py │ │ │ ├── example.py │ │ │ └── registry.py │ │ └── postprocessing │ │ │ ├── __init__.py │ │ │ └── video.py │ └── pager_ext.py │ ├── _legacy │ ├── __init__.py │ ├── client.py │ ├── exceptions.py │ ├── project.py │ ├── schema │ │ └── label_config_schema.json │ ├── users.py │ ├── utils.py │ └── workspaces.py │ ├── actions │ ├── __init__.py │ ├── client.py │ └── types │ │ ├── __init__.py │ │ ├── actions_create_request_filters.py │ │ ├── actions_create_request_filters_conjunction.py │ │ ├── actions_create_request_filters_items_item.py │ │ ├── actions_create_request_filters_items_item_filter.py │ │ ├── actions_create_request_filters_items_item_operator.py │ │ ├── actions_create_request_filters_items_item_value.py │ │ ├── actions_create_request_id.py │ │ ├── actions_create_request_ordering_item.py │ │ ├── actions_create_request_selected_items.py │ │ ├── actions_create_request_selected_items_excluded.py │ │ └── actions_create_request_selected_items_included.py │ ├── annotations │ ├── __init__.py │ ├── client.py │ └── types │ │ ├── __init__.py │ │ ├── annotations_create_bulk_request_selected_items.py │ │ └── annotations_create_bulk_response_item.py │ ├── base_client.py │ ├── client.py │ ├── comments │ ├── __init__.py │ └── client.py │ ├── converter │ ├── README.md │ ├── __init__.py │ ├── audio.py │ ├── brush.py │ ├── converter.py │ ├── exports │ │ ├── __init__.py │ │ ├── brush_to_coco.py │ │ ├── csv.py │ │ ├── csv2.py │ │ └── yolo.py │ ├── funsd.py │ ├── imports │ │ ├── __init__.py │ │ ├── coco.py │ │ ├── colors.py │ │ ├── label_config.py │ │ ├── pathtrack.py │ │ └── yolo.py │ ├── keypoints.py │ ├── main.py │ └── utils.py │ ├── core │ ├── __init__.py │ ├── api_error.py │ ├── client_wrapper.py │ ├── datetime_utils.py │ ├── file.py │ ├── http_client.py │ ├── jsonable_encoder.py │ ├── pagination.py │ ├── pydantic_utilities.py │ ├── query_encoder.py │ ├── remove_none_from_dict.py │ ├── request_options.py │ └── serialization.py │ ├── data_manager.py │ ├── environment.py │ ├── errors │ ├── __init__.py │ ├── bad_request_error.py │ ├── internal_server_error.py │ ├── not_found_error.py │ └── unauthorized_error.py │ ├── export_storage │ ├── __init__.py │ ├── azure │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── azure_create_response.py │ │ │ └── azure_update_response.py │ ├── client.py │ ├── gcs │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── gcs_create_response.py │ │ │ └── gcs_update_response.py │ ├── local │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── local_create_response.py │ │ │ └── local_update_response.py │ ├── redis │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── redis_create_response.py │ │ │ └── redis_update_response.py │ ├── s3 │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── s3create_response.py │ │ │ └── s3update_response.py │ ├── s3s │ │ ├── __init__.py │ │ └── client.py │ └── types │ │ ├── __init__.py │ │ └── export_storage_list_types_response_item.py │ ├── files │ ├── __init__.py │ └── client.py │ ├── import_storage │ ├── __init__.py │ ├── azure │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── azure_create_response.py │ │ │ └── azure_update_response.py │ ├── client.py │ ├── gcs │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── gcs_create_response.py │ │ │ └── gcs_update_response.py │ ├── local │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── local_create_response.py │ │ │ └── local_update_response.py │ ├── redis │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── redis_create_response.py │ │ │ └── redis_update_response.py │ ├── s3 │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── s3create_response.py │ │ │ └── s3update_response.py │ ├── s3s │ │ ├── __init__.py │ │ └── client.py │ └── types │ │ ├── __init__.py │ │ └── import_storage_list_types_response_item.py │ ├── jwt_settings │ ├── __init__.py │ └── client.py │ ├── label_interface │ ├── __init__.py │ ├── base.py │ ├── control_tags.py │ ├── create.py │ ├── data_examples.json │ ├── interface.py │ ├── label_tags.py │ ├── object_tags.py │ ├── objects.py │ └── region.py │ ├── ml │ ├── __init__.py │ ├── client.py │ └── types │ │ ├── __init__.py │ │ ├── ml_create_request_auth_method.py │ │ ├── ml_create_response.py │ │ ├── ml_create_response_auth_method.py │ │ ├── ml_update_request_auth_method.py │ │ ├── ml_update_response.py │ │ └── ml_update_response_auth_method.py │ ├── model_providers │ ├── __init__.py │ └── client.py │ ├── predictions │ ├── __init__.py │ └── client.py │ ├── projects │ ├── __init__.py │ ├── client.py │ ├── client_ext.py │ ├── exports │ │ ├── __init__.py │ │ ├── client.py │ │ ├── client_ext.py │ │ └── types │ │ │ ├── __init__.py │ │ │ ├── exports_convert_response.py │ │ │ └── exports_list_formats_response_item.py │ ├── pauses │ │ ├── __init__.py │ │ └── client.py │ └── types │ │ ├── __init__.py │ │ ├── projects_create_response.py │ │ ├── projects_import_tasks_response.py │ │ ├── projects_list_response.py │ │ └── projects_update_response.py │ ├── prompts │ ├── __init__.py │ ├── client.py │ ├── indicators │ │ ├── __init__.py │ │ └── client.py │ ├── runs │ │ ├── __init__.py │ │ ├── client.py │ │ └── types │ │ │ ├── __init__.py │ │ │ └── runs_list_request_project_subset.py │ ├── types │ │ ├── __init__.py │ │ ├── prompts_batch_failed_predictions_request_failed_predictions_item.py │ │ ├── prompts_batch_failed_predictions_response.py │ │ ├── prompts_batch_predictions_request_results_item.py │ │ └── prompts_batch_predictions_response.py │ └── versions │ │ ├── __init__.py │ │ └── client.py │ ├── py.typed │ ├── tasks │ ├── __init__.py │ ├── client.py │ ├── client_ext.py │ └── types │ │ ├── __init__.py │ │ ├── tasks_list_request_fields.py │ │ └── tasks_list_response.py │ ├── tokens │ ├── __init__.py │ ├── client.py │ └── client_ext.py │ ├── types │ ├── __init__.py │ ├── access_token_response.py │ ├── annotation.py │ ├── annotation_completed_by.py │ ├── annotation_filter_options.py │ ├── annotation_last_action.py │ ├── annotations_dm_field.py │ ├── annotations_dm_field_last_action.py │ ├── api_token_response.py │ ├── azure_blob_export_storage.py │ ├── azure_blob_export_storage_status.py │ ├── azure_blob_import_storage.py │ ├── azure_blob_import_storage_status.py │ ├── base_task.py │ ├── base_task_file_upload.py │ ├── base_task_updated_by.py │ ├── base_user.py │ ├── comment.py │ ├── comment_created_by.py │ ├── converted_format.py │ ├── converted_format_status.py │ ├── data_manager_task_serializer.py │ ├── data_manager_task_serializer_annotators_item.py │ ├── data_manager_task_serializer_comment_authors_item.py │ ├── data_manager_task_serializer_drafts_item.py │ ├── data_manager_task_serializer_predictions_item.py │ ├── data_manager_task_serializer_predictions_item_model_run.py │ ├── export.py │ ├── export_format.py │ ├── export_snapshot.py │ ├── export_snapshot_status.py │ ├── export_status.py │ ├── file_upload.py │ ├── filter.py │ ├── filter_group.py │ ├── gcs_export_storage.py │ ├── gcs_export_storage_status.py │ ├── gcs_import_storage.py │ ├── gcs_import_storage_status.py │ ├── inference_run.py │ ├── inference_run_cost_estimate.py │ ├── inference_run_created_by.py │ ├── inference_run_organization.py │ ├── inference_run_project_subset.py │ ├── inference_run_status.py │ ├── jwt_settings_response.py │ ├── key_indicator_value.py │ ├── key_indicators.py │ ├── key_indicators_item.py │ ├── key_indicators_item_additional_kpis_item.py │ ├── key_indicators_item_extra_kpis_item.py │ ├── local_files_export_storage.py │ ├── local_files_export_storage_status.py │ ├── local_files_import_storage.py │ ├── local_files_import_storage_status.py │ ├── ml_backend.py │ ├── ml_backend_auth_method.py │ ├── ml_backend_state.py │ ├── model_provider_connection.py │ ├── model_provider_connection_budget_reset_period.py │ ├── model_provider_connection_created_by.py │ ├── model_provider_connection_organization.py │ ├── model_provider_connection_provider.py │ ├── model_provider_connection_scope.py │ ├── pause.py │ ├── pause_paused_by.py │ ├── prediction.py │ ├── project.py │ ├── project_import.py │ ├── project_import_status.py │ ├── project_label_config.py │ ├── project_sampling.py │ ├── project_skip_queue.py │ ├── prompt.py │ ├── prompt_associated_projects_item.py │ ├── prompt_associated_projects_item_id.py │ ├── prompt_created_by.py │ ├── prompt_organization.py │ ├── prompt_version.py │ ├── prompt_version_created_by.py │ ├── prompt_version_organization.py │ ├── prompt_version_provider.py │ ├── redis_export_storage.py │ ├── redis_export_storage_status.py │ ├── redis_import_storage.py │ ├── redis_import_storage_status.py │ ├── refined_prompt_response.py │ ├── refined_prompt_response_refinement_status.py │ ├── rotate_token_response.py │ ├── s3export_storage.py │ ├── s3export_storage_status.py │ ├── s3import_storage.py │ ├── s3import_storage_status.py │ ├── s3s_export_storage.py │ ├── s3s_import_storage.py │ ├── s3s_import_storage_status.py │ ├── serialization_option.py │ ├── serialization_options.py │ ├── task.py │ ├── task_annotators_item.py │ ├── task_comment_authors_item.py │ ├── task_filter_options.py │ ├── user_simple.py │ ├── view.py │ ├── webhook.py │ ├── webhook_actions_item.py │ ├── webhook_serializer_for_update.py │ ├── webhook_serializer_for_update_actions_item.py │ └── workspace.py │ ├── users │ ├── __init__.py │ ├── client.py │ └── types │ │ ├── __init__.py │ │ ├── users_get_token_response.py │ │ └── users_reset_token_response.py │ ├── version.py │ ├── versions │ ├── __init__.py │ ├── client.py │ └── types │ │ ├── __init__.py │ │ ├── versions_get_response.py │ │ └── versions_get_response_edition.py │ ├── views │ ├── __init__.py │ ├── client.py │ └── types │ │ ├── __init__.py │ │ ├── views_create_request_data.py │ │ ├── views_create_request_data_filters.py │ │ ├── views_create_request_data_filters_conjunction.py │ │ ├── views_create_request_data_filters_items_item.py │ │ ├── views_create_request_data_filters_items_item_filter.py │ │ ├── views_create_request_data_filters_items_item_operator.py │ │ ├── views_create_request_data_filters_items_item_value.py │ │ ├── views_create_request_data_ordering_item.py │ │ ├── views_update_request_data.py │ │ ├── views_update_request_data_filters.py │ │ ├── views_update_request_data_filters_conjunction.py │ │ ├── views_update_request_data_filters_items_item.py │ │ ├── views_update_request_data_filters_items_item_filter.py │ │ ├── views_update_request_data_filters_items_item_operator.py │ │ ├── views_update_request_data_filters_items_item_value.py │ │ └── views_update_request_data_ordering_item.py │ ├── webhooks │ ├── __init__.py │ ├── client.py │ └── types │ │ ├── __init__.py │ │ └── webhooks_update_request_actions_item.py │ └── workspaces │ ├── __init__.py │ ├── client.py │ └── members │ ├── __init__.py │ ├── client.py │ └── types │ ├── __init__.py │ ├── members_create_response.py │ └── members_list_response_item.py ├── tests ├── __init__.py ├── conftest.py ├── custom │ ├── converter │ │ ├── __init__.py │ │ ├── data │ │ │ ├── test_brush │ │ │ │ └── test.png │ │ │ ├── test_export_coco │ │ │ │ ├── data.json │ │ │ │ └── label_config.xml │ │ │ ├── test_export_csv │ │ │ │ ├── csv_test.json │ │ │ │ ├── csv_test2.json │ │ │ │ ├── csv_test2_result.csv │ │ │ │ └── csv_test_history.json │ │ │ ├── test_export_json_min │ │ │ │ ├── data.json │ │ │ │ ├── data_repeater.json │ │ │ │ ├── label_config.xml │ │ │ │ └── label_config_repeater.json │ │ │ ├── test_export_yolo │ │ │ │ ├── data.json │ │ │ │ ├── data_keypoints.json │ │ │ │ ├── data_obb.json │ │ │ │ ├── data_polygons.json │ │ │ │ ├── label_config.xml │ │ │ │ ├── label_config_keypoints.xml │ │ │ │ ├── label_config_obb.xml │ │ │ │ └── label_config_polygons.xml │ │ │ ├── test_import_coco │ │ │ │ └── coco_import_input.json │ │ │ ├── test_import_yolo_data │ │ │ │ ├── classes.txt │ │ │ │ ├── images │ │ │ │ │ ├── img_1.jpg │ │ │ │ │ ├── img_2.png │ │ │ │ │ ├── img_3.png │ │ │ │ │ ├── img_4.png │ │ │ │ │ ├── img_5.jpg │ │ │ │ │ ├── img_6.jpeg │ │ │ │ │ └── img_7.jpeg │ │ │ │ └── labels │ │ │ │ │ ├── img_1.txt │ │ │ │ │ ├── img_2.txt │ │ │ │ │ ├── img_3.txt │ │ │ │ │ ├── img_4.txt │ │ │ │ │ ├── img_5.txt │ │ │ │ │ ├── img_6.txt │ │ │ │ │ └── img_7.txt │ │ │ └── test_import_yolo_data_unif_dims │ │ │ │ ├── classes.txt │ │ │ │ ├── images │ │ │ │ ├── img_1.jpg │ │ │ │ ├── img_2.jpg │ │ │ │ ├── img_3.jpg │ │ │ │ ├── img_4.jpg │ │ │ │ └── img_5.jpg │ │ │ │ └── labels │ │ │ │ ├── img_1.txt │ │ │ │ ├── img_2.txt │ │ │ │ ├── img_3.txt │ │ │ │ ├── img_4.txt │ │ │ │ └── img_5.txt │ │ ├── pathtrack │ │ │ ├── gt │ │ │ │ └── gt-short.txt │ │ │ └── info.xml │ │ ├── test.png │ │ ├── test_brush.py │ │ ├── test_brush_to_coco.py │ │ ├── test_export_coco.py │ │ ├── test_export_conll.py │ │ ├── test_export_csv.py │ │ ├── test_export_json_min.py │ │ ├── test_export_keypoints_yolo.py │ │ ├── test_export_yolo.py │ │ ├── test_import_coco.py │ │ ├── test_import_yolo.py │ │ ├── test_yolo_with_images.py │ │ └── utils.py │ ├── label_studio_tools │ │ ├── __init__.py │ │ ├── test_core_label_config.py │ │ ├── test_get_local_path.py │ │ └── test_postprocessing_video.py │ ├── legacy │ │ ├── __init__.py │ │ ├── requirements-test.txt │ │ ├── test_client.py │ │ └── test_export.py │ ├── test_client.py │ └── test_interface │ │ ├── __init__.py │ │ ├── configs.py │ │ ├── mockups.py │ │ ├── test_compat.py │ │ ├── test_control_tags.py │ │ ├── test_control_tags_label.py │ │ ├── test_control_tags_redefine.py │ │ ├── test_create.py │ │ ├── test_data_generation.py │ │ ├── test_json_schema.py │ │ ├── test_lpi.py │ │ ├── test_main.py │ │ ├── test_object_tags.py │ │ ├── test_region.py │ │ ├── test_validate_summary.py │ │ ├── test_validation.py │ │ └── test_value_objects.py ├── export_storage │ ├── __init__.py │ ├── test_azure.py │ ├── test_gcs.py │ ├── test_local.py │ ├── test_redis.py │ ├── test_s3.py │ └── test_s3s.py ├── import_storage │ ├── __init__.py │ ├── test_azure.py │ ├── test_gcs.py │ ├── test_local.py │ ├── test_redis.py │ ├── test_s3.py │ └── test_s3s.py ├── projects │ ├── __init__.py │ ├── test_exports.py │ └── test_pauses.py ├── prompts │ ├── __init__.py │ ├── test_indicators.py │ ├── test_runs.py │ └── test_versions.py ├── test_actions.py ├── test_annotations.py ├── test_comments.py ├── test_export_storage.py ├── test_files.py ├── test_import_storage.py ├── test_jwt_settings.py ├── test_ml.py ├── test_model_providers.py ├── test_predictions.py ├── test_projects.py ├── test_prompts.py ├── test_refresh_token.py ├── test_tasks.py ├── test_tokens.py ├── test_users.py ├── test_versions.py ├── test_views.py ├── test_webhooks.py ├── test_workspaces.py ├── utilities.py ├── utils │ ├── __init__.py │ ├── assets │ │ └── models │ │ │ ├── __init__.py │ │ │ ├── circle.py │ │ │ ├── color.py │ │ │ ├── object_with_defaults.py │ │ │ ├── object_with_optional_field.py │ │ │ ├── shape.py │ │ │ ├── square.py │ │ │ └── undiscriminated_shape.py │ ├── test_http_client.py │ ├── test_query_encoding.py │ └── test_serialization.py └── workspaces │ ├── __init__.py │ └── test_members.py └── tutorials ├── connect_to_ml_backend.ipynb ├── evaluate_llm_response.ipynb ├── fastapi_server.py └── yolo_predictions.ipynb /.github/CODEOWNERS: -------------------------------------------------------------------------------- 1 | .github/ @HumanSignal/devops 2 | -------------------------------------------------------------------------------- /.github/autolabeler.yml: -------------------------------------------------------------------------------- 1 | template: "Mandatory field" #https://github.com/release-drafter/release-drafter/blob/master/bin/generate-schema.js#L15 2 | autolabeler: 3 | # - label: 'breaking' 4 | # body: 5 | # - '/BREAKING CHANGE/i' 6 | - label: 'fix' 7 | title: 8 | - '/^fix:/' 9 | - label: 'feat' 10 | title: 11 | - '/^feat:/' 12 | - label: 'docs' 13 | title: 14 | - '/^docs:/' 15 | - label: 'chore' 16 | title: 17 | - '/^chore:/' 18 | - label: 'ci' 19 | title: 20 | - '/^ci:/' 21 | - label: 'perf' 22 | title: 23 | - '/^perf:/' 24 | - label: 'refactor' 25 | title: 26 | - '/^refactor:/' 27 | - label: 'style' 28 | title: 29 | - '/^style:/' 30 | - label: 'test' 31 | title: 32 | - '/^test:/' 33 | -------------------------------------------------------------------------------- /.github/dependabot.yml: -------------------------------------------------------------------------------- 1 | version: 2 2 | updates: 3 | - package-ecosystem: "github-actions" 4 | directory: "/" 5 | schedule: 6 | interval: "weekly" 7 | timezone: "Europe/London" 8 | time: "09:00" 9 | day: "monday" 10 | commit-message: 11 | prefix: "ci:" 12 | -------------------------------------------------------------------------------- /.github/pr-title-checker-config.json: -------------------------------------------------------------------------------- 1 | { 2 | "LABEL": { 3 | "name": "title needs formatting", 4 | "color": "EEEEEE" 5 | }, 6 | "CHECKS": { 7 | "prefixes": [ 8 | "fix: ", 9 | "feat: ", 10 | "docs: ", 11 | "chore: ", 12 | "ci: ", 13 | "perf: ", 14 | "refactor: ", 15 | "style: ", 16 | "test: " 17 | ], 18 | "ignoreLabels": [ 19 | "skip-changelog", 20 | "skip-ci" 21 | ] 22 | }, 23 | "MESSAGES": { 24 | "success": "PR title is valid", 25 | "failure": "PR title is invalid", 26 | "notice": "Please set prefix" 27 | } 28 | } 29 | -------------------------------------------------------------------------------- /.github/release.yml: -------------------------------------------------------------------------------- 1 | changelog: 2 | exclude: 3 | labels: 4 | - 'skip-changelog' 5 | - 'skip-ci' 6 | categories: 7 | - title: 'BREAKING CHANGES' 8 | labels: 9 | - breaking 10 | - title: 'Features' 11 | labels: 12 | - feat 13 | - title: 'Bug Fixes' 14 | labels: 15 | - fix 16 | - title: 'Other Changes' 17 | labels: 18 | - "*" -------------------------------------------------------------------------------- /.github/workflows/codeql.yml: -------------------------------------------------------------------------------- 1 | name: "CodeQL" 2 | 3 | on: 4 | push: 5 | branches: [ "master", "release/**" ] 6 | schedule: 7 | - cron: '35 22 * * 0' 8 | 9 | jobs: 10 | analyze: 11 | name: Analyze 12 | runs-on: 'ubuntu-latest' 13 | timeout-minutes: 45 14 | permissions: 15 | actions: read 16 | contents: read 17 | security-events: write 18 | 19 | strategy: 20 | fail-fast: false 21 | matrix: 22 | language: [ 'python' ] 23 | 24 | steps: 25 | - name: Checkout repository 26 | uses: actions/checkout@v4 27 | 28 | - name: Initialize CodeQL 29 | uses: github/codeql-action/init@v3 30 | with: 31 | languages: ${{ matrix.language }} 32 | #config-file: ./.github/codeql/codeql-config.yaml 33 | 34 | - name: Perform CodeQL Analysis 35 | uses: github/codeql-action/analyze@v3 36 | with: 37 | category: "/language:${{matrix.language}}" 38 | -------------------------------------------------------------------------------- /.github/workflows/docs.yml: -------------------------------------------------------------------------------- 1 | # DISABLED as api.labelstud.io is managed by fern 2 | #name: deploy:docs 3 | # 4 | #on: 5 | # push: 6 | # branches: [ master ] 7 | # 8 | #jobs: 9 | # deploy_docs: 10 | # runs-on: ubuntu-latest 11 | # steps: 12 | # - uses: actions/checkout@v4 13 | # 14 | # - name: Cache pip deps 15 | # uses: actions/cache@v4 16 | # env: 17 | # cache-name: cache-pip-packages 18 | # with: 19 | # path: ~/.cache/pip 20 | # key: ${{ runner.os }}-pip-${{ env.cache-name }}-${{ hashFiles('setup.py') }}-${{ hashFiles('requirements.txt') }} 21 | # restore-keys: | 22 | # ${{ runner.os }}-pip-${{ env.cache-name }}- 23 | # ${{ runner.os }}-pip- 24 | # ${{ runner.os }}- 25 | # 26 | # - name: Install pdoc with dependencies 27 | # run: make install 28 | # 29 | # - name: Build HTML for deployment 30 | # run: make build 31 | # 32 | # - name: Publish docs to AWS S3 33 | # env: 34 | # AWS_ACCESS_KEY_ID: ${{ secrets.DOCS_DEPLOY_AWS_ACCESS_KEY_ID }} 35 | # AWS_SECRET_ACCESS_KEY: ${{ secrets.DOCS_DEPLOY_AWS_SECRET_ACCESS_KEY }} 36 | # run: make deploy 37 | -------------------------------------------------------------------------------- /.github/workflows/fm-command.yml: -------------------------------------------------------------------------------- 1 | name: "/fm command" 2 | 3 | on: 4 | repository_dispatch: 5 | types: [ fm-command ] 6 | 7 | concurrency: 8 | group: ${{ github.workflow }}-${{ github.event.client_payload.github.payload.issue.number }}-${{ github.event.client_payload.slash_command.command }}-${{ github.event.client_payload.slash_command.args.unnamed.arg1 || github.event.client_payload.slash_command.args.all }} 9 | 10 | jobs: 11 | sync: 12 | name: "Update: Update Feature Flags" 13 | if: github.event.client_payload.slash_command.args.unnamed.arg1 == 'sync' 14 | uses: ./.github/workflows/follow-merge-upstream-repo-sync-v2.yml 15 | with: 16 | branch_name: ${{ github.event.client_payload.slash_command.args.unnamed.arg2 || github.event.client_payload.pull_request.head.ref }} 17 | secrets: inherit 18 | 19 | help: 20 | if: ${{ github.event.client_payload.slash_command.args.unnamed.arg1 == 'help' || !contains(fromJson('["sync"]'), github.event.client_payload.slash_command.args.unnamed.arg1) }} 21 | runs-on: ubuntu-latest 22 | timeout-minutes: 1 23 | steps: 24 | - name: Update comment 25 | uses: peter-evans/create-or-update-comment@v4 26 | with: 27 | token: ${{ secrets.GIT_PAT }} 28 | repository: ${{ github.event.client_payload.github.payload.repository.full_name }} 29 | comment-id: ${{ github.event.client_payload.github.payload.comment.id }} 30 | body: | 31 | > Command | Description 32 | > --- | --- 33 | > /fm sync | Sync upstream prs and merge with pull request base 34 | reactions: hooray 35 | -------------------------------------------------------------------------------- /.github/workflows/pr-labeler.yml: -------------------------------------------------------------------------------- 1 | name: "PR labeler" 2 | 3 | on: 4 | pull_request_target: 5 | types: 6 | - opened 7 | - edited 8 | - reopened 9 | - synchronize 10 | - ready_for_review 11 | branches: 12 | - master 13 | - 'release/**' 14 | 15 | env: 16 | ACTIONS_STEP_DEBUG: '${{ secrets.ACTIONS_STEP_DEBUG }}' 17 | 18 | jobs: 19 | autolabel: 20 | name: "PR label validator" 21 | runs-on: ubuntu-latest 22 | permissions: 23 | pull-requests: write 24 | steps: 25 | 26 | - uses: hmarr/debug-action@v3.0.0 27 | 28 | - name: "Validate PR's title" 29 | uses: thehanimo/pr-title-checker@v1.4.3 30 | with: 31 | GITHUB_TOKEN: ${{ github.token }} 32 | pass_on_octokit_error: false 33 | configuration_path: ".github/pr-title-checker-config.json" 34 | 35 | - name: "Set PR's label based on title" 36 | uses: release-drafter/release-drafter@v6.1.0 37 | with: 38 | disable-releaser: true 39 | config-name: autolabeler.yml 40 | env: 41 | GITHUB_TOKEN: ${{ github.token }} 42 | -------------------------------------------------------------------------------- /.github/workflows/release-pipeline.yml: -------------------------------------------------------------------------------- 1 | name: "Release: Pipeline" 2 | 3 | on: 4 | release: 5 | types: 6 | - released 7 | 8 | concurrency: 9 | group: ${{ github.workflow }}-${{ github.event.pull_request.number || github.event.pull_request.head.ref || github.ref }} 10 | cancel-in-progress: true 11 | 12 | jobs: 13 | build-pypi: 14 | name: "Build" 15 | permissions: 16 | contents: write 17 | uses: ./.github/workflows/build_pypi.yml 18 | with: 19 | version: ${{ github.ref_name }} 20 | ref: ${{ github.ref_name }} 21 | upload_to_pypi: true 22 | release-id: ${{ github.event.release.id }} 23 | secrets: inherit 24 | -------------------------------------------------------------------------------- /.github/workflows/tests.yml: -------------------------------------------------------------------------------- 1 | name: pytests 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | paths: 8 | - 'src/**' 9 | - 'tests/**' 10 | - '.github/workflows/tests.yml' 11 | - '**/requirements**' 12 | - 'codecov.yml' 13 | tags-ignore: 14 | - '**' 15 | pull_request: 16 | types: 17 | - opened 18 | - synchronize 19 | - reopened 20 | - ready_for_review 21 | branches: 22 | - master 23 | - 'release/**' 24 | workflow_dispatch: 25 | 26 | env: 27 | POETRY_VERSION: 2.1.2 28 | 29 | jobs: 30 | run_pytest: 31 | name: "pytest ${{ matrix.os }} | ${{ matrix.python-version }}" 32 | runs-on: ubuntu-latest 33 | strategy: 34 | fail-fast: false 35 | matrix: 36 | python-version: 37 | - 3.12 38 | os: 39 | - ubuntu-latest 40 | 41 | steps: 42 | - uses: actions/checkout@v4 43 | 44 | - name: "Install poetry" 45 | run: pipx install "poetry==${{ env.POETRY_VERSION }}" 46 | 47 | - name: "Set up Python" 48 | id: setup_python 49 | uses: actions/setup-python@v5 50 | with: 51 | python-version: ${{ matrix.python-version }} 52 | cache: 'poetry' 53 | 54 | - name: "Install dependencies" 55 | run: poetry install 56 | 57 | - name: Install Fern 58 | run: npm install -g fern-api@latest 59 | 60 | - name: Test 61 | run: fern test --command "poetry run pytest -rP ." 62 | -------------------------------------------------------------------------------- /.github/workflows/validator-dependencies.yml: -------------------------------------------------------------------------------- 1 | name: "Check" 2 | 3 | on: 4 | push: 5 | branches: 6 | - master 7 | pull_request_target: 8 | types: 9 | - opened 10 | - reopened 11 | - synchronize 12 | - ready_for_review 13 | branches: 14 | - master 15 | 16 | env: 17 | ACTIONS_STEP_DEBUG: '${{ secrets.ACTIONS_STEP_DEBUG }}' 18 | 19 | jobs: 20 | dependencies: 21 | name: "Dependencies" 22 | runs-on: ubuntu-latest 23 | steps: 24 | - uses: hmarr/debug-action@v3.0.0 25 | 26 | - name: Checkout Actions Hub 27 | uses: actions/checkout@v4 28 | with: 29 | token: ${{ secrets.GIT_PAT }} 30 | repository: HumanSignal/actions-hub 31 | path: ./.github/actions-hub 32 | 33 | - name: Get Upstream PRs 34 | uses: ./.github/actions-hub/actions/follow-merge-upstream-prs 35 | id: upstream-prs 36 | with: 37 | branch_name: "${{ github.event.pull_request.head.ref || github.ref_name }}" 38 | poetry_repositories: "" 39 | infra_repositories: "label-studio-client-generator" 40 | github_token: "${{ secrets.GIT_PAT }}" 41 | 42 | - name: Fail Check 43 | if: steps.upstream-prs.outputs.status != 'merged' && steps.upstream-prs.outputs.status != 'stale' 44 | run: exit 1 45 | -------------------------------------------------------------------------------- /.github/workflows/zendesk_task_solve.yml: -------------------------------------------------------------------------------- 1 | name: "ZenDesk: Close GitHub Issue on Zendesk Ticket Solved" 2 | 3 | on: 4 | workflow_dispatch: 5 | inputs: 6 | external_id: 7 | description: "GitHub issue url" 8 | required: true 9 | type: string 10 | 11 | jobs: 12 | close_issue: 13 | runs-on: ubuntu-latest 14 | steps: 15 | - uses: hmarr/debug-action@v3.0.0 16 | 17 | - uses: actions/github-script@v7 18 | with: 19 | github-token: ${{ secrets.GIT_PAT_HEIDI }} 20 | script: | 21 | // Extract issue details from the Zendesk external_id 22 | const parts = context.payload.inputs.external_id.split("/"); 23 | const issue_number = parts[parts.length - 1]; 24 | const issue_repo = parts[parts.length - 3]; 25 | const issue_owner = parts[parts.length - 4]; 26 | 27 | // Close the GitHub issue 28 | const { data: issue } await github.rest.issues.update({ 29 | owner: issue_owner, 30 | repo: issue_repo, 31 | issue_number: issue_number, 32 | state: "closed" 33 | }); 34 | 35 | core.info(`GitHub issue ${issue.html_url} closed successfully.`); 36 | -------------------------------------------------------------------------------- /.gitignore: -------------------------------------------------------------------------------- 1 | dist/ 2 | .mypy_cache/ 3 | __pycache__/ 4 | poetry.toml 5 | .ruff_cache/ 6 | -------------------------------------------------------------------------------- /.mock/definition/api.yml: -------------------------------------------------------------------------------- 1 | name: api 2 | error-discrimination: 3 | strategy: status-code 4 | display-name: Label Studio API 5 | environments: 6 | Default: http://localhost:8080 7 | default-environment: Default 8 | auth-schemes: 9 | Token: 10 | header: Authorization 11 | name: api_key 12 | type: string 13 | env: LABEL_STUDIO_API_KEY 14 | prefix: 'Token ' 15 | auth: Token 16 | -------------------------------------------------------------------------------- /.mock/definition/exportStorage.yml: -------------------------------------------------------------------------------- 1 | service: 2 | auth: false 3 | base-path: '' 4 | endpoints: 5 | list: 6 | path: /api/storages/export 7 | method: GET 8 | auth: true 9 | docs: Retrieve a list of the export storages of all types with their IDs. 10 | source: 11 | openapi: openapi/openapi.yaml 12 | display-name: List all export storages from the project 13 | examples: 14 | - {} 15 | audiences: 16 | - internal 17 | list_types: 18 | path: /api/storages/export/types 19 | method: GET 20 | auth: true 21 | docs: Retrieve a list of the export storages types. 22 | source: 23 | openapi: openapi/openapi.yaml 24 | display-name: List all export storages types 25 | response: 26 | docs: '' 27 | type: list 28 | examples: 29 | - response: 30 | body: 31 | - name: name 32 | title: title 33 | audiences: 34 | - public 35 | source: 36 | openapi: openapi/openapi.yaml 37 | types: 38 | ExportStorageListTypesResponseItem: 39 | properties: 40 | name: optional 41 | title: optional 42 | source: 43 | openapi: openapi/openapi.yaml 44 | -------------------------------------------------------------------------------- /.mock/definition/importStorage.yml: -------------------------------------------------------------------------------- 1 | service: 2 | auth: false 3 | base-path: '' 4 | endpoints: 5 | list: 6 | path: /api/storages/ 7 | method: GET 8 | auth: true 9 | docs: Retrieve a list of the import storages of all types with their IDs. 10 | source: 11 | openapi: openapi/openapi.yaml 12 | display-name: List all import storages from the project 13 | examples: 14 | - {} 15 | audiences: 16 | - internal 17 | list_types: 18 | path: /api/storages/types 19 | method: GET 20 | auth: true 21 | docs: Retrieve a list of the import storages types. 22 | source: 23 | openapi: openapi/openapi.yaml 24 | display-name: List all import storages types 25 | response: 26 | docs: '' 27 | type: list 28 | examples: 29 | - response: 30 | body: 31 | - name: name 32 | title: title 33 | audiences: 34 | - public 35 | source: 36 | openapi: openapi/openapi.yaml 37 | types: 38 | ImportStorageListTypesResponseItem: 39 | properties: 40 | name: optional 41 | title: optional 42 | source: 43 | openapi: openapi/openapi.yaml 44 | -------------------------------------------------------------------------------- /.mock/definition/jwtSettings.yml: -------------------------------------------------------------------------------- 1 | imports: 2 | root: __package__.yml 3 | service: 4 | auth: false 5 | base-path: '' 6 | endpoints: 7 | get: 8 | path: /api/jwt/settings 9 | method: GET 10 | auth: true 11 | docs: | 12 | Retrieve JWT settings for the currently-active organization. 13 | source: 14 | openapi: openapi/openapi.yaml 15 | display-name: Retrieve JWT Settings 16 | response: 17 | docs: JWT settings retrieved successfully 18 | type: root.JwtSettingsResponse 19 | examples: 20 | - response: 21 | body: 22 | api_tokens_enabled: true 23 | legacy_api_tokens_enabled: true 24 | api_token_ttl_days: 1 25 | audiences: 26 | - public 27 | create: 28 | path: /api/jwt/settings 29 | method: POST 30 | auth: true 31 | docs: | 32 | Update JWT settings for the currently active organization. 33 | source: 34 | openapi: openapi/openapi.yaml 35 | display-name: Update JWT Settings 36 | request: 37 | body: root.JwtSettingsResponse 38 | content-type: application/json 39 | response: 40 | docs: JWT settings updated successfully 41 | type: root.JwtSettingsResponse 42 | examples: 43 | - request: 44 | api_tokens_enabled: true 45 | legacy_api_tokens_enabled: true 46 | api_token_ttl_days: 1 47 | response: 48 | body: 49 | api_tokens_enabled: true 50 | legacy_api_tokens_enabled: true 51 | api_token_ttl_days: 1 52 | audiences: 53 | - public 54 | source: 55 | openapi: openapi/openapi.yaml 56 | -------------------------------------------------------------------------------- /.mock/fern.config.json: -------------------------------------------------------------------------------- 1 | { 2 | "organization" : "humansignal-org", 3 | "version" : "0.51.7" 4 | } -------------------------------------------------------------------------------- /examples/import_preannotations/data/images.csv: -------------------------------------------------------------------------------- 1 | image,pet 2 | https://data.heartex.net/open-images/train_0/mini/0045dd96bf73936c.jpg,Dog 3 | https://data.heartex.net/open-images/train_0/mini/0083d02f6ad18b38.jpg,Cat -------------------------------------------------------------------------------- /examples/mensuration_and_polling/data/666dbadcf1cf8e0001fb2f51_cropped.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/examples/mensuration_and_polling/data/666dbadcf1cf8e0001fb2f51_cropped.png -------------------------------------------------------------------------------- /examples/mensuration_and_polling/data/Screenshot from 2024-06-14 09-18-21.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/examples/mensuration_and_polling/data/Screenshot from 2024-06-14 09-18-21.png -------------------------------------------------------------------------------- /examples/mensuration_and_polling/data/e9b9661bcbd97b67f45364aafd82f9d6/response.tiff: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/examples/mensuration_and_polling/data/e9b9661bcbd97b67f45364aafd82f9d6/response.tiff -------------------------------------------------------------------------------- /examples/mensuration_and_polling/data/oam/666dbadcf1cf8e0001fb2f51_cropped.tif: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/examples/mensuration_and_polling/data/oam/666dbadcf1cf8e0001fb2f51_cropped.tif -------------------------------------------------------------------------------- /examples/mensuration_and_polling/data/response.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/examples/mensuration_and_polling/data/response.png -------------------------------------------------------------------------------- /examples/mensuration_and_polling/requirements.txt: -------------------------------------------------------------------------------- 1 | label_studio_sdk~=1.0.2 2 | numpy~=2.0.0 3 | rasterio~=1.3.10 4 | sentinelhub~=3.10.2 5 | Shapely~=2.0.4 6 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/src/label_studio_sdk/_extensions/__init__.py -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/src/label_studio_sdk/_extensions/label_studio_tools/__init__.py -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/core/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/src/label_studio_sdk/_extensions/label_studio_tools/core/__init__.py -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/core/utils/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/src/label_studio_sdk/_extensions/label_studio_tools/core/utils/__init__.py -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/core/utils/exceptions.py: -------------------------------------------------------------------------------- 1 | class LabelStudioXMLSyntaxErrorSentryIgnored(Exception): 2 | pass 3 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/core/utils/params.py: -------------------------------------------------------------------------------- 1 | import os 2 | 3 | 4 | def bool_from_request(params, key, default): 5 | """Get boolean value from request GET, POST, etc 6 | :param params: dict POST, GET, etc 7 | :param key: key to find 8 | :param default: default value 9 | :return: boolean 10 | """ 11 | value = params.get(key, default) 12 | 13 | if isinstance(value, str): 14 | value = cast_bool_from_str(value) 15 | 16 | return bool(int(value)) 17 | 18 | 19 | def cast_bool_from_str(value): 20 | if isinstance(value, str): 21 | if value.lower() in ["true", "yes", "on", "1"]: 22 | value = True 23 | elif value.lower() in ["false", "no", "not", "off", "0"]: 24 | value = False 25 | else: 26 | raise ValueError( 27 | f'Incorrect bool value "{value}". ' 28 | f"It should be one of [1, 0, true, false, yes, no]" 29 | ) 30 | return value 31 | 32 | 33 | def get_env(name, default=None, is_bool=False): 34 | for env_key in ["LABEL_STUDIO_" + name, "HEARTEX_" + name, name]: 35 | value = os.environ.get(env_key) 36 | if value is not None: 37 | if is_bool: 38 | return bool_from_request(os.environ, env_key, default) 39 | else: 40 | return value 41 | return default 42 | 43 | 44 | def get_bool_env(key, default): 45 | return get_env(key, default, is_bool=True) 46 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/etl/__init__.py: -------------------------------------------------------------------------------- 1 | from registry import transform 2 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/etl/beam.py: -------------------------------------------------------------------------------- 1 | import apache_beam as beam 2 | from registry import dataloader, call_dataloader 3 | 4 | 5 | class CallDataLoader(beam.DoFn): 6 | def __init__(self, dataloader_name): 7 | self.dataloader_name = dataloader_name 8 | 9 | def setup(self): 10 | print("Setup!") 11 | pass 12 | 13 | def process(self, element, *args, **kwargs): 14 | return call_dataloader(self.dataloader_name, element, *args, **kwargs) 15 | 16 | def teardown(self): 17 | print("Teardown!") 18 | pass 19 | 20 | 21 | @dataloader("test") 22 | def f(i, k): 23 | print("I!!", k) 24 | yield i 25 | 26 | 27 | with beam.Pipeline() as pipeline: 28 | results = ( 29 | pipeline 30 | | "Get storage keys" >> beam.io.gcp.gcsio.list_files("bucket") 31 | | "Run dataloader" 32 | >> beam.FlatMap(fn=CallDataLoader("test"), **dataloader_kwargs) 33 | | "Load into Vector DB" >> beam.ParDo(fn=LoadDataRecordInDB) 34 | ) 35 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/etl/example.py: -------------------------------------------------------------------------------- 1 | from label_studio_sdk._extensions.label_studio_tools.etl.registry import ( 2 | transform, 3 | call_dataloader, 4 | ) 5 | 6 | 7 | @transform.datarecords("read_base64_from_blob") 8 | def gcs_blob_to_base64( 9 | key: str, 10 | bucket_name: str, 11 | google_project_id: str = None, 12 | ): 13 | print(key, bucket_name) 14 | 15 | 16 | if __name__ == "__main__": 17 | call_dataloader("gcs_blob_reader", key=12, bucket_name=34) 18 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_extensions/label_studio_tools/postprocessing/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/src/label_studio_sdk/_extensions/label_studio_tools/postprocessing/__init__.py -------------------------------------------------------------------------------- /src/label_studio_sdk/_legacy/__init__.py: -------------------------------------------------------------------------------- 1 | """ .. include::../docs/index.md 2 | """ 3 | 4 | from .client import Client 5 | from .project import Project 6 | from .utils import parse_config 7 | 8 | __pdoc__ = {"label_interface": False} 9 | 10 | 11 | __version__ = '0.0.35.dev' 12 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_legacy/exceptions.py: -------------------------------------------------------------------------------- 1 | class LSConfigParseException(Exception): 2 | """ """ 3 | 4 | 5 | class LabelStudioXMLSyntaxErrorSentryIgnored(Exception): 6 | """ """ 7 | 8 | 9 | class LabelStudioValidationErrorSentryIgnored(Exception): 10 | """ """ 11 | -------------------------------------------------------------------------------- /src/label_studio_sdk/_legacy/users.py: -------------------------------------------------------------------------------- 1 | from datetime import datetime 2 | from enum import Enum 3 | from typing import List, Optional 4 | 5 | from pydantic import BaseModel, Field 6 | 7 | from .client import Client 8 | 9 | 10 | class UserRole(Enum): 11 | ANNOTATOR = "AN" 12 | REVIEWER = "RE" 13 | MANAGER = "MA" 14 | ADMINISTRATOR = "AD" 15 | OWNER = "OW" 16 | NOT_ACTIVATED = "NO" 17 | DISABLED = "DI" 18 | 19 | 20 | class OrgMembership(BaseModel): 21 | role: UserRole 22 | active: bool 23 | organization_id: int 24 | 25 | 26 | class User(BaseModel): 27 | id: int 28 | first_name: str 29 | last_name: str 30 | username: str 31 | email: str 32 | last_activity: datetime 33 | initials: str 34 | phone: str 35 | active_organization: Optional[int] = None 36 | org_membership: Optional[List[OrgMembership]] = Field(default_factory=list) 37 | client: Client 38 | 39 | class Config: 40 | arbitrary_types_allowed = True 41 | 42 | def set_role(self, role: UserRole): 43 | """Set user role in current active organization 44 | 45 | Parameters 46 | ---------- 47 | role: label_studio_sdk.users.UserRole 48 | User role 49 | """ 50 | response = self.client.make_request( 51 | "PATCH", 52 | f"/api/organizations/{self.active_organization}/memberships", 53 | json={"user_id": self.id, "role": role.value}, 54 | ) 55 | for membership in self.org_membership: 56 | if membership.organization_id == self.active_organization: 57 | membership.role = UserRole 58 | return response 59 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/__init__.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from .types import ( 4 | ActionsCreateRequestFilters, 5 | ActionsCreateRequestFiltersConjunction, 6 | ActionsCreateRequestFiltersItemsItem, 7 | ActionsCreateRequestFiltersItemsItemFilter, 8 | ActionsCreateRequestFiltersItemsItemOperator, 9 | ActionsCreateRequestFiltersItemsItemValue, 10 | ActionsCreateRequestId, 11 | ActionsCreateRequestOrderingItem, 12 | ActionsCreateRequestSelectedItems, 13 | ActionsCreateRequestSelectedItemsExcluded, 14 | ActionsCreateRequestSelectedItemsIncluded, 15 | ) 16 | 17 | __all__ = [ 18 | "ActionsCreateRequestFilters", 19 | "ActionsCreateRequestFiltersConjunction", 20 | "ActionsCreateRequestFiltersItemsItem", 21 | "ActionsCreateRequestFiltersItemsItemFilter", 22 | "ActionsCreateRequestFiltersItemsItemOperator", 23 | "ActionsCreateRequestFiltersItemsItemValue", 24 | "ActionsCreateRequestId", 25 | "ActionsCreateRequestOrderingItem", 26 | "ActionsCreateRequestSelectedItems", 27 | "ActionsCreateRequestSelectedItemsExcluded", 28 | "ActionsCreateRequestSelectedItemsIncluded", 29 | ] 30 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/__init__.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from .actions_create_request_filters import ActionsCreateRequestFilters 4 | from .actions_create_request_filters_conjunction import ActionsCreateRequestFiltersConjunction 5 | from .actions_create_request_filters_items_item import ActionsCreateRequestFiltersItemsItem 6 | from .actions_create_request_filters_items_item_filter import ActionsCreateRequestFiltersItemsItemFilter 7 | from .actions_create_request_filters_items_item_operator import ActionsCreateRequestFiltersItemsItemOperator 8 | from .actions_create_request_filters_items_item_value import ActionsCreateRequestFiltersItemsItemValue 9 | from .actions_create_request_id import ActionsCreateRequestId 10 | from .actions_create_request_ordering_item import ActionsCreateRequestOrderingItem 11 | from .actions_create_request_selected_items import ActionsCreateRequestSelectedItems 12 | from .actions_create_request_selected_items_excluded import ActionsCreateRequestSelectedItemsExcluded 13 | from .actions_create_request_selected_items_included import ActionsCreateRequestSelectedItemsIncluded 14 | 15 | __all__ = [ 16 | "ActionsCreateRequestFilters", 17 | "ActionsCreateRequestFiltersConjunction", 18 | "ActionsCreateRequestFiltersItemsItem", 19 | "ActionsCreateRequestFiltersItemsItemFilter", 20 | "ActionsCreateRequestFiltersItemsItemOperator", 21 | "ActionsCreateRequestFiltersItemsItemValue", 22 | "ActionsCreateRequestId", 23 | "ActionsCreateRequestOrderingItem", 24 | "ActionsCreateRequestSelectedItems", 25 | "ActionsCreateRequestSelectedItemsExcluded", 26 | "ActionsCreateRequestSelectedItemsIncluded", 27 | ] 28 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_filters_conjunction.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | import typing 4 | 5 | ActionsCreateRequestFiltersConjunction = typing.Union[typing.Literal["or", "and"], typing.Any] 6 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_filters_items_item_filter.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | import typing 4 | 5 | ActionsCreateRequestFiltersItemsItemFilter = typing.Union[ 6 | typing.Literal[ 7 | "filter:tasks:agreement", 8 | "filter:tasks:annotations_results", 9 | "filter:tasks:annotators", 10 | "filter:tasks:cancelled_annotations", 11 | "filter:tasks:comments", 12 | "filter:tasks:completed_at", 13 | "filter:tasks:created_at", 14 | "filter:tasks:file_upload", 15 | "filter:tasks:ground_truth", 16 | "filter:tasks:id", 17 | "filter:tasks:inner_id", 18 | "filter:tasks:predictions_model_versions", 19 | "filter:tasks:predictions_results", 20 | "filter:tasks:predictions_score", 21 | "filter:tasks:reviewed", 22 | "filter:tasks:reviewers", 23 | "filter:tasks:reviews_accepted", 24 | "filter:tasks:reviews_rejected", 25 | "filter:tasks:total_annotations", 26 | "filter:tasks:total_predictions", 27 | "filter:tasks:unresolved_comment_count", 28 | "filter:tasks:updated_at", 29 | ], 30 | typing.Any, 31 | ] 32 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_filters_items_item_operator.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | import typing 4 | 5 | ActionsCreateRequestFiltersItemsItemOperator = typing.Union[ 6 | typing.Literal[ 7 | "contains", 8 | "ends_with", 9 | "equal", 10 | "exists", 11 | "greater", 12 | "greater_or_equal", 13 | "in", 14 | "less", 15 | "less_or_equal", 16 | "not_contains", 17 | "not_equal", 18 | "not_exists", 19 | "not_in", 20 | "starts_with", 21 | ], 22 | typing.Any, 23 | ] 24 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_filters_items_item_value.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | import typing 4 | 5 | ActionsCreateRequestFiltersItemsItemValue = typing.Union[ 6 | str, int, float, bool, typing.Dict[str, typing.Optional[typing.Any]] 7 | ] 8 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_id.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | import typing 4 | 5 | ActionsCreateRequestId = typing.Union[ 6 | typing.Literal[ 7 | "retrieve_tasks_predictions", 8 | "predictions_to_annotations", 9 | "remove_duplicates", 10 | "delete_tasks", 11 | "delete_ground_truths", 12 | "delete_tasks_annotations", 13 | "delete_tasks_reviews", 14 | "delete_tasks_predictions", 15 | "delete_reviewers", 16 | "delete_annotators", 17 | ], 18 | typing.Any, 19 | ] 20 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_ordering_item.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | import typing 4 | 5 | ActionsCreateRequestOrderingItem = typing.Union[ 6 | typing.Literal[ 7 | "tasks:agreement", 8 | "tasks:annotations_results", 9 | "tasks:annotators", 10 | "tasks:cancelled_annotations", 11 | "tasks:comments", 12 | "tasks:completed_at", 13 | "tasks:created_at", 14 | "tasks:file_upload", 15 | "tasks:ground_truth", 16 | "tasks:id", 17 | "tasks:inner_id", 18 | "tasks:predictions_model_versions", 19 | "tasks:predictions_results", 20 | "tasks:predictions_score", 21 | "tasks:reviewed", 22 | "tasks:reviewers", 23 | "tasks:reviews_accepted", 24 | "tasks:reviews_rejected", 25 | "tasks:total_annotations", 26 | "tasks:total_predictions", 27 | "tasks:unresolved_comment_count", 28 | "tasks:updated_at", 29 | ], 30 | typing.Any, 31 | ] 32 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_selected_items.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | import typing 4 | from .actions_create_request_selected_items_included import ActionsCreateRequestSelectedItemsIncluded 5 | from .actions_create_request_selected_items_excluded import ActionsCreateRequestSelectedItemsExcluded 6 | 7 | ActionsCreateRequestSelectedItems = typing.Union[ 8 | ActionsCreateRequestSelectedItemsIncluded, ActionsCreateRequestSelectedItemsExcluded 9 | ] 10 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_selected_items_excluded.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from ...core.pydantic_utilities import UniversalBaseModel 4 | import typing_extensions 5 | from ...core.serialization import FieldMetadata 6 | import pydantic 7 | import typing 8 | from ...core.pydantic_utilities import IS_PYDANTIC_V2 9 | 10 | 11 | class ActionsCreateRequestSelectedItemsExcluded(UniversalBaseModel): 12 | all_: typing_extensions.Annotated[bool, FieldMetadata(alias="all")] = pydantic.Field() 13 | """ 14 | All tasks are selected 15 | """ 16 | 17 | excluded: typing.Optional[typing.List[int]] = pydantic.Field(default=None) 18 | """ 19 | List of excluded task IDs 20 | """ 21 | 22 | if IS_PYDANTIC_V2: 23 | model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 24 | else: 25 | 26 | class Config: 27 | frozen = True 28 | smart_union = True 29 | extra = pydantic.Extra.allow 30 | -------------------------------------------------------------------------------- /src/label_studio_sdk/actions/types/actions_create_request_selected_items_included.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from ...core.pydantic_utilities import UniversalBaseModel 4 | import typing_extensions 5 | from ...core.serialization import FieldMetadata 6 | import pydantic 7 | import typing 8 | from ...core.pydantic_utilities import IS_PYDANTIC_V2 9 | 10 | 11 | class ActionsCreateRequestSelectedItemsIncluded(UniversalBaseModel): 12 | all_: typing_extensions.Annotated[bool, FieldMetadata(alias="all")] = pydantic.Field() 13 | """ 14 | No tasks are selected 15 | """ 16 | 17 | included: typing.Optional[typing.List[int]] = pydantic.Field(default=None) 18 | """ 19 | List of included task IDs 20 | """ 21 | 22 | if IS_PYDANTIC_V2: 23 | model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 24 | else: 25 | 26 | class Config: 27 | frozen = True 28 | smart_union = True 29 | extra = pydantic.Extra.allow 30 | -------------------------------------------------------------------------------- /src/label_studio_sdk/annotations/__init__.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from .types import AnnotationsCreateBulkRequestSelectedItems, AnnotationsCreateBulkResponseItem 4 | 5 | __all__ = ["AnnotationsCreateBulkRequestSelectedItems", "AnnotationsCreateBulkResponseItem"] 6 | -------------------------------------------------------------------------------- /src/label_studio_sdk/annotations/types/__init__.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from .annotations_create_bulk_request_selected_items import AnnotationsCreateBulkRequestSelectedItems 4 | from .annotations_create_bulk_response_item import AnnotationsCreateBulkResponseItem 5 | 6 | __all__ = ["AnnotationsCreateBulkRequestSelectedItems", "AnnotationsCreateBulkResponseItem"] 7 | -------------------------------------------------------------------------------- /src/label_studio_sdk/annotations/types/annotations_create_bulk_request_selected_items.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from ...core.pydantic_utilities import UniversalBaseModel 4 | import typing_extensions 5 | import typing 6 | from ...core.serialization import FieldMetadata 7 | import pydantic 8 | from ...core.pydantic_utilities import IS_PYDANTIC_V2 9 | 10 | 11 | class AnnotationsCreateBulkRequestSelectedItems(UniversalBaseModel): 12 | all_: typing_extensions.Annotated[typing.Optional[bool], FieldMetadata(alias="all")] = pydantic.Field(default=None) 13 | """ 14 | Indicates whether to apply the operation to all tasks. If true, this overrides any included or excluded lists. 15 | """ 16 | 17 | included: typing.Optional[typing.List[int]] = pydantic.Field(default=None) 18 | """ 19 | An explicit list of task IDs to include. 20 | """ 21 | 22 | excluded: typing.Optional[typing.List[int]] = pydantic.Field(default=None) 23 | """ 24 | An explicit list of task IDs to exclude. 25 | """ 26 | 27 | if IS_PYDANTIC_V2: 28 | model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 29 | else: 30 | 31 | class Config: 32 | frozen = True 33 | smart_union = True 34 | extra = pydantic.Extra.allow 35 | -------------------------------------------------------------------------------- /src/label_studio_sdk/annotations/types/annotations_create_bulk_response_item.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | from ...core.pydantic_utilities import UniversalBaseModel 4 | import typing 5 | from ...core.pydantic_utilities import IS_PYDANTIC_V2 6 | import pydantic 7 | 8 | 9 | class AnnotationsCreateBulkResponseItem(UniversalBaseModel): 10 | id: typing.Optional[int] = None 11 | 12 | if IS_PYDANTIC_V2: 13 | model_config: typing.ClassVar[pydantic.ConfigDict] = pydantic.ConfigDict(extra="allow", frozen=True) # type: ignore # Pydantic v2 14 | else: 15 | 16 | class Config: 17 | frozen = True 18 | smart_union = True 19 | extra = pydantic.Extra.allow 20 | -------------------------------------------------------------------------------- /src/label_studio_sdk/client.py: -------------------------------------------------------------------------------- 1 | from .base_client import LabelStudioBase, AsyncLabelStudioBase 2 | from .tasks.client_ext import TasksClientExt, AsyncTasksClientExt 3 | from .projects.client_ext import ProjectsClientExt, AsyncProjectsClientExt 4 | from .core.api_error import ApiError 5 | 6 | 7 | class LabelStudio(LabelStudioBase): 8 | """""" 9 | __doc__ += LabelStudioBase.__doc__ 10 | 11 | def __init__(self, *args, **kwargs): 12 | super().__init__(*args, **kwargs) 13 | 14 | self.tasks = TasksClientExt(client_wrapper=self._client_wrapper) 15 | self.projects = ProjectsClientExt(client_wrapper=self._client_wrapper) 16 | 17 | 18 | class AsyncLabelStudio(AsyncLabelStudioBase): 19 | """""" 20 | __doc__ += AsyncLabelStudioBase.__doc__ 21 | 22 | def __init__(self, *args, **kwargs): 23 | super().__init__(*args, **kwargs) 24 | 25 | self.tasks = AsyncTasksClientExt(client_wrapper=self._client_wrapper) 26 | self.projects = AsyncProjectsClientExt(client_wrapper=self._client_wrapper) 27 | -------------------------------------------------------------------------------- /src/label_studio_sdk/comments/__init__.py: -------------------------------------------------------------------------------- 1 | # This file was auto-generated by Fern from our API Definition. 2 | 3 | -------------------------------------------------------------------------------- /src/label_studio_sdk/converter/__init__.py: -------------------------------------------------------------------------------- 1 | # try is used here to import this file in setup.py and don't break the setup process 2 | try: 3 | from .converter import Converter 4 | except ModuleNotFoundError as e: 5 | print(e) 6 | 7 | __version__ = "0.0.59.dev" 8 | -------------------------------------------------------------------------------- /src/label_studio_sdk/converter/exports/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/src/label_studio_sdk/converter/exports/__init__.py -------------------------------------------------------------------------------- /src/label_studio_sdk/converter/imports/__init__.py: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/HumanSignal/label-studio-sdk/855b393d63e26a750a1e0ecad8a616313afa9f4a/src/label_studio_sdk/converter/imports/__init__.py -------------------------------------------------------------------------------- /src/label_studio_sdk/converter/imports/label_config.py: -------------------------------------------------------------------------------- 1 | from label_studio_sdk.converter.imports.colors import COLORS 2 | 3 | 4 | LABELS = """ 5 | <{# TAG_NAME #} name="{# FROM_NAME #}" toName="image"> 6 | {# LABELS #} 7 | """ 8 | 9 | LABELING_CONFIG = """ 10 | 11 | {# BODY #} 12 | """ 13 | 14 | 15 | def generate_label_config( 16 | categories, tags, to_name="image", from_name="label", filename=None 17 | ): 18 | labels = "" 19 | for key in sorted(categories.keys()): 20 | color = COLORS[int(key) % len(COLORS)] 21 | label = f'