From cc2c547ad763deb59c32fd2535d4618015efe241 Mon Sep 17 00:00:00 2001 From: jcchr Date: Tue, 26 Aug 2025 16:27:19 +0200 Subject: [PATCH 1/7] rebranding of Geti --- CHANGELOG.md | 126 +++++++++--------- CONTRIBUTING.md | 2 +- README.md | 26 ++-- docs/source/conf.py | 2 +- docs/source/index.rst | 14 +- geti_sdk/__init__.py | 8 +- geti_sdk/annotation_readers/__init__.py | 2 +- .../base_annotation_reader.py | 2 +- .../directory_tree_annotation_reader.py | 2 +- .../geti_annotation_reader.py | 14 +- geti_sdk/benchmarking/__init__.py | 2 +- geti_sdk/benchmarking/benchmarker.py | 4 +- geti_sdk/data_models/algorithms.py | 2 +- geti_sdk/data_models/annotations.py | 2 +- geti_sdk/data_models/code_deployment_info.py | 2 +- .../data_models/configuration_identifiers.py | 6 +- .../data_models/containers/algorithm_list.py | 8 +- geti_sdk/data_models/containers/label_list.py | 2 +- geti_sdk/data_models/containers/media_list.py | 6 +- geti_sdk/data_models/credit_system.py | 6 +- geti_sdk/data_models/dataset.py | 2 +- geti_sdk/data_models/enums/annotation_kind.py | 2 +- .../data_models/enums/annotation_state.py | 2 +- .../data_models/enums/configuration_enums.py | 8 +- geti_sdk/data_models/enums/dataset_format.py | 2 +- .../data_models/enums/deployment_state.py | 2 +- geti_sdk/data_models/enums/domain.py | 2 +- geti_sdk/data_models/enums/job_state.py | 2 +- geti_sdk/data_models/enums/job_type.py | 2 +- .../data_models/enums/optimization_type.py | 2 +- geti_sdk/data_models/enums/prediction_mode.py | 2 +- geti_sdk/data_models/enums/shape_type.py | 2 +- .../data_models/enums/subscription_status.py | 2 +- geti_sdk/data_models/enums/subset_purpose.py | 2 +- geti_sdk/data_models/enums/task_type.py | 2 +- geti_sdk/data_models/job.py | 18 +-- geti_sdk/data_models/media.py | 36 ++--- geti_sdk/data_models/media_identifiers.py | 14 +- geti_sdk/data_models/model.py | 26 ++-- geti_sdk/data_models/model_group.py | 6 +- geti_sdk/data_models/performance.py | 4 +- geti_sdk/data_models/predictions.py | 12 +- geti_sdk/data_models/project.py | 2 +- geti_sdk/data_models/shapes.py | 16 +-- geti_sdk/data_models/task_annotation_state.py | 2 +- geti_sdk/data_models/test_result.py | 2 +- geti_sdk/data_models/user.py | 2 +- geti_sdk/demos/__init__.py | 2 +- geti_sdk/demos/demo_projects/anomaly_demos.py | 4 +- geti_sdk/demos/demo_projects/coco_demos.py | 10 +- geti_sdk/deployment/__init__.py | 4 +- geti_sdk/deployment/deployed_model.py | 4 +- geti_sdk/deployment/deployment.py | 2 +- geti_sdk/deployment/resources/OVMS_README.md | 6 +- geti_sdk/geti.py | 58 ++++---- geti_sdk/http_session/exception.py | 6 +- geti_sdk/http_session/geti_session.py | 40 +++--- geti_sdk/http_session/server_config.py | 10 +- geti_sdk/import_export/__init__.py | 2 +- .../import_export/import_export_module.py | 4 +- geti_sdk/platform_versions.py | 10 +- .../actions/geti_data_collection.py | 12 +- geti_sdk/prediction_visualization/__init__.py | 2 +- geti_sdk/rest_clients/__init__.py | 2 +- .../rest_clients/active_learning_client.py | 2 +- .../annotation_clients/annotation_client.py | 4 +- .../base_annotation_client.py | 4 +- geti_sdk/rest_clients/credit_system_client.py | 8 +- geti_sdk/rest_clients/dataset_client.py | 4 +- geti_sdk/rest_clients/deployment_client.py | 4 +- .../rest_clients/media_client/media_client.py | 6 +- .../rest_clients/media_client/video_client.py | 2 +- geti_sdk/rest_clients/model_client.py | 16 +-- geti_sdk/rest_clients/prediction_client.py | 12 +- .../project_client/project_client.py | 28 ++-- geti_sdk/rest_clients/testing_client.py | 4 +- geti_sdk/rest_clients/training_client.py | 8 +- .../annotation_rest_converter.py | 2 +- .../configuration_rest_converter.py | 14 +- .../rest_converters/job_rest_converter.py | 4 +- .../rest_converters/media_rest_converter.py | 4 +- .../rest_converters/model_rest_converter.py | 8 +- .../normalized_prediction_rest_converter.py | 2 +- .../prediction_rest_converter.py | 2 +- .../rest_converters/project_rest_converter.py | 6 +- .../rest_converters/status_rest_converter.py | 4 +- .../test_result_rest_converter.py | 4 +- geti_sdk/utils/algorithm_helpers.py | 2 +- geti_sdk/utils/job_helpers.py | 18 +-- geti_sdk/utils/label_helpers.py | 2 +- .../002_create_project_from_dataset.ipynb | 4 +- notebooks/009_post_inference_hooks.ipynb | 2 +- notebooks/012_benchmarking_models.ipynb | 2 +- notebooks/README.md | 6 +- ...imulate_low_light_product_inspection.ipynb | 8 +- .../102_from_zero_to_hero_9_steps.ipynb | 38 +++--- .../103_parking_lot_train2deployment.ipynb | 44 +++--- notebooks/use_cases/utils/upload.py | 4 +- pyproject.toml | 2 +- tests/README.md | 22 +-- .../datumaro_annotation_reader.py | 4 +- .../datumaro_dataset.py | 4 +- tests/helpers/project_helpers.py | 2 +- tests/pre-merge/unit/test_platform_version.py | 2 +- 104 files changed, 455 insertions(+), 455 deletions(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index ff71d9069..4bff6705f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,4 +1,4 @@ -# v2.12.0 Intel® Geti™ SDK +# v2.12.0 Geti™ SDK ## What's Changed @@ -47,7 +47,7 @@ **Full Changelog**: https://github.com/open-edge-platform/geti-sdk/compare/v2.11.0...v2.12.0 -# v2.11.0 Intel® Geti™ SDK (15-07-2025) +# v2.11.0 Geti™ SDK (15-07-2025) ## What's Changed @@ -76,7 +76,7 @@ **Full Changelog**: https://github.com/open-edge-platform/geti-sdk/compare/v2.10.2...v2.11.0 -# v2.10.2 Intel® Geti™ SDK (04-07-2025) +# v2.10.2 Geti™ SDK (04-07-2025) ## What's Changed Bugfixes: @@ -85,7 +85,7 @@ Bugfixes: **Full Changelog**: https://github.com/open-edge-platform/geti-sdk/compare/v2.10.1...v2.10.2 -# v2.10.1 Intel® Geti™ SDK (30-06-2025) +# v2.10.1 Geti™ SDK (30-06-2025) ## What's Changed Bugfixes: @@ -94,7 +94,7 @@ Bugfixes: **Full Changelog**: https://github.com/open-edge-platform/geti-sdk/compare/v2.10.0...v2.10.1 -# v2.10.0 Intel® Geti™ SDK (30-05-2025) +# v2.10.0 Geti™ SDK (30-05-2025) ## What's Changed Features: @@ -125,10 +125,10 @@ Extra: **Full Changelog**: https://github.com/open-edge-platform/geti-sdk/compare/v2.8.0...v2.10.0 -# v2.9.0 Intel® Geti™ SDK (skipped) +# v2.9.0 Geti™ SDK (skipped) -# v2.8.0 Intel® Geti™ SDK (17-03-2025) +# v2.8.0 Geti™ SDK (17-03-2025) ## What's Changed * Bugfix: inference would sometimes fail if labels have number-like names by @maxxgx in https://github.com/openvinotoolkit/geti-sdk/pull/567 @@ -139,7 +139,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.7.1...v2.8.0 -# v2.7.1 Intel® Geti™ SDK (26-02-2025) +# v2.7.1 Geti™ SDK (26-02-2025) ## What's Changed * Bugfix: automatic workspace selection would sometimes not work by @leoll2 in https://github.com/openvinotoolkit/geti-sdk/pull/565 @@ -147,7 +147,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.7.0...v.2.7.1 -# v2.7.0 Intel® Geti™ SDK (17-02-2025) +# v2.7.0 Geti™ SDK (17-02-2025) ## What's Changed * Added support for Python 3.12 by @gdlg in https://github.com/openvinotoolkit/geti-sdk/pull/549 @@ -163,14 +163,14 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.6.2...v.2.7.0 -# v2.6.2 Intel® Geti™ SDK (08-01-2025) +# v2.6.2 Geti™ SDK (08-01-2025) ## What's Changed * Bugfix: inference not working for classification projects with label containing spaces in their name by @maxxgx in https://github.com/openvinotoolkit/geti-sdk/pull/539 **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.6.1...v2.6.2 -# v2.6.1 Intel® Geti™ SDK (02-01-2025) +# v2.6.1 Geti™ SDK (02-01-2025) ## What's Changed * Bugfix: empty label sometimes not recognized during inference by @maxxgx in https://github.com/openvinotoolkit/geti-sdk/pull/534 @@ -180,7 +180,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.6.0...v2.6.1 -# v2.6.0 Intel® Geti™ SDK (26-12-2024) +# v2.6.0 Geti™ SDK (26-12-2024) ## What's Changed * Updated model representation to that of Geti V2.6 by @Daankrol in https://github.com/openvinotoolkit/geti-sdk/pull/523 * Mark model response fields as deprecated in 2.6 instead of removed by @leoll2 in https://github.com/openvinotoolkit/geti-sdk/pull/528 @@ -191,7 +191,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.5.0...v2.6.0 -# v2.5.0 Intel® Geti™ SDK (22-10-2024) +# v2.5.0 Geti™ SDK (22-10-2024) ## What's Changed * Introduce `delete_dataset` method by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/489 * Update the download_all method for ImageClient to download specific dataset by @rajeshgangireddy in https://github.com/openvinotoolkit/geti-sdk/pull/484 @@ -220,7 +220,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.3.0...v2.5.0 -# v2.3.0 Intel® Geti™ SDK (03-09-2024) +# v2.3.0 Geti™ SDK (03-09-2024) ## What's Changed * Add method to purge models by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/468 * Fix visualization in 008 example notebook by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/472 @@ -234,7 +234,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.2.0...v2.3.0 -# v2.2.0 Intel® Geti™ SDK (18-07-2024) +# v2.2.0 Geti™ SDK (18-07-2024) ## What's Changed * Add `description` attribute to the job class by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/448 * Project/Dataset export import API alignment by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/446 @@ -259,7 +259,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/releases/v2.1.0...1234 -# v2.1.0 Intel® Geti™ SDK (19-06-2024) +# v2.1.0 Geti™ SDK (19-06-2024) ## What's Changed * Saliency map visualization by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/424 * Add a model management notebook by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/419 @@ -285,7 +285,7 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.0.1...v2.1.0 -# v2.0.1 Intel® Geti™ SDK (29-05-2024) +# v2.0.1 Geti™ SDK (29-05-2024) ## What's Changed * Add retry mechanism to better handle `ConnectionError` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/420 * Undo changes to video tempfile handling, register atexit handler for tempfile deletion by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/423 @@ -293,16 +293,16 @@ Extra: **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v2.0.0...v2.0.1 -# v2.0.0 Intel® Geti™ SDK (16-05-2024) +# v2.0.0 Geti™ SDK (16-05-2024) ## New features This release introduces a new feature related to model deployment: post-inference hooks! A post-inference hook can be added to any `Deployment`, and will be executed after every inference request (i.e. every call to `deployment.infer()`). The hooks allow you to define specific actions to take under certain conditions. For example, a hook could implement the following behaviour: -**If** the confidence level of one of the predictions for the image is less than 20%, **then** upload the image to the Intel® Geti™ project in which the model was trained. +**If** the confidence level of one of the predictions for the image is less than 20%, **then** upload the image to the Geti™ project in which the model was trained. This could be useful for improving your model with a next training round, because including such 'low confidence images' in the training dataset might help to improve model accuracy. Additional examples of post-inference hooks, and instructions for configuring them, can be found in the newly added [notebook 012](https://github.com/openvinotoolkit/geti-sdk/blob/main/notebooks/012_post_inference_hooks.ipynb) in this repository. ## Breaking changes -This major release of the Intel® Geti™ SDK breaks backwards compatibility with Intel® Geti™ servers of version v1.14 and below. Please make sure that your Intel® Geti™ server is updated to the latest version of the Intel® Geti™ platform, to prevent compatibility issues. +This major release of the Geti™ SDK breaks backwards compatibility with Geti™ servers of version v1.14 and below. Please make sure that your Geti™ server is updated to the latest version of the Geti™ platform, to prevent compatibility issues. ## What's Changed * Update `Video` data model with annotation statistics by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/391 @@ -338,14 +338,14 @@ This major release of the Intel® Geti™ SDK breaks backwards compatibility wit **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.16.1...v2.0.0 -# v1.16.1 Intel® Geti™ SDK (22-04-2024) +# v1.16.1 Geti™ SDK (22-04-2024) ## What's Changed * Add `default_workspace` to possible default workspace names by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/394 **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.16.0...v1.16.1 -# v1.16.0 Intel® Geti™ SDK (26-03-2024) +# v1.16.0 Geti™ SDK (26-03-2024) ## What's Changed * Decouple visualizer for OTX by @igor-davidyuk in https://github.com/openvinotoolkit/geti-sdk/pull/356 * Update data models to account for REST API changes in Geti v1.16 by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/357 @@ -357,11 +357,11 @@ This major release of the Intel® Geti™ SDK breaks backwards compatibility wit **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.15.0...v1.16.0 -# v1.15.0 Intel® Geti™ SDK (12-03-2024) -This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of the changes is focused on that, but below is a list of other changes that are worth mentioning. +# v1.15.0 Geti™ SDK (12-03-2024) +This release makes the SDK compatible for Geti™ v1.15. The majority of the changes is focused on that, but below is a list of other changes that are worth mentioning. ## Release Highlights -- Add compatibility for Intel® Geti™ v1.15. Note that we maintain backwards compatibility for models created in Intel® Geti™ v1.8: This means that the SDK can run inference on deployments from both both the latest Intel® Geti™ on-prem release and Intel® Geti™ SaaS. +- Add compatibility for Geti™ v1.15. Note that we maintain backwards compatibility for models created in Geti™ v1.8: This means that the SDK can run inference on deployments from both both the latest Geti™ on-prem release and Geti™ SaaS. - Add benchmarking functionality for deployments through the `Benchmarker` class, as well as a new notebook to demonstrate this feature. - Improve the job monitoring feature, job progression is now displayed via progress bars. - Image and annotation upload and download now uses multithreading, greatly speeding up the process. @@ -424,7 +424,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v.1.8.2...v1.15.0 -# v1.8.2 Intel® Geti™ SDK (22-02-2024) +# v1.8.2 Geti™ SDK (22-02-2024) ## What's Changed * Update `opencv-python` requirement to `4.9.*` * Update `Pillow` requirement to `10.2.*` @@ -434,7 +434,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v.1.8.1...v.1.8.2 -# v1.8.1 Intel® Geti™ SDK (20-11-2023) +# v1.8.1 Geti™ SDK (20-11-2023) ## What's Changed * Update pytest requirement from ==7.3.* to ==7.4.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/261 * Update pytest-env requirement from ==0.8.* to ==1.0.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/275 @@ -443,7 +443,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v.1.8.0...v.1.8.1 -# v1.8.0 Intel® Geti™ SDK (16-10-2023) +# v1.8.0 Geti™ SDK (16-10-2023) ## What's Changed * Predict video on local by @jihyeonyi in https://github.com/openvinotoolkit/geti-sdk/pull/243 * Update job datamodel for new job scheduler by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/251 @@ -474,7 +474,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.8...v.1.8.0 -# v1.5.8 Intel® Geti™ SDK (19-06-2023) +# v1.5.8 Geti™ SDK (19-06-2023) ## What's Changed * Update vcrpy requirement from ==4.2.* to ==4.3.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/227 * Specify correct project name in notebook 009 by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/229 @@ -490,7 +490,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.7...v1.5.8 -# v1.5.7 Intel® Geti™ SDK (30-05-2023) +# v1.5.7 Geti™ SDK (30-05-2023) ## What's Changed * Allow more efficient image uploading for datumaro annotation readers by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/224 * Fix deployment for `otx v1.2.2` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/225 @@ -498,7 +498,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.6...v1.5.7 -# v1.5.6 Intel® Geti™ SDK (23-05-2023) +# v1.5.6 Geti™ SDK (23-05-2023) ## What's Changed * Add `group` key to hierarchical label definition in notebook 001 by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/220 * Add `TestingClient` to perform model tests by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/221 @@ -508,14 +508,14 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.5...v1.5.6 -# v1.5.5 Intel® Geti™ SDK (15-05-2023) +# v1.5.5 Geti™ SDK (15-05-2023) ## What's Changed * Add param to disable certificate validation for data download helpers by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/218 **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.4...v1.5.5 -# v1.5.4 Intel® Geti™ SDK (11-05-2023) +# v1.5.4 Geti™ SDK (11-05-2023) ## What's Changed * Add active learning client for retrieving the active set by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/215 * Allow passing label dictionaries to `Geti.create_single_task_project_from_dataset` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/216 @@ -524,7 +524,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.3...v1.5.4 -# v1.5.3 Intel® Geti™ SDK (10-05-2023) +# v1.5.3 Geti™ SDK (10-05-2023) ## What's Changed * Add `ONNX` as optimization type by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/212 * Remove trailing slash from the base url in the media rest client by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/214 @@ -534,7 +534,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.2...v1.5.3 -# v1.5.2 Intel® Geti™ SDK (08-05-2023) +# v1.5.2 Geti™ SDK (08-05-2023) ## What's Changed * Add score NoneType check in summary function of ProjectStatus by @harimkang in https://github.com/openvinotoolkit/geti-sdk/pull/208 * Update `OptimizedModel` data model by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/209 @@ -545,7 +545,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.1...v1.5.2 -# v1.5.1 Intel® Geti™ SDK (26-04-2023) +# v1.5.1 Geti™ SDK (26-04-2023) ## What's Changed * Update hashing algorithm to `sha3_512` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/204 * Bump otx from 1.1.2 to 1.2.0 in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/203 @@ -554,7 +554,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.5.0...v1.5.1 -# v1.5.0 Intel® Geti™ SDK (24-04-2023) +# v1.5.0 Geti™ SDK (24-04-2023) ## What's Changed * Pin orjson version to 3.8.8 to avoid installation error by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/178 * Fix nightly tests for classification project by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/179 @@ -585,7 +585,7 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.4.1...v1.5.0 -# [Pre-release] v1.4.1 Intel® Geti™ SDK (28-03-2023) +# [Pre-release] v1.4.1 Geti™ SDK (28-03-2023) ## What's Changed * Update otx requirement to `otx==1.1.0` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/176 * Make model wrapper module namespace unique by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/177 @@ -593,16 +593,16 @@ This release makes the SDK compatible for Intel® Geti™ v1.15. The majority of **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.4.0...v1.4.1 -# [Pre-release] v1.4.0 Intel® Geti™ SDK (27-03-2023) +# [Pre-release] v1.4.0 Geti™ SDK (27-03-2023) ## What's Changed * Migrate from `ote_sdk` to `otx.api` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/166 ## Caution: Backwards incompatibility for project `Deployments` -This release breaks backwards compatibility with `deployments` created by earlier versions of the Intel® Geti™ platform. Please only update to this version of the Geti SDK if you are sure that your Intel® Geti™ server is also on version 1.4 or later. +This release breaks backwards compatibility with `deployments` created by earlier versions of the Geti™ platform. Please only update to this version of the Geti SDK if you are sure that your Geti™ server is also on version 1.4 or later. **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.2.4...v1.4.0 -# v1.2.4 Intel® Geti™ SDK (27-03-2023) +# v1.2.4 Geti™ SDK (27-03-2023) ## What's Changed * Update ipython requirement from ==8.10.* to ==8.11.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/172 * Fix `upload_and_predict_from_numpy.py` example by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/173 @@ -611,7 +611,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.2.3...v1.2.4 -# v1.2.3 Intel® Geti™ SDK (13-03-2023) +# v1.2.3 Geti™ SDK (13-03-2023) ## What's Changed * Fix saving images and annotations with non-ascii characters in their filename by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/160 * Update tqdm requirement from ==4.64.* to ==4.65.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/161 @@ -631,7 +631,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.2.2...v1.2.3 -# v1.2.2 Intel® Geti™ SDK (28-02-2023) +# v1.2.2 Geti™ SDK (28-02-2023) ## What's Changed * Enable OVMS deployment by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/148 * Minor fixes for notebook 010 by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/149 @@ -645,7 +645,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.2.1...v1.2.2 -# v1.2.1 Intel® Geti™ SDK (02-02-2023) +# v1.2.1 Geti™ SDK (02-02-2023) ## What's Changed * Fix issue with deployment for anomaly classification models by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/144 * Require `mistune>=2.0.3` for notebooks by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/147 @@ -655,7 +655,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.2.0...v1.2.1 -# v1.2 Intel® Geti™ SDK (24-01-2023) +# v1.2 Geti™ SDK (24-01-2023) ## What's Changed * Add `size` field to MediaInformation data model by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/133 * Update available Geti versions by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/134 @@ -674,7 +674,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.1.1...v1.2.0 -# v1.1.1 Intel® Geti™ SDK (20-12-2022) +# v1.1.1 Geti™ SDK (20-12-2022) ## What's Changed * Fix issue with model to dictionary conversion by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/128 * Only submit train request once all running jobs for task have finished by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/129 @@ -682,7 +682,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.1.0...v1.1.1 -# v1.1.0 Intel® Geti™ SDK (15-12-2022) +# v1.1.0 Geti™ SDK (15-12-2022) ## What's Changed * Minor fix in README.md by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/118 * Fix and improve geti version comparison mechanism by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/117 @@ -695,7 +695,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.0.4...v1.1.0 -# v1.0.4 Intel® Geti™ SDK (08-12-2022) +# v1.0.4 Geti™ SDK (08-12-2022) ## What's Changed * Update ipython requirement from ==8.6.* to ==8.7.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/112 * Properly check for empty annotation before uploading by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/111 @@ -707,7 +707,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.0.3...v1.0.4 -# v1.0.3 Intel® Geti™ SDK (25-11-2022) +# v1.0.3 Geti™ SDK (25-11-2022) ## What's Changed * Add `ScoreMetadata` to represent the new `scores` field by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/106 * Add model and prediction client integration tests + update cassettes by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/107 @@ -717,7 +717,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.0.2...v1.0.3 -# v1.0.2 Intel® Geti™ SDK (17-11-2022) +# v1.0.2 Geti™ SDK (17-11-2022) ## What's Changed * Update ote-sdk requirement to v0.3.1 by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/98 * Add integration tests for `project_client`, fix `project_client.add_labels` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/99 @@ -729,7 +729,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.0.1...v1.0.2 -# v1.0.1 Intel® Geti™ SDK (11-11-2022) +# v1.0.1 Geti™ SDK (11-11-2022) ## What's Changed * Add path validation to project download target path by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/87 * Update tqdm requirement from ==4.62.* to ==4.64.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/84 @@ -737,7 +737,7 @@ This release breaks backwards compatibility with `deployments` created by earlie * Add security note to README for project download by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/88 * Update numpy requirement to 1.21.* by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/89 * Reduce permissions upon directory creation by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/90 -* Update README to correctly reference Intel Geti brand everywhere by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/92 +* Update README to correctly reference Geti brand everywhere by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/92 * Improve check for video processing in `Geti.upload_project_data()` to avoid potential infinite loop by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/93 * Add unit tests to pre-merge test suite by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/91 * Update ProjectStatus and TaskStatus to include new field `n_new_annotations` by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/94 @@ -747,7 +747,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v1.0.0...v1.0.1 -# v1.0.0 Intel® Geti™ SDK (04-11-2022) +# v1.0.0 Geti™ SDK (04-11-2022) ## What's Changed * Add a re-authentication mechanism when using token authentication by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/72 * Update pytest requirement from ==7.1.* to ==7.2.* in /requirements by @dependabot in https://github.com/openvinotoolkit/geti-sdk/pull/73 @@ -768,7 +768,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v0.2.4...v1.0.0rc1 -# v0.2.4 Intel® Geti™ SDK (25-10-2022) +# v0.2.4 Geti™ SDK (25-10-2022) ## What's Changed * Auto detect normalized annotation files for GetiAnnotationReader by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/63 * Fix version detection mechanism and add tests for GetiVersion by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/64 @@ -782,7 +782,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v0.2.3...v0.2.4 -# v0.2.3 Intel® Geti™ SDK (06-10-2022) +# v0.2.3 Geti™ SDK (06-10-2022) ## What's Changed * Remove VCR from nightly test for demos by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/54 * Improve nightly tests for `demos` module by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/55 @@ -795,7 +795,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v0.2.2...v0.2.3 -# v0.2.2 Intel® Geti™ SDK (04-10-2022) +# v0.2.2 Geti™ SDK (04-10-2022) ## What's Changed * Add coverage report to pre-merge and nightly test artifacts by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/47 * Correctly set permissions on extracted files for anomaly dataset by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/51 @@ -805,7 +805,7 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v0.2.1...v0.2.2 -# v0.2.1 Intel® Geti™ SDK (30-09-2022) +# v0.2.1 Geti™ SDK (30-09-2022) ## What's Changed * Replace SC references in docstrings by Geti by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/33 * Change package name from `geti_sdk` to `geti-sdk`. Import names are unchanged by @ljcornel in https://github.com/openvinotoolkit/geti-sdk/pull/34 @@ -825,20 +825,20 @@ This release breaks backwards compatibility with `deployments` created by earlie **Full Changelog**: https://github.com/openvinotoolkit/geti-sdk/compare/v0.2.0...v0.2.1 -# v0.2.0 Intel® Geti™ SDK (27-09-2022) +# v0.2.0 Geti™ SDK (27-09-2022) -This is the first official release of the Intel® Geti™ Software Development Kit (SDK). +This is the first official release of the Geti™ Software Development Kit (SDK). The purpose of this SDK is twofold: -1. Provide an easy-to-use interface to the [Intel® Geti™ platform](www.geti.intel.com), to manipulate -Intel® Geti™ projects and other entities or automate tasks on the platform. All +1. Provide an easy-to-use interface to the [Geti™ platform](www.geti.intel.com), to manipulate +Geti™ projects and other entities or automate tasks on the platform. All of this from a Python script or Jupyter notebook. -2. Provide an API to deploy and run models trained on the Intel® Geti™ server on your local +2. Provide an API to deploy and run models trained on the Geti™ server on your local machine. The SDK Deployment module provides a straightforward -route to create a deployment for your Intel® Geti™ project, save it to a local disk and run +route to create a deployment for your Geti™ project, save it to a local disk and run it offline. This SDK includes various example scripts and Jupyter notebooks which illustrate a diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index 6d969d3e7..bc1af5f0c 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -1,4 +1,4 @@ -We appreciate any contribution to the Intel® Geti™ SDK, whether it's in the form of a +We appreciate any contribution to the Geti™ SDK, whether it's in the form of a Pull Request, Feature Request or general comment/issue that you found. For feature requests and issues, please feel free to create a GitHub Issue in this repository. diff --git a/README.md b/README.md index 3b78faa54..96245cf4d 100644 --- a/README.md +++ b/README.md @@ -5,7 +5,7 @@ Intel® Geti™ enables anyone from domain experts to data scientists to rapidly develop production-ready AI models.

@@ -13,7 +13,7 @@
[![python](https://img.shields.io/badge/python-3.10%2B-green)]() -![Intel Geti](https://img.shields.io/badge/Intel%C2%AE%20Geti%E2%84%A2-2.12-blue?link=https%3A%2F%2Fgeti.intel.com%2F) +![Geti](https://img.shields.io/badge/Intel%C2%AE%20Geti%E2%84%A2-2.12-blue?link=https%3A%2F%2Fgeti.intel.com%2F) [![openvino](https://img.shields.io/badge/openvino-2025.2-purple)](https://github.com/openvinotoolkit/openvino) ![Pre-merge Tests Status](https://img.shields.io/github/actions/workflow/status/open-edge-platform/geti-sdk/pre-merge-tests.yml?label=pre-merge%20tests&link=https%3A%2F%2Fgithub.com%2Fopen-edge-platform%2Fgeti-sdk%2Factions%2Fworkflows%2Fpre-merge-tests.yml) @@ -26,12 +26,12 @@ # Geti SDK -Geti SDK is a Python client for programmatically interacting with an [Intel® Geti™](https://github.com/open-edge-platform/geti) server via its [REST API](https://docs.geti.intel.com/docs/rest-api/openapi-specification). +Geti SDK is a Python client for programmatically interacting with an [Geti™](https://github.com/open-edge-platform/geti) server via its [REST API](https://docs.geti.intel.com/docs/rest-api/openapi-specification). With Geti SDK, you can automate and streamline computer vision workflows, making it easy to manage datasets, train models, and deploy solutions directly from your Python environment. -- [About Intel® Geti™](#what-is-intel-geti) +- [About Geti™](#what-is-intel-geti) - [Install the SDK](#install-the-sdk) * [From PyPI](#from-pypi) * [From source](#from-source) @@ -48,9 +48,9 @@ With Geti SDK, you can automate and streamline computer vision workflows, making -### What is Intel® Geti™? +### What is Geti™? -[Intel® Geti™](https://github.com/open-edge-platform/geti) is an AI platform designed to help anyone build state-of-the-art computer vision models quickly and efficiently, even with minimal data. +[Geti™](https://github.com/open-edge-platform/geti) is an AI platform designed to help anyone build state-of-the-art computer vision models quickly and efficiently, even with minimal data. It provides an end-to-end workflow for preparing, training, deploying, and running computer vision models at the edge. Geti™ supports the full AI model lifecycle, including dataset preparation, model training, and deployment of [OpenVINO™](https://docs.openvino.ai/)-optimized models. ### What can you do with Geti SDK? @@ -68,7 +68,7 @@ With Geti SDK, you can: ### Tutorials and Examples The ['Code examples'](#code-examples) sections below contains short snippets that demonstrate -how to perform several common tasks. This also shows how to configure the SDK to connect to your Intel® Geti™ server. +how to perform several common tasks. This also shows how to configure the SDK to connect to your Geti™ server. For more comprehensive examples, see the [Jupyter notebooks](https://github.com/open-edge-platform/geti-sdk/tree/main/notebooks). These tutorials demonstrate how to use the SDK for various computer vision tasks and workflows, from basic project creation @@ -137,15 +137,15 @@ Follow these steps to install the SDK from a specific branch or commit: The package provides a main class `Geti` that can be used for the following use cases: -### Connect to the Intel® Geti™ platform +### Connect to the Geti™ platform -To establish a connection between the SDK and the Intel® Geti™ platform, the `Geti` class needs to know the hostname or IP address for the server and requires authentication. +To establish a connection between the SDK and the Geti™ platform, the `Geti` class needs to know the hostname or IP address for the server and requires authentication. #### Personal Access Token (Recommended) The recommended authentication method is the 'Personal Access Token'. To obtain a token: -1. Open the Intel® Geti™ user interface in your browser +1. Open the Geti™ user interface in your browser 2. Click on the `User` menu in the top right corner 3. Select `Personal access token` from the dropdown menu 4. Follow the steps to create a token and copy the token value @@ -366,9 +366,9 @@ although some advanced features may not be available yet due to technical and se - [x] **Deploy and benchmark models locally** - Export OpenVINO inference models, run full pipeline inference on local machines, and measure inference throughput on your hardware configurations - [x] **Download and upload datasets** - Export datasets to archives and import them to create new projects - [x] **Download and upload full projects** - Create complete backups of projects, including datasets, models and configurations, and restore them -- [ ] **Upload trained models** - Intel® Geti™ does not allow to import external models -- [ ] **Import datasets to existing projects** - currently, this feature is only available through the Intel® Geti™ UI and API -- [ ] **Manage users and roles** - currently, this feature is only available through the Intel® Geti™ UI and API +- [ ] **Upload trained models** - Geti™ does not allow to import external models +- [ ] **Import datasets to existing projects** - currently, this feature is only available through the Geti™ UI and API +- [ ] **Manage users and roles** - currently, this feature is only available through the Geti™ UI and API Are you looking for a specific feature that is not listed here? Please check if it is implemented by one of the clients in the [rest_clients](geti_sdk/rest_clients) module, diff --git a/docs/source/conf.py b/docs/source/conf.py index a6d9cea34..08e0ad3b2 100644 --- a/docs/source/conf.py +++ b/docs/source/conf.py @@ -25,7 +25,7 @@ # -- Project information ----------------------------------------------------- -project = "Intel® Geti™ SDK" +project = "Geti™ SDK" copyright = "2024 Intel Corporation" # noqa: A001 author = "Ludo Cornelissen" diff --git a/docs/source/index.rst b/docs/source/index.rst index 70589bf04..f5c29e140 100644 --- a/docs/source/index.rst +++ b/docs/source/index.rst @@ -1,17 +1,17 @@ -.. Intel® Geti™ SDK documentation master file +.. Geti™ SDK documentation master file -Intel® Geti™ SDK documentation +Geti™ SDK documentation ====================================== -Welcome to the documentation for the Intel® Geti™ SDK! The purpose of this SDK is twofold: +Welcome to the documentation for the Geti™ SDK! The purpose of this SDK is twofold: -#. Provide an easy-to-use interface to the Intel® Geti™ platform, to manipulate - Intel® Geti™ projects and other entities or automate tasks on the platform. All +#. Provide an easy-to-use interface to the Geti™ platform, to manipulate + Geti™ projects and other entities or automate tasks on the platform. All of this from a Python script or Jupyter notebook. -#. Provide an API to deploy and run models trained on the Intel® Geti™ server on your local +#. Provide an API to deploy and run models trained on the Geti™ server on your local machine. The SDK :py:mod:`~geti_sdk.deployment` module provides a straightforward - route to create a deployment for your Intel® Geti™ project, save it to a local disk and run + route to create a deployment for your Geti™ project, save it to a local disk and run it offline. This SDK includes various example scripts and Jupyter notebooks which illustrate a diff --git a/geti_sdk/__init__.py b/geti_sdk/__init__.py index c46cd914f..a425ab169 100644 --- a/geti_sdk/__init__.py +++ b/geti_sdk/__init__.py @@ -20,7 +20,7 @@ :py:class:`~geti_sdk.geti.Geti`. The :py:class:`~geti_sdk.geti.Geti` class implements convenience -methods for common operations that can be performed on the Intel® Geti™ cluster, such as +methods for common operations that can be performed on the Geti™ cluster, such as creating a project from a pre-existing dataset, downloading or uploading a project, uploading an image and getting a prediction for it and creating a deployment for a project. @@ -38,20 +38,20 @@ geti.download_project_data(project_name="dummy_project") The :py:class:`~geti_sdk.geti.Geti` class provides a high-level interface for -import-export operations in Intel® Geti™ platform. Here is a list of these operations: +import-export operations in Geti™ platform. Here is a list of these operations: * Project download :py:meth:`~geti_sdk.geti.Geti.download_project_data` method fetches the project data and creates a local Python object that supports a range of operations with the project. * Project upload :py:meth:`~geti_sdk.geti.Geti.upload_project_data` method uploads the project data - from a local Python object to the Intel® Geti™ platform. + from a local Python object to the Geti™ platform. * Batched project download and upload :py:meth:`~geti_sdk.geti.Geti.download_all_projects` and :py:meth:`~geti_sdk.geti.Geti.upload_all_projects` methods download and upload multiple projects at once. * Project export :py:meth:`~geti_sdk.geti.Geti.export_project` method exports the project snapshot - to a zip archive. The archive can be used to import the project to another or the same Intel® Geti™ + to a zip archive. The archive can be used to import the project to another or the same Geti™ instance. * Project import :py:meth:`~geti_sdk.geti.Geti.import_project` method imports the project from a zip archive. diff --git a/geti_sdk/annotation_readers/__init__.py b/geti_sdk/annotation_readers/__init__.py index a8f1c89ef..2b91f6281 100644 --- a/geti_sdk/annotation_readers/__init__.py +++ b/geti_sdk/annotation_readers/__init__.py @@ -21,7 +21,7 @@ base class, which provides an interface for implementing custom annotation readers. Annotation readers server to load annotation files in custom formats and convert them -to Intel® Geti™ format, such that they can be uploaded to an Intel® Geti™ project. +to Geti™ format, such that they can be uploaded to an Geti™ project. Module contents --------------- diff --git a/geti_sdk/annotation_readers/base_annotation_reader.py b/geti_sdk/annotation_readers/base_annotation_reader.py index 12e39fd77..9552f7c7a 100644 --- a/geti_sdk/annotation_readers/base_annotation_reader.py +++ b/geti_sdk/annotation_readers/base_annotation_reader.py @@ -24,7 +24,7 @@ class AnnotationReader: """ Base class for annotation reading, to handle loading and converting annotations - to Intel Geti format + to Geti format """ def __init__( diff --git a/geti_sdk/annotation_readers/directory_tree_annotation_reader.py b/geti_sdk/annotation_readers/directory_tree_annotation_reader.py index 4d9821651..32b8b1d03 100644 --- a/geti_sdk/annotation_readers/directory_tree_annotation_reader.py +++ b/geti_sdk/annotation_readers/directory_tree_annotation_reader.py @@ -36,7 +36,7 @@ class DirectoryTreeAnnotationReader(AnnotationReader): that should not be considered as labels, but should be used to acquire the data. For example ['train', 'validation', 'test'] for a dataset that is split into three subsets. - :param task_type: TaskType for the task in the Intel® Geti™ platform to which the + :param task_type: TaskType for the task in the Geti™ platform to which the annotations should be uploaded """ diff --git a/geti_sdk/annotation_readers/geti_annotation_reader.py b/geti_sdk/annotation_readers/geti_annotation_reader.py index 3eeeb5961..cc7a4b8a6 100644 --- a/geti_sdk/annotation_readers/geti_annotation_reader.py +++ b/geti_sdk/annotation_readers/geti_annotation_reader.py @@ -33,7 +33,7 @@ class GetiAnnotationReader(AnnotationReader): """ - AnnotationReader for loading annotation files in Intel® Geti™ format. + AnnotationReader for loading annotation files in Geti™ format. """ def __init__( @@ -53,7 +53,7 @@ def __init__( when reading annotation data. This can be used to filter the annotations for certain labels. :param anomaly_reduction: True to reduce all anomaly tasks to the single anomaly task. - This is done in accordance with the Intel Geti 2.5 Anomaly Reduction effort. + This is done in accordance with the Geti 2.5 Anomaly Reduction effort. All pixel level annotations are converted to full rectangles. All anomaly tasks are mapped to th new "Anomaly Detection" task wich corresponds to the old "Anomaly Classification". """ @@ -123,7 +123,7 @@ def get_data( (e.g. width, height) about the media item to upload the annotation for :param preserve_shape_for_global_labels: False to convert shapes for global tasks to full rectangles (required for classification like tasks in - Intel® Geti™ projects), True to preserve such shapes. This parameter + Geti™ projects), True to preserve such shapes. This parameter should be: - False when uploading annotations to a single task project @@ -154,8 +154,8 @@ def get_data( annotation_object.pop_label_by_name(label_name=label_dict["name"]) new_annotations.append(annotation_object) if self.anomaly_reduction and annotation_object.labels[0].name.lower() == "anomalous": - # Part of anomaly task reduction in Intel Geti 2.5 -> all anomaly tasks combined into one. - # Intel Geti now only accepts full rectangles for anomaly tasks. + # Part of anomaly task reduction in Geti 2.5 -> all anomaly tasks combined into one. + # Geti now only accepts full rectangles for anomaly tasks. new_annotations = [ Annotation( labels=[annotation_object.labels[0]], @@ -228,8 +228,8 @@ def _has_normalized_annotations(self) -> bool: logging.info( "Legacy annotation format detected. The annotations you are trying to " "upload were most likely downloaded from a pre-production version of " - "the Intel Geti software. They will be converted to the latest " - "annotation format upon upload to the Intel Geti platform. " + "the Geti software. They will be converted to the latest " + "annotation format upon upload to the Geti platform. " ) return True raise ValueError( diff --git a/geti_sdk/benchmarking/__init__.py b/geti_sdk/benchmarking/__init__.py index 8ff945a74..209538ba6 100644 --- a/geti_sdk/benchmarking/__init__.py +++ b/geti_sdk/benchmarking/__init__.py @@ -18,7 +18,7 @@ The `benchmarking` package contains the :py:class:`~geti_sdk.benchmarking.benchmarker.Benchmarker` class, which provides -methods for benchmarking models that are trained and deployed with Intel® Geti™. +methods for benchmarking models that are trained and deployed with Geti™. For example, benchmarking local inference rates for your project can help in selecting the model architecture to use for your project, or in assessing the performance of the diff --git a/geti_sdk/benchmarking/benchmarker.py b/geti_sdk/benchmarking/benchmarker.py index 7b4f69c38..ec41fba4f 100644 --- a/geti_sdk/benchmarking/benchmarker.py +++ b/geti_sdk/benchmarking/benchmarker.py @@ -67,7 +67,7 @@ def __init__( framerates for different model architectures and precision levels for the specified project. - The Benchmarker will fetch models from Intel Geti and measure the + The Benchmarker will fetch models from Geti and measure the throughput for local inference for these models. It requires an existing Geti Project to work. The project does not need to be trained yet, but must have sufficient annotations to be able to start training. @@ -112,7 +112,7 @@ def __init__( self.geti = geti # Update project object to get the latest project details self.project = self.geti.get_project(project_id=project.id) - logging.info(f"Setting up Benchmarker for Intel® Geti™ project `{self.project.name}`.") + logging.info(f"Setting up Benchmarker for Geti™ project `{self.project.name}`.") self._is_single_task = len(self.project.get_trainable_tasks()) == 1 if precision_levels is None: precision_levels = ["FP32", "FP16"] diff --git a/geti_sdk/data_models/algorithms.py b/geti_sdk/data_models/algorithms.py index 91447fcb9..f7c5dab5d 100644 --- a/geti_sdk/data_models/algorithms.py +++ b/geti_sdk/data_models/algorithms.py @@ -28,7 +28,7 @@ @attr.define class LegacyAlgorithm: """ - Representation of a supported algorithm on the Intel® Geti™ platform. + Representation of a supported algorithm on the Geti™ platform. """ model_size: str diff --git a/geti_sdk/data_models/annotations.py b/geti_sdk/data_models/annotations.py index 1f6c574e9..e55d635f7 100644 --- a/geti_sdk/data_models/annotations.py +++ b/geti_sdk/data_models/annotations.py @@ -31,7 +31,7 @@ @attr.define class Annotation: """ - Representation of a single annotation for a media item on the Intel® Geti™ platform. + Representation of a single annotation for a media item on the Geti™ platform. :var labels: List of labels belonging to the annotation :var modified: Date and time of the last modification made to this annotation diff --git a/geti_sdk/data_models/code_deployment_info.py b/geti_sdk/data_models/code_deployment_info.py index 0a7693995..5da31d806 100644 --- a/geti_sdk/data_models/code_deployment_info.py +++ b/geti_sdk/data_models/code_deployment_info.py @@ -54,7 +54,7 @@ def from_model(cls, model: BaseModel) -> "DeploymentModelIdentifier": @attr.define() class CodeDeploymentInformation: """ - Class containing information pertaining to the deployment of an Intel® Geti™ + Class containing information pertaining to the deployment of an Geti™ project. :var id: Unique ID of the code deployment diff --git a/geti_sdk/data_models/configuration_identifiers.py b/geti_sdk/data_models/configuration_identifiers.py index b48548e5d..a1677d5a8 100644 --- a/geti_sdk/data_models/configuration_identifiers.py +++ b/geti_sdk/data_models/configuration_identifiers.py @@ -24,7 +24,7 @@ @attr.define class EntityIdentifier: """ - Identifying information for a configurable entity on the Intel® Geti™ platform, + Identifying information for a configurable entity on the Geti™ platform, as returned by the /configuration endpoint. :var workspace_id: ID of the workspace to which the entity belongs @@ -48,7 +48,7 @@ def to_dict(self) -> dict[str, Any]: @attr.define class HyperParameterGroupIdentifier(EntityIdentifier): """ - Identifying information for a HyperParameterGroup on the Intel® Geti™ platform, + Identifying information for a HyperParameterGroup on the Geti™ platform, as returned by the /configuration endpoint. :var model_storage_id: ID of the model storage to which the hyper parameter group @@ -79,7 +79,7 @@ def resolve_algorithm(self, algorithm: Algorithm): @attr.define class ComponentEntityIdentifier(EntityIdentifier): """ - Identifying information for a configurable Component on the Intel® Geti™ platform, + Identifying information for a configurable Component on the Geti™ platform, as returned by the /configuration endpoint. :var component: Name of the component diff --git a/geti_sdk/data_models/containers/algorithm_list.py b/geti_sdk/data_models/containers/algorithm_list.py index 96b0f5107..393c59d6a 100644 --- a/geti_sdk/data_models/containers/algorithm_list.py +++ b/geti_sdk/data_models/containers/algorithm_list.py @@ -36,7 +36,7 @@ class AlgorithmList(UserList): """ - A list containing the algorithms supported in Intel® Geti™. + A list containing the algorithms supported in Geti™. """ def __init__(self, data: Sequence[Algorithm] | None = None): @@ -48,11 +48,11 @@ def __init__(self, data: Sequence[Algorithm] | None = None): def from_rest(rest_input: dict[str, Any], geti_version: GetiVersion) -> "AlgorithmList": """ Create an AlgorithmList from the response of the /supported_algorithms REST - endpoint in Intel® Geti™. + endpoint in Geti™. :param rest_input: Dictionary retrieved from the /supported_algorithms REST endpoint - :param geti_version: Version of Intel® Geti™ platform - :return: AlgorithmList holding the information related to the supported algorithms in Intel® Geti™ + :param geti_version: Version of Geti™ platform + :return: AlgorithmList holding the information related to the supported algorithms in Geti™ """ algorithm_list = AlgorithmList([]) if "items" in rest_input: diff --git a/geti_sdk/data_models/containers/label_list.py b/geti_sdk/data_models/containers/label_list.py index e8f188345..2819750c6 100644 --- a/geti_sdk/data_models/containers/label_list.py +++ b/geti_sdk/data_models/containers/label_list.py @@ -23,7 +23,7 @@ class LabelList(UserList): """ - A list containing labels for an Intel® Geti™ inference model. + A list containing labels for an Geti™ inference model. """ def __init__(self, data: Sequence[Label] | None = None): diff --git a/geti_sdk/data_models/containers/media_list.py b/geti_sdk/data_models/containers/media_list.py index 5595f4009..da2eb851a 100644 --- a/geti_sdk/data_models/containers/media_list.py +++ b/geti_sdk/data_models/containers/media_list.py @@ -26,7 +26,7 @@ class MediaList(UserList, Generic[MediaTypeVar]): """ - A list containing Intel® Geti™ media entities + A list containing Geti™ media entities """ @property @@ -74,9 +74,9 @@ def media_type(self) -> type[MediaTypeVar]: def from_rest_list(rest_input: list[dict[str, Any]], media_type: type[MediaTypeVar]) -> MediaList[MediaTypeVar]: """ Create a MediaList instance from a list of media entities obtained from the - Intel® Geti™ /media endpoints. + Geti™ /media endpoints. - :param rest_input: List of dictionaries representing media entities in Intel® Geti™ + :param rest_input: List of dictionaries representing media entities in Geti™ :param media_type: Image or Video, type of the media entities that are to be converted. diff --git a/geti_sdk/data_models/credit_system.py b/geti_sdk/data_models/credit_system.py index 7b7a79851..a4ad1621e 100644 --- a/geti_sdk/data_models/credit_system.py +++ b/geti_sdk/data_models/credit_system.py @@ -34,7 +34,7 @@ @attr.define class CreditBalance: """ - Representation of the Credit Balance in Intel Geti + Representation of the Credit Balance in Geti """ incoming: int @@ -45,7 +45,7 @@ class CreditBalance: @attr.define class CreditAccount: """ - Representation of the Credit Account in Intel Geti + Representation of the Credit Account in Geti """ _identifier_fields = [ @@ -96,7 +96,7 @@ def deidentify(self) -> None: @attr.define class Subscription: """ - Representation of the Subscription in Intel Geti + Representation of the Subscription in Geti """ _identifier_fields = [ diff --git a/geti_sdk/data_models/dataset.py b/geti_sdk/data_models/dataset.py index a34dd4ffd..abd9002fa 100644 --- a/geti_sdk/data_models/dataset.py +++ b/geti_sdk/data_models/dataset.py @@ -28,7 +28,7 @@ @attr.define class Dataset: """ - Representation of a dataset for a project in Intel® Geti™. + Representation of a dataset for a project in Geti™. :var id: Unique database ID of the dataset :var name: name of the dataset diff --git a/geti_sdk/data_models/enums/annotation_kind.py b/geti_sdk/data_models/enums/annotation_kind.py index c64d1d798..7cf65f252 100644 --- a/geti_sdk/data_models/enums/annotation_kind.py +++ b/geti_sdk/data_models/enums/annotation_kind.py @@ -17,7 +17,7 @@ class AnnotationKind(Enum): """ - Enum representing the different kind of annotation scenes on the Intel® Geti™ + Enum representing the different kind of annotation scenes on the Geti™ platform. """ diff --git a/geti_sdk/data_models/enums/annotation_state.py b/geti_sdk/data_models/enums/annotation_state.py index c53a4e123..1ff8dfcbe 100644 --- a/geti_sdk/data_models/enums/annotation_state.py +++ b/geti_sdk/data_models/enums/annotation_state.py @@ -18,7 +18,7 @@ class AnnotationState(Enum): """ Enum representing the different annotation statuses for media items within an - Intel® Geti™ project. + Geti™ project. """ TO_REVISIT = "to_revisit" diff --git a/geti_sdk/data_models/enums/configuration_enums.py b/geti_sdk/data_models/enums/configuration_enums.py index 024121828..1c53b9d0f 100644 --- a/geti_sdk/data_models/enums/configuration_enums.py +++ b/geti_sdk/data_models/enums/configuration_enums.py @@ -17,7 +17,7 @@ class ConfigurationEntityType(Enum): """ - Enum representing the different configuration types on the Intel® Geti™ platform. + Enum representing the different configuration types on the Geti™ platform. """ HYPER_PARAMETER_GROUP = "HYPER_PARAMETER_GROUP" @@ -33,7 +33,7 @@ def __str__(self): class ParameterDataType(Enum): """ Enum representing the different data types for configurable parameters on the - Intel® Geti™ platform. + Geti™ platform. """ BOOLEAN = "boolean" @@ -51,7 +51,7 @@ def __str__(self): class ParameterInputType(Enum): """ Enum representing the different input types for configurable parameters on the - Intel® Geti™ platform. + Geti™ platform. """ INPUT = "input" @@ -67,7 +67,7 @@ def __str__(self): class ConfigurableParameterType(Enum): """ Enum representing the different types of configurable parameters on the - Intel® Geti™ platform. + Geti™ platform. """ CONFIGURABLE_PARAMETERS = "CONFIGURABLE_PARAMETERS" diff --git a/geti_sdk/data_models/enums/dataset_format.py b/geti_sdk/data_models/enums/dataset_format.py index 9f4d13857..d53148c5e 100644 --- a/geti_sdk/data_models/enums/dataset_format.py +++ b/geti_sdk/data_models/enums/dataset_format.py @@ -18,7 +18,7 @@ class DatasetFormat(Enum): """ Enum representing the different annotation formats for datasets within an - Intel® Geti™ platform. + Geti™ platform. """ COCO = "coco" diff --git a/geti_sdk/data_models/enums/deployment_state.py b/geti_sdk/data_models/enums/deployment_state.py index d57e0b784..67c71fc97 100644 --- a/geti_sdk/data_models/enums/deployment_state.py +++ b/geti_sdk/data_models/enums/deployment_state.py @@ -16,7 +16,7 @@ class DeploymentState(Enum): """ - Enum representing the status of a deployment creation process for an Intel® Geti™ + Enum representing the status of a deployment creation process for an Geti™ project. """ diff --git a/geti_sdk/data_models/enums/domain.py b/geti_sdk/data_models/enums/domain.py index 631b90216..c06e00e5c 100644 --- a/geti_sdk/data_models/enums/domain.py +++ b/geti_sdk/data_models/enums/domain.py @@ -19,7 +19,7 @@ class Domain(Enum): """ - Enum representing the different task domains in Intel® Geti™ projects. + Enum representing the different task domains in Geti™ projects. """ DETECTION = "DETECTION" diff --git a/geti_sdk/data_models/enums/job_state.py b/geti_sdk/data_models/enums/job_state.py index c086d3c3b..9ad09c9aa 100644 --- a/geti_sdk/data_models/enums/job_state.py +++ b/geti_sdk/data_models/enums/job_state.py @@ -17,7 +17,7 @@ class JobState(Enum): """ - Enum representing the state of a job on the Intel® Geti™ server. + Enum representing the state of a job on the Geti™ server. """ IDLE = "idle" diff --git a/geti_sdk/data_models/enums/job_type.py b/geti_sdk/data_models/enums/job_type.py index 99c45e61c..736f7e31f 100644 --- a/geti_sdk/data_models/enums/job_type.py +++ b/geti_sdk/data_models/enums/job_type.py @@ -17,7 +17,7 @@ class JobType(Enum): """ - Enum representing the type of a job on the Intel® Geti™ cluster. + Enum representing the type of a job on the Geti™ cluster. """ UNDEFINED = "undefined" diff --git a/geti_sdk/data_models/enums/optimization_type.py b/geti_sdk/data_models/enums/optimization_type.py index f407f23a6..f7fc45447 100644 --- a/geti_sdk/data_models/enums/optimization_type.py +++ b/geti_sdk/data_models/enums/optimization_type.py @@ -17,7 +17,7 @@ class OptimizationType(Enum): """ - Enum representing the optimization type for an OptimizedModel in Intel® Geti™. + Enum representing the optimization type for an OptimizedModel in Geti™. """ NNCF = "NNCF" diff --git a/geti_sdk/data_models/enums/prediction_mode.py b/geti_sdk/data_models/enums/prediction_mode.py index 8bbb393c2..39d039940 100644 --- a/geti_sdk/data_models/enums/prediction_mode.py +++ b/geti_sdk/data_models/enums/prediction_mode.py @@ -17,7 +17,7 @@ class PredictionMode(Enum): """ - Enum representing the mode used to generate predictions on the Intel® Geti™ + Enum representing the mode used to generate predictions on the Geti™ platform. """ diff --git a/geti_sdk/data_models/enums/shape_type.py b/geti_sdk/data_models/enums/shape_type.py index a429a64c0..e4c7c1b44 100644 --- a/geti_sdk/data_models/enums/shape_type.py +++ b/geti_sdk/data_models/enums/shape_type.py @@ -17,7 +17,7 @@ class ShapeType(Enum): """ - Enum representing the types of shapes available for annotations on the Intel® Geti™ + Enum representing the types of shapes available for annotations on the Geti™ platform. """ diff --git a/geti_sdk/data_models/enums/subscription_status.py b/geti_sdk/data_models/enums/subscription_status.py index 8c6870af3..4663aa1e9 100644 --- a/geti_sdk/data_models/enums/subscription_status.py +++ b/geti_sdk/data_models/enums/subscription_status.py @@ -17,7 +17,7 @@ class SubscriptionStatus(Enum): """ - Enum representing the status of a subscription on the Intel® Geti™ platform. + Enum representing the status of a subscription on the Geti™ platform. """ ACTIVE = "ACTIVE" diff --git a/geti_sdk/data_models/enums/subset_purpose.py b/geti_sdk/data_models/enums/subset_purpose.py index 4a1c80fb6..cbaa2b501 100644 --- a/geti_sdk/data_models/enums/subset_purpose.py +++ b/geti_sdk/data_models/enums/subset_purpose.py @@ -17,7 +17,7 @@ class SubsetPurpose(Enum): """ - Enum representing the purpose of a subset of a dataset on the Intel® Geti™ platform. + Enum representing the purpose of a subset of a dataset on the Geti™ platform. """ TRAINING = "training" diff --git a/geti_sdk/data_models/enums/task_type.py b/geti_sdk/data_models/enums/task_type.py index bcf78f215..afc071edd 100644 --- a/geti_sdk/data_models/enums/task_type.py +++ b/geti_sdk/data_models/enums/task_type.py @@ -17,7 +17,7 @@ class TaskType(Enum): """ - Enum representing the different task types in Intel® Geti™ projects. + Enum representing the different task types in Geti™ projects. """ DETECTION = "detection" diff --git a/geti_sdk/data_models/job.py b/geti_sdk/data_models/job.py index 2bf5abfe6..086482b3e 100644 --- a/geti_sdk/data_models/job.py +++ b/geti_sdk/data_models/job.py @@ -33,7 +33,7 @@ @attr.define(slots=False) class JobStatus(StatusSummary): """ - Current status of a job on the Intel® Geti™ server. + Current status of a job on the Geti™ server. :var state: Current state of the job """ @@ -46,7 +46,7 @@ def from_dict(cls, status_dict: dict[str, Any]) -> "JobStatus": Create a JobStatus object from a dictionary. :param status_dict: Dictionary representing a status, as returned by the - Intel® Geti™ /status and /jobs endpoints + Geti™ /status and /jobs endpoints :return: JobStatus object holding the status data contained in `status_dict` """ return cls(**status_dict) @@ -55,7 +55,7 @@ def from_dict(cls, status_dict: dict[str, Any]) -> "JobStatus": @attr.define class TaskMetadata: """ - Metadata related to a task on the Intel® Geti™ cluster. + Metadata related to a task on the Geti™ cluster. :var name: Name of the task :var model_template_id: Identifier of the model template used by the task @@ -200,7 +200,7 @@ class JobMetadata: @attr.define class JobCancellationInfo: """ - Information relating to the cancellation of a Job in Intel Geti + Information relating to the cancellation of a Job in Geti :var is_cancelled: True if the job is cancelled, False otherwise :var user_uid: Unique ID of the User who cancelled the Job @@ -216,7 +216,7 @@ class JobCancellationInfo: @attr.define class JobCost: """ - Information relating to the cost of a Job in Intel Geti. + Information relating to the cost of a Job in Geti. """ requests: list @@ -443,9 +443,9 @@ def current_step_progress(self) -> float: @property def geti_version(self) -> GetiVersion: """ - Return the version of the Intel Geti instance from which the job originates. + Return the version of the Geti instance from which the job originates. - :return: Version of the Intel Geti instance from which the job originates + :return: Version of the Geti instance from which the job originates """ if self._geti_version is None: raise ValueError(f"Geti version for job {self} is unknown, it was never set.") @@ -454,8 +454,8 @@ def geti_version(self) -> GetiVersion: @geti_version.setter def geti_version(self, geti_version: GetiVersion): """ - Set the version of the Intel Geti instance for the job. + Set the version of the Geti instance for the job. - :param geti_version: Version of the Intel Geti instance from which the job originates + :param geti_version: Version of the Geti instance from which the job originates """ self._geti_version = geti_version diff --git a/geti_sdk/data_models/media.py b/geti_sdk/data_models/media.py index af387d83a..d4f4a6456 100644 --- a/geti_sdk/data_models/media.py +++ b/geti_sdk/data_models/media.py @@ -44,7 +44,7 @@ @attr.define class MediaInformation: """ - Basic information about a media item in Intel® Geti™. + Basic information about a media item in Geti™. :var display_url: URL that can be used to download the full size media entity :var height: Height of the media entity, in pixels @@ -62,7 +62,7 @@ class MediaInformation: @attr.define class VideoInformation(MediaInformation): """ - Basic information about a video entity in Intel® Geti™. + Basic information about a video entity in Geti™. :var duration: Duration of the video :var frame_count: Total number of frames in the video @@ -79,7 +79,7 @@ class VideoInformation(MediaInformation): @attr.define class ImageInformation(MediaInformation): """ - Basic information about an image entity in Intel® Geti™ + Basic information about an image entity in Geti™ """ pass @@ -88,7 +88,7 @@ class ImageInformation(MediaInformation): @attr.define class VideoFrameInformation(MediaInformation): """ - Basic information about a video frame in Intel® Geti™. + Basic information about a video frame in Geti™. """ frame_index: int = attr.ib(kw_only=True) @@ -98,7 +98,7 @@ class VideoFrameInformation(MediaInformation): @attr.define class MediaPreprocessing: """ - Basic information about a media preprocessing in Intel® Geti™. + Basic information about a media preprocessing in Geti™. """ status: str = attr.ib(kw_only=True) @@ -108,7 +108,7 @@ class MediaPreprocessing: @attr.define class MediaItem: """ - Representation of a media entity in Intel® Geti™. + Representation of a media entity in Geti™. :var id: Unique database ID of the media entity :var name: Filename of the media entity @@ -138,7 +138,7 @@ class MediaItem: def download_url(self) -> str: """ Return the URL that can be used to download the full size media entity from the - Intel® Geti™ server. + Geti™ server. :return: URL at which the media entity can be downloaded """ @@ -185,7 +185,7 @@ def get_data(self, session: GetiSession) -> np.ndarray | str: objects, this method will return a path-like string, pointing to the video on the local disk. - :param session: REST session to the Intel® Geti™ server on which the MediaItem + :param session: REST session to the Geti™ server on which the MediaItem lives :raises ValueError: If the cache is empty and no data can be downloaded from the cluster @@ -215,7 +215,7 @@ def overview(self) -> str: @attr.define(slots=False) class Image(MediaItem): """ - Representation of an image in Intel® Geti™. + Representation of an image in Geti™. :var media_information: Container holding basic information such as width and height about the image entity @@ -248,7 +248,7 @@ def get_data(self, session: GetiSession) -> np.ndarray: NOTE: The pixel data will be returned in BGR channel order - :param session: REST session to the Intel® Geti™ server on which the Image lives + :param session: REST session to the Geti™ server on which the Image lives :raises ValueError: If the cache is empty and no data can be downloaded from the cluster :return: Numpy.ndarray holding the pixel data for this Image. @@ -259,7 +259,7 @@ def get_data(self, session: GetiSession) -> np.ndarray: self._data = numpy_from_buffer(response.content) else: raise ValueError( - f"Unable to retrieve data for image {self}, received response {response} from Intel® Geti™ server." + f"Unable to retrieve data for image {self}, received response {response} from Geti™ server." ) return self._data @@ -278,7 +278,7 @@ def numpy(self) -> np.ndarray | None: @attr.define(slots=False) class VideoAnnotationStatistics: """ - Annotation statistics for a video in Intel® Geti™. + Annotation statistics for a video in Geti™. :var annotated: Number of frames in the video that have been fully annotated :var partially_annotated: Number of frames in the video that have been partially @@ -294,7 +294,7 @@ class VideoAnnotationStatistics: @attr.define(slots=False) class Video(MediaItem): """ - Representation of a video in Intel® Geti™. + Representation of a video in Geti™. :var media_information: Container holding basic information such as width, height and duration about the video entity @@ -323,7 +323,7 @@ def identifier(self) -> VideoIdentifier: def get_data(self, session: GetiSession) -> str: """ - Get the video data from the Intel® Geti™ server. Calling this method will + Get the video data from the Geti™ server. Calling this method will download the video data to a temporary file, and returns the path to file. :param session: GetiSession object pointing to the instance from which the video @@ -340,7 +340,7 @@ def get_data(self, session: GetiSession) -> str: self._needs_tempfile_deletion = True else: raise ValueError( - f"Unable to retrieve data for image {self}, received response {response} from Intel® Geti™ server." + f"Unable to retrieve data for image {self}, received response {response} from Geti™ server." ) return self._data @@ -397,7 +397,7 @@ def __del__(self): @attr.define(slots=False) class VideoFrame(MediaItem): """ - Representation of a video frame in Intel® Geti™. + Representation of a video frame in Geti™. :var media_information: Container holding basic information such as width and height about the VideoFrame entity @@ -474,7 +474,7 @@ def get_data(self, session: GetiSession) -> np.ndarray: is empty, it will download the data using the provided session. Otherwise it will return the cached data directly - :param session: REST session to the Intel® Geti™ server on which the + :param session: REST session to the Geti™ server on which the VideoFrame lives :raises ValueError: If the cache is empty and no data can be downloaded from the cluster @@ -486,6 +486,6 @@ def get_data(self, session: GetiSession) -> np.ndarray: self._data = numpy_from_buffer(response.content) else: raise ValueError( - f"Unable to retrieve data for image {self}, received response {response} from Intel® Geti™ server." + f"Unable to retrieve data for image {self}, received response {response} from Geti™ server." ) return self._data diff --git a/geti_sdk/data_models/media_identifiers.py b/geti_sdk/data_models/media_identifiers.py index c3468b2ae..d9f97b5f2 100644 --- a/geti_sdk/data_models/media_identifiers.py +++ b/geti_sdk/data_models/media_identifiers.py @@ -22,7 +22,7 @@ @attr.define class MediaIdentifier: """ - Representation of media identification data as output by the Intel® Geti™ + Representation of media identification data as output by the Geti™ /annotations REST endpoints. :var type: Type of the media to which the annotation belongs @@ -42,8 +42,8 @@ def to_dict(self) -> dict[str, str]: @attr.define class ImageIdentifier(MediaIdentifier): """ - Representation of image identification data used by the Intel® Geti™ /annotations - endpoints. This object uniquely identifies an Image on the Intel® Geti™ server. + Representation of image identification data used by the Geti™ /annotations + endpoints. This object uniquely identifies an Image on the Geti™ server. :var image_id: unique database ID of the image """ @@ -56,9 +56,9 @@ class ImageIdentifier(MediaIdentifier): @attr.define class VideoFrameIdentifier(MediaIdentifier): """ - Representation of video frame identification data used by the Intel® Geti™ + Representation of video frame identification data used by the Geti™ /annotations endpoints. This object uniquely identifies a VideoFrame on the - Intel® Geti™ server. + Geti™ server. :var frame_index: Index of the video frame in the full video :var video_id: unique database ID of the video to which the frame belongs @@ -75,8 +75,8 @@ class VideoFrameIdentifier(MediaIdentifier): @attr.define class VideoIdentifier(MediaIdentifier): """ - Representation of video identification data used by the Intel® Geti™ /annotations - endpoints. This object uniquely identifiers a Video on the Intel® Geti™ server. + Representation of video identification data used by the Geti™ /annotations + endpoints. This object uniquely identifiers a Video on the Geti™ server. :var video_id: unique database ID of the video """ diff --git a/geti_sdk/data_models/model.py b/geti_sdk/data_models/model.py index 510ec22b6..c2a3878fe 100644 --- a/geti_sdk/data_models/model.py +++ b/geti_sdk/data_models/model.py @@ -37,7 +37,7 @@ @attr.define class OptimizationCapabilities: """ - Representation of the various model optimization capabilities in Intel Geti. + Representation of the various model optimization capabilities in Geti. """ is_nncf_supported: bool @@ -71,7 +71,7 @@ class TrainingFramework: @attr.define class OptimizationConfigurationParameter: """ - Representation of a parameter for model optimization in Intel Geti. + Representation of a parameter for model optimization in Geti. """ name: str @@ -81,7 +81,7 @@ class OptimizationConfigurationParameter: @attr.define(slots=False) class BaseModel: """ - Representation of the basic information for a Model or OptimizedModel in Intel Geti + Representation of the basic information for a Model or OptimizedModel in Geti """ _identifier_fields: ClassVar[str] = [ @@ -103,10 +103,10 @@ class BaseModel: previous_trained_revision_id: str | None = None performance: Performance | None = None id: str | None = attr.field(default=None) - label_schema_in_sync: bool | None = attr.field(default=None) # Added in Intel Geti 1.1 - total_disk_size: int | None = None # Added in Intel Geti 2.3 - training_framework: TrainingFramework | None = None # Added in Intel Geti 2.5 - learning_approach: str | None = None # Added in Intel Geti v2.6 + label_schema_in_sync: bool | None = attr.field(default=None) # Added in Geti 1.1 + total_disk_size: int | None = None # Added in Geti 2.3 + training_framework: TrainingFramework | None = None # Added in Geti 2.5 + learning_approach: str | None = None # Added in Geti v2.6 def __attrs_post_init__(self): """ @@ -141,7 +141,7 @@ def base_url(self) -> str | None: model, etc., if available. :return: base url at which the model can be addressed. The url is defined - relative to the ip address or hostname of the Intel® Geti™ server + relative to the ip address or hostname of the Geti™ server """ if self._base_url is not None: return self._base_url @@ -207,7 +207,7 @@ def deidentify(self) -> None: @attr.define(slots=False) class OptimizedModel(BaseModel): """ - Representation of an OptimizedModel in Intel® Geti™. An optimized model is a trained model + Representation of an OptimizedModel in Geti™. An optimized model is a trained model that has been converted OpenVINO representation. This conversion may involve weight quantization, filter pruning, or other optimization techniques supported by OpenVINO. @@ -220,15 +220,15 @@ class OptimizedModel(BaseModel): version: int | None = attr.field(kw_only=True, default=None) configurations: list[OptimizationConfigurationParameter] | None = attr.field( kw_only=True, default=None - ) # Added in Intel Geti v1.4 - model_format: str | None = None # Added in Intel Geti v1.5 - has_xai_head: bool = False # Added in Intel Geti v1.5 + ) # Added in Geti v1.4 + model_format: str | None = None # Added in Geti v1.5 + has_xai_head: bool = False # Added in Geti v1.5 @attr.define(slots=False) class Model(BaseModel): """ - Representation of a trained Model in Intel® Geti™. + Representation of a trained Model in Geti™. """ architecture: str = attr.field(kw_only=True) diff --git a/geti_sdk/data_models/model_group.py b/geti_sdk/data_models/model_group.py index 6eaba0f85..36221102f 100644 --- a/geti_sdk/data_models/model_group.py +++ b/geti_sdk/data_models/model_group.py @@ -26,7 +26,7 @@ @attr.define class ModelSummary: """ - Representation of a Model on the Intel® Geti™ platform, containing only the + Representation of a Model on the Geti™ platform, containing only the minimal information about the model. :var name: Name of the model @@ -62,7 +62,7 @@ class ModelSummary: @attr.define(slots=False) class ModelGroup: """ - Representation of a ModelGroup on the Intel® Geti™ server. A model group is a + Representation of a ModelGroup on the Geti™ server. A model group is a collection of models that all share the same neural network architecture, but may have been trained with different training datasets or hyper parameters. """ @@ -142,7 +142,7 @@ def algorithm(self) -> Algorithm | None: """ Return the details for the algorithm corresponding to the ModelGroup This property will return None unless the `get_algorithm_details` method is - called to retrieve the algorithm information from the Intel® Geti™ server + called to retrieve the algorithm information from the Geti™ server :return: Algorithm details, if available """ diff --git a/geti_sdk/data_models/performance.py b/geti_sdk/data_models/performance.py index ad222e63a..d5ce64df0 100644 --- a/geti_sdk/data_models/performance.py +++ b/geti_sdk/data_models/performance.py @@ -32,7 +32,7 @@ class Score: @attr.define() class TaskPerformance: """ - Task Performance metrics in Intel® Geti™. + Task Performance metrics in Geti™. :var task_id: Unique ID of the task to which this Performance metric applies. @@ -52,7 +52,7 @@ class TaskPerformance: @attr.define() class Performance: """ - Performance metrics for a project or model in Intel® Geti™. + Performance metrics for a project or model in Geti™. :var score: Overall score of the project or model :var local_score: Accuracy of the model or project with respect to object diff --git a/geti_sdk/data_models/predictions.py b/geti_sdk/data_models/predictions.py index 1b5c4141a..c662ba972 100644 --- a/geti_sdk/data_models/predictions.py +++ b/geti_sdk/data_models/predictions.py @@ -34,7 +34,7 @@ @attr.define class ResultMedium: """ - Representation of a single result medium in Intel® Geti™. + Representation of a single result medium in Geti™. :var name: Name of the result medium option :var type: Type of the result medium represented by this object @@ -71,7 +71,7 @@ def get_data(self, session: GetiSession) -> bytes: """ Download the data belonging to this ResultMedium object. - :param session: REST session to the Intel® Geti™ server from which this ResultMedium + :param session: REST session to the Geti™ server from which this ResultMedium was generated :return: bytes object holding the data, if any is found """ @@ -82,7 +82,7 @@ def get_data(self, session: GetiSession) -> bytes: else: raise ValueError( f"Unable to retrieve data for result medium {self}, received " - f"response {response} from Intel® Geti™ server." + f"response {response} from Geti™ server." ) return self.data @@ -99,10 +99,10 @@ def friendly_name(self) -> str: @attr.define class Prediction(AnnotationScene): """ - Representation of the model predictions for a certain media entity in Intel® Geti™. + Representation of the model predictions for a certain media entity in Geti™. :var annotations: List of predictions belonging to the media entity - :var id: unique database ID of the Prediction in Intel® Geti™ + :var id: unique database ID of the Prediction in Geti™ :var kind: Kind of prediction (Annotation or Prediction) :var media_identifier: Identifier of the media entity to which this Prediction applies @@ -158,7 +158,7 @@ def get_result_media_data(self, session: GetiSession) -> list[ResultMedium]: """ Download the data for all result media belonging to this prediction. - :param session: REST session to the Intel® Geti™ server from which this Prediction + :param session: REST session to the Geti™ server from which this Prediction was generated :return: List of result media, that have their data downloaded from the cluster """ diff --git a/geti_sdk/data_models/project.py b/geti_sdk/data_models/project.py index 8f2d24996..d0d9f569c 100644 --- a/geti_sdk/data_models/project.py +++ b/geti_sdk/data_models/project.py @@ -152,7 +152,7 @@ def prepare_for_post(self) -> None: @attr.define class Project: """ - Representation of a project in Intel® Geti™. + Representation of a project in Geti™. :var id: Unique database ID of the project :var name: Name of the project diff --git a/geti_sdk/data_models/shapes.py b/geti_sdk/data_models/shapes.py index 0f725ebe2..03c81520d 100644 --- a/geti_sdk/data_models/shapes.py +++ b/geti_sdk/data_models/shapes.py @@ -24,7 +24,7 @@ from geti_sdk.data_models.utils import round_to_n_digits, str_to_shape_type # N_DIGITS_TO_ROUND_TO determines how pixel coordinates will be rounded when they are -# passed from the Intel® Geti™ REST API. The Intel® Geti™ server itself rounds some +# passed from the Geti™ REST API. The Geti™ server itself rounds some # coordinates to 4 digits, but not all. Here we round all coordinates for internal # consistency N_DIGITS_TO_ROUND_TO = 0 @@ -34,7 +34,7 @@ @attr.define(slots=False) class Shape: """ - Representation of a shape in on the Intel® Geti™ platform. + Representation of a shape in on the Geti™ platform. :var type: Type of the shape """ @@ -91,7 +91,7 @@ def area(self) -> float: @attr.define(slots=False) class Rectangle(Shape): """ - Representation of a Rectangle on the Intel® Geti™ platform, as used in the + Representation of a Rectangle on the Geti™ platform, as used in the /annotations REST endpoints. NOTE: All coordinates and dimensions are given in pixels @@ -203,7 +203,7 @@ def generate_full_box(cls, image_width: int, image_height: int) -> "Rectangle": @attr.define(slots=False) class Ellipse(Shape): """ - Representation of an Ellipse on the Intel® Geti™ platform, as used in the + Representation of an Ellipse on the Geti™ platform, as used in the /annotations REST endpoints. NOTE: All coordinates and dimensions are given in pixels @@ -303,7 +303,7 @@ def y_max(self) -> int: class Point: """ Representation of a point on a 2D coordinate system. Used to define Polygons on - the Intel® Geti™ platform. + the Geti™ platform. NOTE: All coordinates are defined in pixels @@ -326,7 +326,7 @@ def as_int_tuple(self) -> tuple[int, int]: @attr.define(slots=False) class Polygon(Shape): """ - Representation of a polygon on the Intel® Geti™ platform, as used in the + Representation of a polygon on the Geti™ platform, as used in the /annotations REST endpoints. :var points: List of Points that make up the polygon @@ -456,7 +456,7 @@ def fit_rotated_rectangle(self) -> "RotatedRectangle": @attr.define(slots=False) class RotatedRectangle(Shape): """ - Representation of a RotatedRectangle on the Intel® Geti™ platform, as used in the + Representation of a RotatedRectangle on the Geti™ platform, as used in the /annotations REST endpoints. NOTE: All coordinates and dimensions are specified in pixels @@ -696,7 +696,7 @@ def area(self) -> float: @attr.define(slots=False) class Keypoint(Shape): """ - Representation of a Keypoint on the Intel® Geti™ platform, as used in the + Representation of a Keypoint on the Geti™ platform, as used in the /annotations REST endpoints. NOTE: All coordinates and dimensions are given in pixels diff --git a/geti_sdk/data_models/task_annotation_state.py b/geti_sdk/data_models/task_annotation_state.py index 5dd16f360..e101853e4 100644 --- a/geti_sdk/data_models/task_annotation_state.py +++ b/geti_sdk/data_models/task_annotation_state.py @@ -22,7 +22,7 @@ class TaskAnnotationState: """ Representation of the state of an annotation for a particular task in an - Intel® Geti™ project. + Geti™ project. """ task_id: str diff --git a/geti_sdk/data_models/test_result.py b/geti_sdk/data_models/test_result.py index 89b10848b..7b7037dd9 100644 --- a/geti_sdk/data_models/test_result.py +++ b/geti_sdk/data_models/test_result.py @@ -91,7 +91,7 @@ class Score: class TestResult: """ Representation of the results of a model test job that was run for a specific - model and dataset in an Intel® Geti™ project + model and dataset in an Geti™ project """ datasets_info: list[DatasetInfo] diff --git a/geti_sdk/data_models/user.py b/geti_sdk/data_models/user.py index 76b25a6b3..6cfaaf5ee 100644 --- a/geti_sdk/data_models/user.py +++ b/geti_sdk/data_models/user.py @@ -17,7 +17,7 @@ @attr.define class User: """ - Representation of a User in the Intel Geti platform + Representation of a User in the Geti platform :var name: name of the user :var uid: Unique ID of the user diff --git a/geti_sdk/demos/__init__.py b/geti_sdk/demos/__init__.py index 3e58f7262..f39524548 100644 --- a/geti_sdk/demos/__init__.py +++ b/geti_sdk/demos/__init__.py @@ -17,7 +17,7 @@ ------------ The `demos` package contains useful functions for setting up demo projects on any -Intel® Geti™ server. +Geti™ server. Module contents --------------- diff --git a/geti_sdk/demos/demo_projects/anomaly_demos.py b/geti_sdk/demos/demo_projects/anomaly_demos.py index 808774c74..04723f59a 100644 --- a/geti_sdk/demos/demo_projects/anomaly_demos.py +++ b/geti_sdk/demos/demo_projects/anomaly_demos.py @@ -49,7 +49,7 @@ def create_anomaly_classification_demo_project( the dataset is not found in the target folder, this method will attempt to download it from the internet. :return: Project object, holding detailed information about the project that was - created on the Intel® Geti™ server. + created on the Geti™ server. """ project_client = ProjectClient(session=geti.session, workspace_id=geti.workspace_id) data_path = get_mvtec_dataset(dataset_path) @@ -106,7 +106,7 @@ def ensure_trained_anomaly_project(geti: Geti, project_name: str = "Transistor a If the project does not exist, this method will create an anomaly detection project based on the MVTec AD `transistor` dataset. - :param geti: Geti instance pointing to the Intel® Geti™ server + :param geti: Geti instance pointing to the Geti™ server :param project_name: Name of the project to look for or create :return: Project object representing the project on the server """ diff --git a/geti_sdk/demos/demo_projects/coco_demos.py b/geti_sdk/demos/demo_projects/coco_demos.py index e5b085647..e3d82bfea 100644 --- a/geti_sdk/demos/demo_projects/coco_demos.py +++ b/geti_sdk/demos/demo_projects/coco_demos.py @@ -58,7 +58,7 @@ def create_segmentation_demo_project( download it from the internet. :param project_name: Name of the project to create :return: Project object, holding detailed information about the project that was - created on the Intel® Geti™ server. + created on the Geti™ server. """ coco_path = get_coco_dataset(dataset_path) logging.info(" ------- Creating segmentation project --------------- ") @@ -111,7 +111,7 @@ def create_detection_demo_project( download it from the internet. :param project_name: Name of the project to create :return: Project object, holding detailed information about the project that was - created on the Intel® Geti™ server. + created on the Geti™ server. """ coco_path = get_coco_dataset(dataset_path) logging.info(" ------- Creating detection project --------------- ") @@ -165,7 +165,7 @@ def create_classification_demo_project( download it from the internet. :param project_name: Name of the project to create :return: Project object, holding detailed information about the project that was - created on the Intel® Geti™ server. + created on the Geti™ server. """ coco_path = get_coco_dataset(dataset_path) logging.info(" ------- Creating classification project --------------- ") @@ -222,7 +222,7 @@ def create_detection_to_segmentation_demo_project( download it from the internet. :param project_name: Name of the project to create :return: Project object, holding detailed information about the project that was - created on the Intel® Geti™ server. + created on the Geti™ server. """ coco_path = get_coco_dataset(dataset_path) logging.info(" ------- Creating detection -> segmentation project --------------- ") @@ -284,7 +284,7 @@ def create_detection_to_classification_demo_project( download it from the internet. :param project_name: Name of the project to create :return: Project object, holding detailed information about the project that was - created on the Intel® Geti™ server. + created on the Geti™ server. """ coco_path = get_coco_dataset(dataset_path) logging.info(" ------- Creating detection -> classification project --------------- ") diff --git a/geti_sdk/deployment/__init__.py b/geti_sdk/deployment/__init__.py index 5ee245773..ff8c82168 100644 --- a/geti_sdk/deployment/__init__.py +++ b/geti_sdk/deployment/__init__.py @@ -16,9 +16,9 @@ Introduction ------------ -The `deployment` package allows creating a deployment of any Intel® Geti™ project. +The `deployment` package allows creating a deployment of any Geti™ project. A project deployment can run inference on an image or video frame locally, i.e. -without any connection to the Intel® Geti™ server. +without any connection to the Geti™ server. Deployments can be created for both single task and task chain projects alike, the API is the same in both cases. diff --git a/geti_sdk/deployment/deployed_model.py b/geti_sdk/deployment/deployed_model.py index 6c245915f..f4b044f69 100644 --- a/geti_sdk/deployment/deployed_model.py +++ b/geti_sdk/deployment/deployed_model.py @@ -67,7 +67,7 @@ @attr.define class DeployedModel(OptimizedModel): """ - Representation of an Intel® Geti™ model that has been deployed for inference. It + Representation of an Geti™ model that has been deployed for inference. It can be loaded onto a device to generate predictions. """ @@ -112,7 +112,7 @@ def get_data(self, source: str | os.PathLike | GetiSession): Load the model weights from a data source. The `source` can be one of the following: - 1. The Intel® Geti™ platform (if an GetiSession instance is passed). In this + 1. The Geti™ platform (if an GetiSession instance is passed). In this case the weights will be downloaded, and extracted to a temporary directory 2. A zip file on local disk, in this case the weights will be extracted to a temporary directory diff --git a/geti_sdk/deployment/deployment.py b/geti_sdk/deployment/deployment.py index 5a9b62634..1e0543e44 100644 --- a/geti_sdk/deployment/deployment.py +++ b/geti_sdk/deployment/deployment.py @@ -41,7 +41,7 @@ @attr.define(slots=False) class Deployment: """ - Representation of a deployed Intel® Geti™ project that can be used to run + Representation of a deployed Geti™ project that can be used to run inference locally """ diff --git a/geti_sdk/deployment/resources/OVMS_README.md b/geti_sdk/deployment/resources/OVMS_README.md index 8566d8fe2..0522b05e6 100644 --- a/geti_sdk/deployment/resources/OVMS_README.md +++ b/geti_sdk/deployment/resources/OVMS_README.md @@ -1,7 +1,7 @@ # Deploying Geti models with OpenVINO Model Server (OVMS) > Note: This feature is deprecated and is not recommended for use. -This README describes how to set up an OpenVINO Model Server for any Intel® Geti™ +This README describes how to set up an OpenVINO Model Server for any Geti™ project. Please note that it is meant as an example only, and the configuration used may not be optimal for a production environment. @@ -23,7 +23,7 @@ docker pull openvino/model_server:latest ``` ## Firing up the OVMS container -Follow the steps below to run the OVMS container with your Intel® Geti™ trained +Follow the steps below to run the OVMS container with your Geti™ trained model(s): 1. In your terminal, navigate to the directory containing the deployment you want to @@ -39,7 +39,7 @@ model(s): for inference requests on port 9000. ## Running inference with Geti SDK and OVMS -The following python snippet can be used to run inference for your Intel® Geti™ project +The following python snippet can be used to run inference for your Geti™ project on the OVMS instance that you just launched: ```python from geti_sdk.deployment import Deployment diff --git a/geti_sdk/geti.py b/geti_sdk/geti.py index c02e7a524..b46a3d300 100644 --- a/geti_sdk/geti.py +++ b/geti_sdk/geti.py @@ -68,11 +68,11 @@ class Geti: """ - Interact with an Intel® Geti™ server via the REST API. + Interact with an Geti™ server via the REST API. The `Geti` class provides methods for project creation, downloading and uploading, as well as project deployment. Initializing the class will establish a - HTTP session to the Intel® Geti™ server, and requires authentication. + HTTP session to the Geti™ server, and requires authentication. NOTE: The `Geti` instance can either be initialized in the following ways: @@ -173,7 +173,7 @@ def __init__( "please update the `server_config` accordingly." ) - # Set the Intel Geti SDK version + # Set the Geti SDK version self.sdk_version = Version(sdk_version_string) # Initialize session and get workspace id self.session = GetiSession( @@ -198,36 +198,36 @@ def __init__( def _check_platform_version(self) -> None: """ - Check the version of the Intel® Geti™ server that this `Geti` instance is + Check the version of the Geti™ server that this `Geti` instance is connected to. If the version is not supported by the SDK, a warning will be issued. - :raises: ValueError if the Intel® Geti™ server version is not supported by the - Intel® Geti™ SDK. + :raises: ValueError if the Geti™ server version is not supported by the + Geti™ SDK. """ # Get the build version without a timestamp platform_version = self.session.version.version # Check if the platform version is newer than the SDK version if platform_version > self.sdk_version: warnings.warn( - f"The Intel® Geti™ server version {platform_version} is newer than " + f"The Geti™ server version {platform_version} is newer than " f"the Geti SDK version {self.sdk_version}. Some features may not be " "supported and you may encounter errors.\n" - "Please update the Intel Geti SDK to the latest version " + "Please update the Geti SDK to the latest version " "with `pip install --upgrade geti-sdk`." ) # Check if the platform version is older than the last supported version if self.session.version < GETI_116_VERSION: raise ValueError( - "The Intel® Geti™ server version is not supported by this Intel Geti SDK package. Please " - "update the Intel® Geti™ server to version 2.0 or later, or use a previous version of the SDK." + "The Geti™ server version is not supported by this Geti SDK package. Please " + "update the Geti™ server to version 2.0 or later, or use a previous version of the SDK." ) @property def projects(self) -> list[Project]: """ Return a list of projects that are currently available in the workspace on - the Intel® Geti™ server. + the Geti™ server. :return: List of projects in the workspace addressed by the current `Geti` instance @@ -251,9 +251,9 @@ def get_project( project: Project | None = None, ) -> Project: """ - Return the Intel® Geti™ project by name or ID, if any. + Return the Geti™ project by name or ID, if any. If a project object is passed, the method will return the updated object. - If no project by that name is found on the Intel® Geti™ server, + If no project by that name is found on the Geti™ server, this method will raise a KeyError. :param project_name: Name of the project to retrieve. @@ -268,7 +268,7 @@ def get_project( project = self.project_client.get_project(project_name=project_name, project_id=project_id, project=project) if project is None: raise KeyError( - f"Project '{project_name}' was not found in the current workspace on the Intel® Geti™ server." + f"Project '{project_name}' was not found in the current workspace on the Geti™ server." ) return project @@ -370,7 +370,7 @@ def upload_project_data( max_threads: int = 5, ) -> Project: """ - Upload a previously downloaded Intel® Geti™ project to the server. This method + Upload a previously downloaded Geti™ project to the server. This method expects the `target_folder` to contain the following: images @@ -413,7 +413,7 @@ def upload_project_data( def download_all_projects(self, target_folder: str, include_predictions: bool = True) -> list[Project]: """ - Download all projects in the workspace from the Intel® Geti™ server. + Download all projects in the workspace from the Geti™ server. :param target_folder: Directory on local disk to download the project data to. If not specified, this method will create a directory named 'projects' in @@ -423,7 +423,7 @@ def download_all_projects(self, target_folder: str, include_predictions: bool = If this is set to True but the project has no trained models, downloading predictions will be skipped. :return: List of Project objects, each entry corresponding to one of the - projects found on the Intel® Geti™ server + projects found on the Geti™ server """ return self.import_export_module.download_all_projects( target_folder=target_folder, include_predictions=include_predictions @@ -432,7 +432,7 @@ def download_all_projects(self, target_folder: str, include_predictions: bool = def upload_all_projects(self, target_folder: str) -> list[Project]: """ Upload all projects found in the directory `target_folder` on local disk to - the Intel® Geti™ server. + the Geti™ server. This method expects the directory `target_folder` to contain subfolders. Each subfolder should correspond to the (previously downloaded) data for one @@ -442,7 +442,7 @@ def upload_all_projects(self, target_folder: str) -> list[Project]: :param target_folder: Directory on local disk to retrieve the project data from :return: List of Project objects, each entry corresponding to one of the - projects uploaded to the Intel® Geti™ server. + projects uploaded to the Geti™ server. """ return self.import_export_module.upload_all_projects(target_folder=target_folder) @@ -457,7 +457,7 @@ def export_project( Export a project with name `project_name` to the file specified by `filepath`. The project will be saved in a .zip file format, containing all project data, with the option to include all, none or only the latest_active model, indicated by `include_models`. - and metadata required for project import to another instance of the Intel® Geti™ platform. + and metadata required for project import to another instance of the Geti™ platform. :param filepath: Path to the file to save the project to :param project_id: Id of the project to export @@ -486,7 +486,7 @@ def export_project( def import_project(self, filepath: os.PathLike, project_name: str | None = None) -> Project: """ - Import a project from the zip file specified by `filepath` to the Intel® Geti™ server. + Import a project from the zip file specified by `filepath` to the Geti™ server. The project will be created on the server with the name `project_name`, if specified, esle with the archive base name. > Note: The project zip archive should be exported from the Geti™ server of the same version. @@ -532,7 +532,7 @@ def export_dataset( def import_dataset(self, filepath: os.PathLike, project_name: str, project_type: str) -> Project: """ - Import a dataset from the zip archive specified by `filepath` to the Intel® Geti™ server. + Import a dataset from the zip archive specified by `filepath` to the Geti™ server. A new project will be created from the dataset on the server with the name `project_name`. Please set the `project_type` to determine the type of the project with one of possible values are: @@ -577,7 +577,7 @@ def create_single_task_project_from_dataset( max_threads: int = 5, ) -> Project: """ - Create a single task project named `project_name` on the Intel® Geti™ server, + Create a single task project named `project_name` on the Geti™ server, and upload data from a dataset on local disk. The type of task that will be in the project can be controlled by setting the @@ -706,7 +706,7 @@ def create_task_chain_project_from_dataset( max_threads: int = 5, ) -> Project: """ - Create a single task project named `project_name` on the Intel® Geti™ cluster, + Create a single task project named `project_name` on the Geti™ cluster, and upload data from a dataset on local disk. The type of task that will be in the project can be controlled by setting the @@ -822,14 +822,14 @@ def upload_and_predict_media_folder( ) -> bool: """ Upload a folder with media (images, videos or both) from local disk at path - `target_folder` to the project provided with the `project` argument on the Intel® Geti™ + `target_folder` to the project provided with the `project` argument on the Geti™ server. After the media upload is complete, predictions will be downloaded for all media in the folder. This method will create a 'predictions' directory in the `target_folder`, containing the prediction output in json format. If `delete_after_prediction` is set to True, all uploaded media will be - removed from the project on the Intel® Geti™ server after the predictions have + removed from the project on the Geti™ server after the predictions have been downloaded. :param project: Project object to upload the media to @@ -909,7 +909,7 @@ def upload_and_predict_image( dataset_name: str | None = None, ) -> tuple[Image, Prediction]: """ - Upload a single image to a project on the Intel® Geti™ + Upload a single image to a project on the Geti™ server, and return a prediction for it. :param project: Project object to upload the image to @@ -978,7 +978,7 @@ def upload_and_predict_video( delete_after_prediction: bool = False, ) -> tuple[Video, MediaList[VideoFrame], list[Prediction]]: """ - Upload a single video to a project on the Intel® Geti™ + Upload a single video to a project on the Geti™ server, and return a list of predictions for the frames in the video. The parameter 'frame_stride' is used to control the stride for frame @@ -1103,7 +1103,7 @@ def deploy_project( def logout(self) -> None: """ - Log out of the Intel® Geti™ platform and end the HTTP session. + Log out of the Geti™ platform and end the HTTP session. """ self.session.logout() diff --git a/geti_sdk/http_session/exception.py b/geti_sdk/http_session/exception.py index 98aad05ae..1ddf0eb21 100644 --- a/geti_sdk/http_session/exception.py +++ b/geti_sdk/http_session/exception.py @@ -17,7 +17,7 @@ class GetiRequestException(Exception): """ - Exception representing an unsuccessful http request to the Intel® Geti™ server. + Exception representing an unsuccessful http request to the Geti™ server. """ def __init__( @@ -29,7 +29,7 @@ def __init__( response_data: dict | str | list | None = None, ): """ - Raise this exception upon unsuccessful requests to the Intel® Geti™ server. + Raise this exception upon unsuccessful requests to the Geti™ server. :param method: Method that was used for the request, e.g. 'POST' or 'GET', etc. :param url: URL to which the request was made @@ -61,7 +61,7 @@ def __init__( def __str__(self) -> str: """ Return string representation of the unsuccessful http request to the - Intel® Geti™ server. + Geti™ server. """ error_str = f"{self.method} request to '{self.url}' failed with status code {self.status_code}." if self.response_error_code and self.response_message: diff --git a/geti_sdk/http_session/geti_session.py b/geti_sdk/http_session/geti_session.py index 2ab74614a..928009c66 100644 --- a/geti_sdk/http_session/geti_session.py +++ b/geti_sdk/http_session/geti_session.py @@ -50,7 +50,7 @@ class GetiSession(requests.Session): handles authentication and authorization. :param server_config: Server configuration holding the hostname (or ip address) of - the Intel® Geti™ server, as well as the details required for authentication + the Geti™ server, as well as the details required for authentication (either username and password or personal access token) """ @@ -77,7 +77,7 @@ def __init__( if not server_config.has_valid_certificate: warnings.warn( "You have disabled TLS certificate validation, HTTPS requests made to " - "the Intel® Geti™ server may be compromised. For optimal security, " + "the Geti™ server may be compromised. For optimal security, " "please enable certificate validation.", InsecureRequestWarning, ) @@ -93,7 +93,7 @@ def __init__( if self.platform_serving_mode == SAAS_MODE: raise ValueError( "Authentication via username and password is not supported for " - "Intel® Geti™ SaaS instances. Please use a personal access token." + "Geti™ SaaS instances. Please use a personal access token." ) logging.warning( "Authentication via username and password is deprecated and will be " @@ -135,9 +135,9 @@ def platform_serving_mode(self) -> str: @property def version(self) -> GetiVersion: """ - Return the version of the Intel® Geti™ platform that is running on the server. + Return the version of the Geti™ platform that is running on the server. - :return: Version object holding the Intel® Geti™ version number + :return: Version object holding the Geti™ version number """ if "build-version" in self._product_info: version_string = self._product_info.get("build-version") @@ -187,18 +187,18 @@ def authenticate_with_password(self, verbose: bool = True): login_path = self._get_initial_login_url() except requests.exceptions.SSLError as error: raise requests.exceptions.SSLError( - f"Connection to Intel® Geti™ server at '{self.config.host}' failed, " + f"Connection to Geti™ server at '{self.config.host}' failed, " f"the server address can be resolved but the SSL certificate could not " f"be verified. \n Full error description: {error.args[-1]}" ) except requests.exceptions.ConnectionError as error: if "dummy" in self.config.password or "dummy" in self.config.username: raise ValueError( - "Connection to the Intel® Geti™ server failed, please make sure to " - "update the user login information for the Intel® Geti™ instance." + "Connection to the Geti™ server failed, please make sure to " + "update the user login information for the Geti™ instance." ) from error raise ValueError( - f"Connection to the Intel® Geti™ server at host '{self.config.host}' " + f"Connection to the Geti™ server at host '{self.config.host}' " f"failed, please provide a valid cluster hostname or ip address as" f" well as valid login details." ) from error @@ -273,7 +273,7 @@ def get_rest_response( else: raise ValueError( f"Making a POST request with content of type {contenttype} is " - f"currently not supported through the Intel Geti SDK." + f"currently not supported through the Geti SDK." ) else: kw_data_arg = {} @@ -303,7 +303,7 @@ def get_rest_response( break except requests.exceptions.SSLError as error: raise requests.exceptions.SSLError( - f"Connection to Intel® Geti™ server at '{self.config.host}' failed, " + f"Connection to Geti™ server at '{self.config.host}' failed, " f"the server address can be resolved but the SSL certificate could not " f"be verified. \n Full error description: {error.args[-1]}" ) @@ -385,7 +385,7 @@ def logout(self, verbose: bool = True) -> None: def _get_product_info_and_set_api_version(self) -> dict[str, str]: """ - Return the product info as retrieved from the Intel® Geti™ server. + Return the product info as retrieved from the Geti™ server. This method will also attempt to set the API version correctly, based on the retrieved product info. @@ -396,7 +396,7 @@ def _get_product_info_and_set_api_version(self) -> dict[str, str]: def __exit__(self, exc_type, exc_value, traceback): """ - Log out of the Intel® Geti™ server. This method is called when exiting the + Log out of the Geti™ server. This method is called when exiting the runtime context related to the session, in case the session is used as a context manager. """ @@ -409,7 +409,7 @@ def __exit__(self, exc_type, exc_value, traceback): def __del__(self): """ - Log out of the Intel® Geti™ server. This method is called when the session is + Log out of the Geti™ server. This method is called when the session is deleted from memory. """ if self.logged_in: @@ -515,7 +515,7 @@ def _update_headers_for_content_type(self, content_type: str) -> None: @property def base_url(self) -> str: """ - Return the base URL to the Intel Geti server. If the server is running + Return the base URL to the Geti server. If the server is running Geti v1.9 or later, the organization ID will be included in the URL """ return f"{self.config.base_url}organizations/{self.organization_id}/" @@ -559,7 +559,7 @@ def _get_organization_id(self) -> str: if org_id is None: raise ValueError( - f"Unable to retrieve organization ID from the Intel Geti server. Server responded with: `{result}`" + f"Unable to retrieve organization ID from the Geti server. Server responded with: `{result}`" ) return org_id @@ -605,11 +605,11 @@ def _handle_dex_response(self, response: Response) -> None: ) elif response.status_code == 404: raise ValueError( - "Unable to authenticate with the Intel Geti server. The authentication " + "Unable to authenticate with the Geti server. The authentication " "mechanism you are trying to use is no longer supported. This error " - "indicates that the Intel® Geti™ server version is not supported by " - "this version of the Intel Geti SDK package. Please update the " - "Intel® Geti™ server to version 2.0 or later, or use a previous " + "indicates that the Geti™ server version is not supported by " + "this version of the Geti SDK package. Please update the " + "Geti™ server to version 2.0 or later, or use a previous " "version of the SDK." ) else: diff --git a/geti_sdk/http_session/server_config.py b/geti_sdk/http_session/server_config.py index 042bac21e..efa10dba7 100644 --- a/geti_sdk/http_session/server_config.py +++ b/geti_sdk/http_session/server_config.py @@ -32,10 +32,10 @@ def trim_trailing_slash(input_string: str) -> str: @attrs.define(slots=False) class ServerConfig: """ - Base configuration holding the connection details of the Intel® Geti™ server. + Base configuration holding the connection details of the Geti™ server. Contains the hostname, ssl certificate configuration and proxy configuration. - :var host: full hostname or ip address of the Intel® Geti™ server. + :var host: full hostname or ip address of the Geti™ server. Note: this should include the protocol (i.e. https://your_geti_hostname.com) :var has_valid_certificate: Set to True if the server has a valid SSL certificate that should be validated and used to establish an encrypted HTTPS connection @@ -104,7 +104,7 @@ def api_pattern(self) -> str: @attrs.define(slots=False) class ServerCredentialConfig(ServerConfig): """ - Configuration for an Intel® Geti™ server that requires authentication via username + Configuration for an Geti™ server that requires authentication via username and password. NOTE: This is a legacy authentication method. Recent server versions should @@ -121,7 +121,7 @@ class ServerCredentialConfig(ServerConfig): @attrs.define(slots=False) class ServerTokenConfig(ServerConfig): """ - Configuration for an Intel® Geti™ server that uses a personal access token + Configuration for an Geti™ server that uses a personal access token (API key) for authentication. :var token: Personal access token that can be used to connect to the server. @@ -133,7 +133,7 @@ class ServerTokenConfig(ServerConfig): @attrs.define(slots=False) class SaaSTokenConfig(ServerTokenConfig): """ - Configuration for the Intel® Geti™ SaaS environment that uses a personal access token + Configuration for the Geti™ SaaS environment that uses a personal access token (API key) for authentication. :var token: Personal access token that can be used to connect to the server. diff --git a/geti_sdk/import_export/__init__.py b/geti_sdk/import_export/__init__.py index d5c6047d3..ba4994d2c 100644 --- a/geti_sdk/import_export/__init__.py +++ b/geti_sdk/import_export/__init__.py @@ -17,7 +17,7 @@ ------------ The `import-export` package contains the `GetiIE` class with number of methods for importing and -exporting projets and datasets to and from the Intel® Geti™ platform. +exporting projets and datasets to and from the Geti™ platform. Module contents --------------- diff --git a/geti_sdk/import_export/import_export_module.py b/geti_sdk/import_export/import_export_module.py index 9be0996a9..bc203de26 100644 --- a/geti_sdk/import_export/import_export_module.py +++ b/geti_sdk/import_export/import_export_module.py @@ -30,7 +30,7 @@ class GetiIE: """ - Class to handle importing and exporting projects and datasets to and from the Intel® Geti™ platform. + Class to handle importing and exporting projects and datasets to and from the Geti™ platform. """ def __init__(self, workspace_id: str, session: GetiSession, project_client: ProjectClient) -> None: @@ -248,7 +248,7 @@ def download_all_projects( os.makedirs(target_folder, exist_ok=True, mode=0o770) logging.info( f"Found {len(projects)} projects in the designated workspace on the " - f"Intel® Geti™ server. Commencing project download..." + f"Geti™ server. Commencing project download..." ) # Download all found projects diff --git a/geti_sdk/platform_versions.py b/geti_sdk/platform_versions.py index 24d9beb6a..ab38cc13f 100644 --- a/geti_sdk/platform_versions.py +++ b/geti_sdk/platform_versions.py @@ -18,7 +18,7 @@ class GetiVersion: """ - Version identifier of the Intel Geti platform + Version identifier of the Geti platform """ _GETI10_TIMETAG = "20220910154208" @@ -78,7 +78,7 @@ def __ge__(self, other): :param other: GetiVersion object to compare with :raises: TypeError if `other` is not a GetiVersion instance :return: True if this instance corresponds to a later or equivalent version of - the Intel Geti platform than `other` + the Geti platform than `other` """ return (self > other) or (self == other) @@ -90,7 +90,7 @@ def __le__(self, other): :param other: GetiVersion object to compare with :raises: TypeError if `other` is not a GetiVersion instance :return: True if this instance corresponds to an earlier or equivalent version - of the Intel Geti platform than `other` + of the Geti platform than `other` """ return (self < other) or (self == other) @@ -108,7 +108,7 @@ def __eq__(self, other): def __str__(self) -> str: """ - Return the Intel Geti version as a string + Return the Geti version as a string :return: String containing the version """ @@ -116,7 +116,7 @@ def __str__(self) -> str: def __repr__(self) -> str: """ - Return the string representation of the Intel Geti version + Return the string representation of the Geti version :return: String representing the version """ diff --git a/geti_sdk/post_inference_hooks/actions/geti_data_collection.py b/geti_sdk/post_inference_hooks/actions/geti_data_collection.py index a829dd7b4..810b6edf7 100644 --- a/geti_sdk/post_inference_hooks/actions/geti_data_collection.py +++ b/geti_sdk/post_inference_hooks/actions/geti_data_collection.py @@ -37,9 +37,9 @@ class GetiDataCollection(PostInferenceAction): """ Post inference action that will send an image to a specified `project` and `dataset` - on the Intel® Geti™ server addressed by `session`. + on the Geti™ server addressed by `session`. - :param session: Geti session representing the connecting to the Intel® Geti™ server + :param session: Geti session representing the connecting to the Geti™ server :param workspace_id: unique ID of the workspace in which the project to collect the data resides. :param project: Project or name of the project to whicht the image data should be @@ -67,8 +67,8 @@ def __init__( project = project_client.get_project_by_name(project_name=project_name) if project is None: raise ValueError( - f"Project `{project_name}` does not exist on the Intel® Geti™ " - f"server, unable to initialize the Intel® Geti™ data collection " + f"Project `{project_name}` does not exist on the Geti™ " + f"server, unable to initialize the Geti™ data collection " f"action" ) dataset_client = DatasetClient(session=session, workspace_id=workspace_id, project=project) @@ -103,7 +103,7 @@ def __call__( timestamp: datetime | None = None, ): """ - Execute the action, upload the given `image` to the Intel® Geti™ server. + Execute the action, upload the given `image` to the Geti™ server. The parameters `prediction`, `score`, `name` and `timestamp` are not used in this specific action. @@ -154,7 +154,7 @@ def to_dict(self) -> dict[str, Any]: """ warnings.warn( "GetiDataCollection post inference action contains sensitive information " - "used for authentication on the Intel® Geti™ platform. Be careful when " + "used for authentication on the Geti™ platform. Be careful when " "saving this information to disk or sharing with others!" ) return super().to_dict() diff --git a/geti_sdk/prediction_visualization/__init__.py b/geti_sdk/prediction_visualization/__init__.py index 175c2e562..019eddada 100644 --- a/geti_sdk/prediction_visualization/__init__.py +++ b/geti_sdk/prediction_visualization/__init__.py @@ -33,7 +33,7 @@ show_count=False, ) - # Obtain a prediction from the Intel Geti platfor server or a local deployment. + # Obtain a prediction from the Geti platfor server or a local deployment. ... # Visualize the prediction on the input image. diff --git a/geti_sdk/rest_clients/__init__.py b/geti_sdk/rest_clients/__init__.py index 60b3a3157..ec1c2ce85 100644 --- a/geti_sdk/rest_clients/__init__.py +++ b/geti_sdk/rest_clients/__init__.py @@ -20,7 +20,7 @@ such as :py:class:`~geti_sdk.data_models.project.Project`, :py:class:`~geti_sdk.data_models.media.Image` and :py:class:`~geti_sdk.data_models.model.Model`) -on the Intel® Geti™ server. +on the Geti™ server. The rest clients are initialized with a :py:class:`~geti_sdk.http_session.geti_session.GetiSession` and a workspace id. The diff --git a/geti_sdk/rest_clients/active_learning_client.py b/geti_sdk/rest_clients/active_learning_client.py index c6308af04..0dd803dec 100644 --- a/geti_sdk/rest_clients/active_learning_client.py +++ b/geti_sdk/rest_clients/active_learning_client.py @@ -19,7 +19,7 @@ class ActiveLearningClient: """ - Class to manage the active learning for a certain Intel® Geti™ project. + Class to manage the active learning for a certain Geti™ project. """ def __init__(self, workspace_id: str, project: Project, session: GetiSession): diff --git a/geti_sdk/rest_clients/annotation_clients/annotation_client.py b/geti_sdk/rest_clients/annotation_clients/annotation_client.py index f2dcfe3e2..ced023a3b 100644 --- a/geti_sdk/rest_clients/annotation_clients/annotation_client.py +++ b/geti_sdk/rest_clients/annotation_clients/annotation_client.py @@ -306,7 +306,7 @@ def upload_annotations_for_all_media(self, append_annotations: bool = False, max def upload_annotation(self, media_item: Image | VideoFrame, annotation_scene: AnnotationScene) -> AnnotationScene: """ - Upload an annotation for an image or video frame to the Intel® Geti™ server. + Upload an annotation for an image or video frame to the Geti™ server. :param media_item: Image or VideoFrame to apply and upload the annotation to :param annotation_scene: AnnotationScene to upload @@ -324,7 +324,7 @@ def upload_annotation(self, media_item: Image | VideoFrame, annotation_scene: An def get_annotation(self, media_item: Image | VideoFrame) -> AnnotationScene | None: """ Retrieve the latest annotations for an image or video frame from the - Intel® Geti™ platform. + Geti™ platform. If no annotation is available, this method returns None. :param media_item: Image or VideoFrame to retrieve the annotations for diff --git a/geti_sdk/rest_clients/annotation_clients/base_annotation_client.py b/geti_sdk/rest_clients/annotation_clients/base_annotation_client.py index c3071bca9..d780d1164 100644 --- a/geti_sdk/rest_clients/annotation_clients/base_annotation_client.py +++ b/geti_sdk/rest_clients/annotation_clients/base_annotation_client.py @@ -135,7 +135,7 @@ def __get_label_mapping(self, project: Project) -> dict[str, str]: if label.is_empty: # We perform a casefold on the label name to ensure that we can match # the empy labels from projects created in older versions of the - # Intel Geti platform. + # Geti platform. label_name = label.name.casefold() else: label_name = label.name @@ -324,7 +324,7 @@ def annotation_scene_from_rest_response( self, response_dict: dict[str, Any], media_information: MediaInformation ) -> AnnotationScene: """ - Convert a dictionary with annotation data obtained from the Intel® Geti™ + Convert a dictionary with annotation data obtained from the Geti™ /annotations rest endpoint into an annotation scene. :param response_dict: Dictionary containing the annotation data diff --git a/geti_sdk/rest_clients/credit_system_client.py b/geti_sdk/rest_clients/credit_system_client.py index ea53ebb8d..e8b629f91 100644 --- a/geti_sdk/rest_clients/credit_system_client.py +++ b/geti_sdk/rest_clients/credit_system_client.py @@ -31,7 +31,7 @@ def allow_supported(func): def wrapper(instance, *args, **kwargs): if instance._is_supported: return func(instance, *args, **kwargs) - logging.warning("Credit System is not supported by the Intel Geti Platform.") + logging.warning("Credit System is not supported by the Geti Platform.") return None return wrapper @@ -39,7 +39,7 @@ def wrapper(instance, *args, **kwargs): class CreditSystemClient: """ - Class to work with credits in Intel Geti. + Class to work with credits in Geti. """ def __init__(self, session: GetiSession, workspace_id: str | None = None): @@ -48,12 +48,12 @@ def __init__(self, session: GetiSession, workspace_id: str | None = None): self.workspace_id = workspace_id else: self.workspace_id = get_workspace_id(self.session) - # Make sure the Intel Geti Platform supports Credit System. + # Make sure the Geti Platform supports Credit System. self._is_supported = self.is_supported() def is_supported(self) -> bool: """ - Check if the Intel Geti Platform supports Credit system. + Check if the Geti Platform supports Credit system. :return: True if the Credit System is supported, False otherwise. """ diff --git a/geti_sdk/rest_clients/dataset_client.py b/geti_sdk/rest_clients/dataset_client.py index 1d11103f2..a18aa0620 100644 --- a/geti_sdk/rest_clients/dataset_client.py +++ b/geti_sdk/rest_clients/dataset_client.py @@ -33,7 +33,7 @@ class DatasetClient: """ - Class to manage datasets for a certain Intel® Geti™ project. + Class to manage datasets for a certain Geti™ project. """ def __init__(self, workspace_id: str, project: Project, session: GetiSession): @@ -85,7 +85,7 @@ def delete_dataset(self, dataset: Dataset) -> None: def get_all_datasets(self) -> list[Dataset]: """ - Query the Intel® Geti™ server to retrieve an up to date list of datasets in + Query the Geti™ server to retrieve an up to date list of datasets in the project. :return: List of current datasets in the project diff --git a/geti_sdk/rest_clients/deployment_client.py b/geti_sdk/rest_clients/deployment_client.py index ebb97a451..d5caaf667 100644 --- a/geti_sdk/rest_clients/deployment_client.py +++ b/geti_sdk/rest_clients/deployment_client.py @@ -37,7 +37,7 @@ class DeploymentClient: """ - Class to manage model deployment for a certain Intel® Geti™ project. + Class to manage model deployment for a certain Geti™ project. """ def __init__(self, workspace_id: str, project: Project, session: GetiSession): @@ -62,7 +62,7 @@ def deployment_package_url(self) -> str: """ Return the base URL for the deployment group of endpoints - :return: URL for the deployment endpoints for the Intel® Geti™ project + :return: URL for the deployment endpoints for the Geti™ project """ return self.base_url + "/deployment_package" diff --git a/geti_sdk/rest_clients/media_client/media_client.py b/geti_sdk/rest_clients/media_client/media_client.py index 091f8ddb8..e9cee3b07 100644 --- a/geti_sdk/rest_clients/media_client/media_client.py +++ b/geti_sdk/rest_clients/media_client/media_client.py @@ -167,7 +167,7 @@ def _upload_bytes(self, buffer: BinaryIO, dataset: Dataset | None = None) -> dic :param buffer: BinaryIO object representing a media file :param dataset: Dataset to upload the media to. If no dataset is passed, the media will be uploaded into the default (training) dataset - :return: Dictionary containing the response of the Intel® Geti™ server, which + :return: Dictionary containing the response of the Geti™ server, which holds the details of the uploaded entity """ if dataset is None: @@ -186,7 +186,7 @@ def _upload(self, filepath: str, dataset: Dataset | None = None) -> dict[str, An :param filepath: full path to the media file on disk :param dataset: Dataset to upload the media to. If no dataset is passed, the media will be uploaded into the default (training) dataset - :return: Dictionary containing the response of the Intel® Geti™ server, which + :return: Dictionary containing the response of the Geti™ server, which holds the details of the uploaded entity """ with open(filepath, "rb") as f: @@ -284,7 +284,7 @@ def _upload_folder( ) -> MediaList[MediaTypeVar]: """ Upload all media in a folder to the project. Returns the mapping of filenames - to the unique IDs assigned by Intel Geti. + to the unique IDs assigned by Geti. :param path_to_folder: Folder with media items to upload :param n_media: Number of media to upload from folder diff --git a/geti_sdk/rest_clients/media_client/video_client.py b/geti_sdk/rest_clients/media_client/video_client.py index c7bb77f7a..1a6885c18 100644 --- a/geti_sdk/rest_clients/media_client/video_client.py +++ b/geti_sdk/rest_clients/media_client/video_client.py @@ -121,7 +121,7 @@ def upload_folder( ) -> MediaList[Video]: """ Upload all videos in a folder to the project. Returns the mapping of video - filename to the unique ID assigned by Intel Geti. + filename to the unique ID assigned by Geti. :param path_to_folder: Folder with videos to upload :param n_videos: Number of videos to upload from folder diff --git a/geti_sdk/rest_clients/model_client.py b/geti_sdk/rest_clients/model_client.py index f483447a8..98ba10b40 100644 --- a/geti_sdk/rest_clients/model_client.py +++ b/geti_sdk/rest_clients/model_client.py @@ -192,7 +192,7 @@ def get_model_by_algorithm_task_and_version( task: Task | None = None, ) -> Model | None: """ - Retrieve a Model from the Intel® Geti™ server, corresponding to a specific + Retrieve a Model from the Geti™ server, corresponding to a specific algorithm and model version. If no version is passed, this method will retrieve the latest model for the algorithm. @@ -327,7 +327,7 @@ def get_active_model_for_task(self, task: Task) -> Model | None: :param task: Task object containing details of the task to get the model for :return: Model object representing the currently active model in the - Intel® Geti™ project, if any + Geti™ project, if any """ model_groups = self.get_all_model_groups() model_id: str | None = None @@ -429,7 +429,7 @@ def get_all_active_models(self) -> list[Model | None]: the index of that task will be None :return: Model object representing the currently active model for the task in - the Intel® Geti™ project, if any + the Geti™ project, if any """ return [self.get_active_model_for_task(task=task) for task in self.project.get_trainable_tasks()] @@ -443,7 +443,7 @@ def download_all_active_models(self, path_to_folder: str) -> list[Model | None]: :param path_to_folder: Path to the target folder in which to save the active models, and all optimized models derived from them. :return: List of Model objects representing the currently active models - (if any) for all tasks in the Intel® Geti™ project. The index of the + (if any) for all tasks in the Geti™ project. The index of the Model in the list corresponds to the index of the task in the list of trainable tasks for the project. """ @@ -454,7 +454,7 @@ def download_all_active_models(self, path_to_folder: str) -> list[Model | None]: def get_model_for_job(self, job: Job, check_status: bool = True) -> Model: """ - Return the model that was created by the `job` from the Intel® Geti™ server. + Return the model that was created by the `job` from the Geti™ server. :param job: Job to retrieve the model for :param check_status: True to first update the status of the job, to make sure @@ -544,7 +544,7 @@ def optimize_model(self, model: Model, optimization_type: str = "pot") -> Job: :param optimization_type: DEPRECATED. Type of optimization to run. Currently supported values: ["pot"]. Case insensitive. Defaults to "pot" :return: Job object referring to the optimization job running on the - Intel® Geti™ server. + Geti™ server. """ if isinstance(model, OptimizedModel): raise ValueError( @@ -569,10 +569,10 @@ def optimize_model(self, model: Model, optimization_type: str = "pot") -> Job: def purge_model(self, model: Model | ModelSummary) -> None: """ - Purge the model from the Intel® Geti™ server. + Purge the model from the Geti™ server. This will permanently delete all the files related to the model including base model weights, - optimized model weights and exportable code for the Intel® Geti™ server. + optimized model weights and exportable code for the Geti™ server. :param model: Model to archive. Only base models are accepted, not optimized models. Note: the model must not be the latest in the model group or be the active model. diff --git a/geti_sdk/rest_clients/prediction_client.py b/geti_sdk/rest_clients/prediction_client.py index 2fe58b0bc..4bacc1be7 100644 --- a/geti_sdk/rest_clients/prediction_client.py +++ b/geti_sdk/rest_clients/prediction_client.py @@ -44,7 +44,7 @@ class PredictionClient: """ - Class to download predictions from an existing Intel® Geti™ project. + Class to download predictions from an existing Geti™ project. """ def __init__(self, session: GetiSession, project: Project, workspace_id: str): @@ -116,7 +116,7 @@ def mode(self) -> PredictionMode: def mode(self, new_mode: str | PredictionMode): """ Set the mode for the Prediction client to retrieve predictions from the - Intel® Geti™ server. + Geti™ server. :param new_mode: PredictionMode (or string representing a prediction mode) to set @@ -285,7 +285,7 @@ def _get_prediction_for_media_item( def get_image_prediction(self, image: Image) -> Prediction: """ - Get a prediction for an image from the Intel® Geti™ server, if available. + Get a prediction for an image from the Geti™ server, if available. NOTE: This method is only available for images that are already existing on the server! For getting predictions on a 'new' image, please see the @@ -302,7 +302,7 @@ def get_image_prediction(self, image: Image) -> Prediction: def get_video_frame_prediction(self, video_frame: VideoFrame) -> Prediction: """ - Get a prediction for a video frame from the Intel® Geti™ server, if available. + Get a prediction for a video frame from the Geti™ server, if available. :param video_frame: VideoFrame to get the prediction for. The frame has to be present in the project on the cluster already. @@ -315,7 +315,7 @@ def get_video_frame_prediction(self, video_frame: VideoFrame) -> Prediction: def get_video_predictions(self, video: Video) -> list[Prediction]: """ - Get a list of predictions for a video from the Intel® Geti™ server, if available. + Get a list of predictions for a video from the Geti™ server, if available. :param video: Video to get the predictions for. The video has to be present in the project on the cluster already. @@ -582,7 +582,7 @@ def _download_predictions_for_2d_media_list( def predict_image(self, image: Image | np.ndarray | os.PathLike | str) -> Prediction: """ - Push an image to the Intel® Geti™ project and receive a prediction for it. + Push an image to the Geti™ project and receive a prediction for it. Note that this method will not save the image to the project. diff --git a/geti_sdk/rest_clients/project_client/project_client.py b/geti_sdk/rest_clients/project_client/project_client.py index 231cf5863..d48f65a4f 100644 --- a/geti_sdk/rest_clients/project_client/project_client.py +++ b/geti_sdk/rest_clients/project_client/project_client.py @@ -62,7 +62,7 @@ class ProjectClient: """ - Class to manipulate projects on the Intel® Geti™ server, within a certain workspace. + Class to manipulate projects on the Geti™ server, within a certain workspace. """ def __init__(self, session: GetiSession, workspace_id: str): @@ -72,16 +72,16 @@ def __init__(self, session: GetiSession, workspace_id: str): def get_all_projects(self, request_page_size: int = 50, get_project_details: bool = True) -> list[Project]: """ - Return a list of projects found on the Intel® Geti™ server + Return a list of projects found on the Geti™ server :param request_page_size: Max number of projects to fetch in a single HTTP request. Higher values may reduce the response time of this method when there are many projects, but increase the chance of timeout. :param get_project_details: True to get all details of the projects on the - Intel® Geti™, False to fetch only a summary of each project. Set this to + Geti™, False to fetch only a summary of each project. Set this to False if minimizing latency is a concern. Defaults to True :return: List of Project objects, containing the project information for each - project on the Intel® Geti™ server + project on the Geti™ server """ # The 'projects' endpoint uses pagination: multiple HTTP may be necessary to # fetch the full list of projects @@ -112,7 +112,7 @@ def get_project_by_name( project_name: str, ) -> Project | None: """ - Get a project from the Intel® Geti™ server by project_name. + Get a project from the Geti™ server by project_name. If multiple projects with the same name exist on the server, this method will raise a ValueError. In that case, please use the `ProjectClient.get_project()` @@ -210,9 +210,9 @@ def create_project( def download_project_info(self, project: Project, path_to_folder: str) -> None: """ Get the project data that can be used for project creation on - the Intel® Geti™ server. From the returned data, the + the Geti™ server. From the returned data, the method `ProjectClient.get_or_create_project` can create a project on the - Intel® Geti™ server. The data is retrieved from the cluster and saved in the + Geti™ server. The data is retrieved from the cluster and saved in the target folder `path_to_folder`. :param project: Project to download the data for @@ -346,8 +346,8 @@ def create_project_from_folder(self, path_to_folder: str, project_name: str | No def _is_project_dir(path_to_folder: str) -> bool: """ Check if the folder specified in `path_to_folder` is a directory - containing valid Intel® Geti™ project data that can be used to upload to an - Intel® Geti™ server. + containing valid Geti™ project data that can be used to upload to an + Geti™ server. :param path_to_folder: Directory to check :return: True if the directory holds project data, False otherwise @@ -411,8 +411,8 @@ def _create_project_template( task_names_in_template: list[str] = [previous_task_name] is_first_task = True for task_type, task_labels in zip(get_task_types_by_project_type(project_type), labels): - # Anomaly task reduction introduced in Intel Geti 2.5 - # The last on-premises version of Intel Geti to support legacy anomaly projects is 2.0 + # Anomaly task reduction introduced in Geti 2.5 + # The last on-premises version of Geti to support legacy anomaly projects is 2.0 if self.session.version >= GETI_25_VERSION and task_type.is_anomaly and task_type != TaskType.ANOMALY: logging.info(f"The {task_type} task is mapped to {TaskType.ANOMALY}.") task_type = TaskType.ANOMALY @@ -660,7 +660,7 @@ def add_labels( def _await_project_ready(self, project: Project, timeout: int = 5, interval: int = 1) -> None: """ - Await the completion of the project creation process on the Intel® Geti™ server + Await the completion of the project creation process on the Geti™ server :param project: Project object representing the project :param timeout: Time (in seconds) after which the method will time out and @@ -682,7 +682,7 @@ def _await_project_ready(self, project: Project, timeout: int = 5, interval: int def get_project_by_id(self, project_id: str) -> Project | None: """ - Get a project from the Intel® Geti™ server by project_id. + Get a project from the Geti™ server by project_id. :param project_id: ID of the project to get :return: Project object containing the data of the project, if the project is @@ -698,7 +698,7 @@ def get_project( project: Project | None = None, ) -> Project | None: """ - Get a project from the Intel® Geti™ server by project_name or project_id, or + Get a project from the Geti™ server by project_name or project_id, or update a provided Project object with the latest data from the server. :param project_name: Name of the project to get diff --git a/geti_sdk/rest_clients/testing_client.py b/geti_sdk/rest_clients/testing_client.py index a567b43eb..c9c9b3426 100644 --- a/geti_sdk/rest_clients/testing_client.py +++ b/geti_sdk/rest_clients/testing_client.py @@ -24,7 +24,7 @@ class TestingClient: """ - Class to manage testing jobs for a certain Intel® Geti™ project. + Class to manage testing jobs for a certain Geti™ project. """ def __init__(self, workspace_id: str, project: Project, session: GetiSession): @@ -78,7 +78,7 @@ def test_model( def get_test_result(self, job: Job) -> TestResult: """ - Retrieve the result of the model testing job from the Intel® Geti™ + Retrieve the result of the model testing job from the Geti™ server :param job: Job instance representing the model testing job diff --git a/geti_sdk/rest_clients/training_client.py b/geti_sdk/rest_clients/training_client.py index 0b7f3bf5d..06f393c80 100644 --- a/geti_sdk/rest_clients/training_client.py +++ b/geti_sdk/rest_clients/training_client.py @@ -37,7 +37,7 @@ class TrainingClient: """ - Class to manage training jobs for a certain Intel® Geti™ project. + Class to manage training jobs for a certain Geti™ project. """ def __init__(self, workspace_id: str, project: Project, session: GetiSession): @@ -51,7 +51,7 @@ def __init__(self, workspace_id: str, project: Project, session: GetiSession): def get_status(self) -> ProjectStatus: """ - Get the current status of the project from the Intel® Geti™ server. + Get the current status of the project from the Geti™ server. :return: ProjectStatus object reflecting the current project status """ @@ -66,7 +66,7 @@ def is_training(self) -> bool: def get_jobs(self, project_only: bool = True, running_only: bool = False) -> list[Job]: """ - Return a list of all jobs on the Intel® Geti™ server. + Return a list of all jobs on the Geti™ server. If `project_only = True` (the default), only those jobs related to the project managed by this TrainingClient will be returned. If set to False, all jobs in @@ -74,7 +74,7 @@ def get_jobs(self, project_only: bool = True, running_only: bool = False) -> lis :param project_only: True to return only those jobs pertaining to the project for which the TrainingClient is active. False to return all jobs in the - Intel® Geti™ workspace. + Geti™ workspace. :param running_only: If set to True, only return those jobs that are still running. Completed or Scheduled jobs will not be included in that case :return: List of Jobs diff --git a/geti_sdk/rest_converters/annotation_rest_converter/annotation_rest_converter.py b/geti_sdk/rest_converters/annotation_rest_converter/annotation_rest_converter.py index 837f84f8e..ef287003e 100644 --- a/geti_sdk/rest_converters/annotation_rest_converter/annotation_rest_converter.py +++ b/geti_sdk/rest_converters/annotation_rest_converter/annotation_rest_converter.py @@ -144,7 +144,7 @@ def _media_identifier_from_dict(input_dict: dict[str, Any]) -> MediaIdentifier: def from_dict(annotation_scene: dict[str, Any]) -> AnnotationScene: """ Create an AnnotationScene object from a dictionary returned by the - /annotations REST endpoint in the Intel® Geti™ platform. + /annotations REST endpoint in the Geti™ platform. :param annotation_scene: dictionary representing an AnnotationScene, which contains all annotations for a certain media entity diff --git a/geti_sdk/rest_converters/configuration_rest_converter.py b/geti_sdk/rest_converters/configuration_rest_converter.py index 7fcf0910c..9b3e4cedb 100644 --- a/geti_sdk/rest_converters/configuration_rest_converter.py +++ b/geti_sdk/rest_converters/configuration_rest_converter.py @@ -45,7 +45,7 @@ ) class ConfigurationRESTConverter: """ - Class that handles conversion of Intel® Geti™ REST output for configurable parameter + Class that handles conversion of Geti™ REST output for configurable parameter entities to objects and vice versa. """ @@ -54,7 +54,7 @@ def entity_identifier_from_dict(input_dict: dict[str, Any]) -> EntityIdentifier: """ Create an EntityIdentifier object from an input dictionary. - :param input_dict: Dictionary representing an EntityIdentifier in Intel® Geti™ + :param input_dict: Dictionary representing an EntityIdentifier in Geti™ :return: EntityIdentifier object corresponding to the data in `input_dict` """ identifier_type = input_dict.get("type") @@ -74,7 +74,7 @@ def entity_identifier_from_dict(input_dict: dict[str, Any]) -> EntityIdentifier: def from_dict(input_dict: dict[str, Any]) -> ConfigurableParameters: """ Create a ConfigurableParameters object holding the configurable parameters - for an entity in the Intel® Geti™ platform, from a dictionary returned by the + for an entity in the Geti™ platform, from a dictionary returned by the /configuration REST endpoints. :param input_dict: Dictionary containing the configurable parameters @@ -95,7 +95,7 @@ def _rest_components_to_objects( ) -> list[ConfigurableParameters]: """ Create a list of configurable parameters from a list of dictionaries received - by the Intel® Geti™ /configuration endpoints. + by the Geti™ /configuration endpoints. :param input_list: List of dictionaries to convert :return: List of ConfigurableParameters instances @@ -161,7 +161,7 @@ def configuration_to_minimal_dict( """ Convert a TaskConfiguration, GlobalConfiguration or FullConfiguration into a dictionary, removing fields that are None or are only relevant to the - Intel® Geti™ UI. + Geti™ UI. :param configuration: TaskConfiguration or GlobalConfiguration to convert :param deidentify: True to remove all unique database identifiers, False to @@ -190,7 +190,7 @@ def global_configuration_from_rest( ) -> GlobalConfiguration: """ Create a GlobalConfiguration object holding the configurable parameters - for all project-wide components in the Intel® Geti™ project, from input from the + for all project-wide components in the Geti™ project, from input from the /configuration/global REST endpoint. :param input_: REST response holding the serialized configurable parameters @@ -207,7 +207,7 @@ def global_configuration_from_rest( @staticmethod def full_configuration_from_rest(input_dict: dict[str, Any]) -> FullConfiguration: """ - Convert a dictionary holding the full configuration for an Intel® Geti™ + Convert a dictionary holding the full configuration for an Geti™ project, as returned by the /configuration endpoint, to an object representation. diff --git a/geti_sdk/rest_converters/job_rest_converter.py b/geti_sdk/rest_converters/job_rest_converter.py index b9836cecd..82720e8be 100644 --- a/geti_sdk/rest_converters/job_rest_converter.py +++ b/geti_sdk/rest_converters/job_rest_converter.py @@ -20,7 +20,7 @@ class JobRESTConverter: """ - Class that handles conversion of Intel® Geti™ REST output for jobs to objects, + Class that handles conversion of Geti™ REST output for jobs to objects, and vice-versa """ @@ -29,7 +29,7 @@ def from_dict(job_dict: dict[str, Any]) -> Job: """ Create a Job instance from the input dictionary passed in `job_dict`. - :param job_dict: Dictionary representing a job on the Intel® Geti™ server, as + :param job_dict: Dictionary representing a job on the Geti™ server, as returned by the /jobs endpoints :return: Job instance, holding the job data contained in job_dict """ diff --git a/geti_sdk/rest_converters/media_rest_converter.py b/geti_sdk/rest_converters/media_rest_converter.py index 8e2dbc769..3a5f2f176 100644 --- a/geti_sdk/rest_converters/media_rest_converter.py +++ b/geti_sdk/rest_converters/media_rest_converter.py @@ -20,7 +20,7 @@ class MediaRESTConverter: """ - Class that handles conversion of Intel® Geti™ REST output for media entities to + Class that handles conversion of Geti™ REST output for media entities to objects and vice versa. """ @@ -28,7 +28,7 @@ class MediaRESTConverter: def from_dict(input_dict: dict[str, Any], media_type: type[MediaTypeVar]) -> MediaTypeVar: """ Create an instance of type `media_type` representing a media entity on the - Intel® Geti™ server from a dictionary returned by the GETi /media REST + Geti™ server from a dictionary returned by the GETi /media REST endpoints. :param input_dict: Dictionary representing the media entity diff --git a/geti_sdk/rest_converters/model_rest_converter.py b/geti_sdk/rest_converters/model_rest_converter.py index 26a9f1fc8..78b5e17aa 100644 --- a/geti_sdk/rest_converters/model_rest_converter.py +++ b/geti_sdk/rest_converters/model_rest_converter.py @@ -21,7 +21,7 @@ class ModelRESTConverter: """ - Class that handles conversion of Intel® Geti™ REST output for media entities to + Class that handles conversion of Geti™ REST output for media entities to objects and vice versa. """ @@ -31,7 +31,7 @@ def model_group_from_dict(input_dict: dict[str, Any]) -> ModelGroup: Convert a dictionary representing a model group to a ModelGroup object. :param input_dict: Dictionary representing a model group, as returned by the - Intel® Geti™ /model_groups REST endpoint + Geti™ /model_groups REST endpoint :return: ModelGroup object corresponding to the data in `input_dict` """ return deserialize_dictionary(input_dict, output_type=ModelGroup) @@ -42,7 +42,7 @@ def model_from_dict(input_dict: dict[str, Any]) -> Model: Convert a dictionary representing a model to a Model object. :param input_dict: Dictionary representing a model, as returned by the - Intel® Geti™ /model_groups/models REST endpoint + Geti™ /model_groups/models REST endpoint :return: Model object corresponding to the data in `input_dict` """ model_group_id = input_dict.pop("model_group_id", None) @@ -56,7 +56,7 @@ def optimized_model_from_dict(input_dict: dict[str, Any]) -> OptimizedModel: Convert a dictionary representing an optimized model to a OptimizedModel object. :param input_dict: Dictionary representing an optimized model, as returned by - the Intel® Geti™ /model_groups/models REST endpoint + the Geti™ /model_groups/models REST endpoint :return: OptimizedModel object corresponding to the data in `input_dict` """ model_group_id = input_dict.pop("model_group_id", None) diff --git a/geti_sdk/rest_converters/prediction_rest_converter/normalized_prediction_rest_converter.py b/geti_sdk/rest_converters/prediction_rest_converter/normalized_prediction_rest_converter.py index b5788abe1..a6b3325c3 100644 --- a/geti_sdk/rest_converters/prediction_rest_converter/normalized_prediction_rest_converter.py +++ b/geti_sdk/rest_converters/prediction_rest_converter/normalized_prediction_rest_converter.py @@ -37,7 +37,7 @@ class NormalizedPredictionRESTConverter(PredictionRESTConverter): def normalized_prediction_from_dict(prediction: dict[str, Any], image_width: int, image_height: int) -> Prediction: """ Legacy method that creates an AnnotationScene object from a dictionary - returned by the /annotations REST endpoint in Intel® Geti™ versions 1.1 or + returned by the /annotations REST endpoint in Geti™ versions 1.1 or below :param prediction: dictionary representing a Prediction, which diff --git a/geti_sdk/rest_converters/prediction_rest_converter/prediction_rest_converter.py b/geti_sdk/rest_converters/prediction_rest_converter/prediction_rest_converter.py index 376975831..f0cbeb308 100644 --- a/geti_sdk/rest_converters/prediction_rest_converter/prediction_rest_converter.py +++ b/geti_sdk/rest_converters/prediction_rest_converter/prediction_rest_converter.py @@ -32,7 +32,7 @@ class PredictionRESTConverter: def from_dict(prediction: dict[str, Any]) -> Prediction: """ Create a Prediction object from a dictionary returned by the - /predictions REST endpoint in the Intel® Geti™ platform. + /predictions REST endpoint in the Geti™ platform. :param prediction: dictionary representing a Prediction, which contains all prediction annotations for a certain media entity diff --git a/geti_sdk/rest_converters/project_rest_converter.py b/geti_sdk/rest_converters/project_rest_converter.py index 6a36ce32e..8986465ba 100644 --- a/geti_sdk/rest_converters/project_rest_converter.py +++ b/geti_sdk/rest_converters/project_rest_converter.py @@ -22,7 +22,7 @@ class ProjectRESTConverter: """ - Class that handles conversion of Intel® Geti™ REST output for project entities to + Class that handles conversion of Geti™ REST output for project entities to objects and vice versa. """ @@ -30,10 +30,10 @@ class ProjectRESTConverter: def from_dict(cls, project_input: dict[str, Any]) -> Project: """ Create a Project from a dictionary representing a project, as - returned by the /projects endpoint on the Intel® Geti™ platform. + returned by the /projects endpoint on the Geti™ platform. :param project_input: Dictionary representing a project, as returned by the - Intel® Geti™ server + Geti™ server :return: Project object representing the project given in `project_input` """ prepared_project = copy.deepcopy(project_input) diff --git a/geti_sdk/rest_converters/status_rest_converter.py b/geti_sdk/rest_converters/status_rest_converter.py index d3f074f66..faf48d068 100644 --- a/geti_sdk/rest_converters/status_rest_converter.py +++ b/geti_sdk/rest_converters/status_rest_converter.py @@ -20,7 +20,7 @@ class StatusRESTConverter: """ - Class that handles conversion of Intel® Geti™ REST output for status entities to + Class that handles conversion of Geti™ REST output for status entities to objects """ @@ -31,7 +31,7 @@ def from_dict(project_status_dict: dict[str, Any]) -> ProjectStatus: `project_status_dict`. :param project_status_dict: Dictionary representing the status of a project on - the Intel® Geti™ server + the Geti™ server :return: ProjectStatus instance, holding the status data contained in project_status_dict """ diff --git a/geti_sdk/rest_converters/test_result_rest_converter.py b/geti_sdk/rest_converters/test_result_rest_converter.py index 6b4899dfc..29b0cb7e4 100644 --- a/geti_sdk/rest_converters/test_result_rest_converter.py +++ b/geti_sdk/rest_converters/test_result_rest_converter.py @@ -20,7 +20,7 @@ class TestResultRESTConverter: """ - Class that handles conversion of Intel® Geti™ REST output for test results to + Class that handles conversion of Geti™ REST output for test results to objects, and vice-versa """ @@ -29,7 +29,7 @@ def from_dict(result_dict: dict[str, Any]) -> TestResult: """ Create a TestResult instance from the input dictionary passed in `result_dict`. - :param result_dict: Dictionary representing a test result on the Intel® Geti™ + :param result_dict: Dictionary representing a test result on the Geti™ server, as returned by the /tests endpoints :return: TestResult instance, holding the result data contained in result_dict """ diff --git a/geti_sdk/utils/algorithm_helpers.py b/geti_sdk/utils/algorithm_helpers.py index ca1cbc087..48448a57e 100644 --- a/geti_sdk/utils/algorithm_helpers.py +++ b/geti_sdk/utils/algorithm_helpers.py @@ -66,7 +66,7 @@ def get_default_algorithm_info( Return the names of the default algorithms for the tasks in the `project`. The returned response is a map of TaskType to the default algorithm name for that task - :param session: GetiSession to the Intel Geti server + :param session: GetiSession to the Geti server :param workspace_id: Workspace ID in which the project to retrieve the default algorithms for lives. :param project: Project to retrieve the default algorithms for diff --git a/geti_sdk/utils/job_helpers.py b/geti_sdk/utils/job_helpers.py index 6030e547f..6ea8f11ad 100644 --- a/geti_sdk/utils/job_helpers.py +++ b/geti_sdk/utils/job_helpers.py @@ -43,10 +43,10 @@ def restrict(value: float, min: float = 0, max: float = 1) -> float: # noqa: A0 def get_job_by_id(job_id: str, session: GetiSession, workspace_id: str) -> Job | None: """ - Retrieve Job information from the Intel® Geti™ server. + Retrieve Job information from the Geti™ server. :param job_id: Unique ID of the job to retrieve - :param session: GetiSession instance addressing the Intel® Geti™ platform + :param session: GetiSession instance addressing the Geti™ platform :param workspace_id: ID of the workspace in which the job was created :return: Job instance holding the details of the job """ @@ -70,11 +70,11 @@ def get_job_with_timeout( timeout: int = 15, ) -> Job: """ - Retrieve a Job from the Intel® Geti™ server, by it's unique ID. If the job is not + Retrieve a Job from the Geti™ server, by it's unique ID. If the job is not found within the specified `timeout`, a RuntimeError is raised. :param job_id: Unique ID of the job to retrieve - :param session: GetiSession instance addressing the Intel® Geti™ platform + :param session: GetiSession instance addressing the Geti™ platform :param workspace_id: ID of the workspace in which the job was created :param job_type: String representing the type of job, for instance "training" or "testing" @@ -108,7 +108,7 @@ def get_job_with_timeout( else: raise job_error if job is None: - raise RuntimeError(f"Unable to find the resulting {job_type} job on the Intel® Geti™ server.") + raise RuntimeError(f"Unable to find the resulting {job_type} job on the Geti™ server.") return job @@ -119,7 +119,7 @@ def monitor_jobs(session: GetiSession, jobs: list[Job], timeout: int = 10000, in Progress will be reported in 15s intervals - :param session: GetiSession instance addressing the Intel® Geti™ platform + :param session: GetiSession instance addressing the Geti™ platform :param jobs: List of jobs to monitor :param timeout: Timeout (in seconds) after which to stop the monitoring :param interval: Time interval (in seconds) at which the TrainingClient polls @@ -195,7 +195,7 @@ def monitor_jobs(session: GetiSession, jobs: list[Job], timeout: int = 10000, in if error.status_code == 404: logging.warning( f"Job with name `{job.name}` and id `{job.id}` was not " - f"found on the Intel Geti instance. Monitoring is skipped " + f"found on the Geti instance. Monitoring is skipped " f"for this job." ) jobs_with_error.append(job) @@ -256,7 +256,7 @@ def monitor_job(session: GetiSession, job: Job, timeout: int = 10000, interval: Progress will be reported in 15s intervals - :param session: GetiSession instance addressing the Intel® Geti™ platform + :param session: GetiSession instance addressing the Geti™ platform :param job: Job to monitor :param timeout: Timeout (in seconds) after which to stop the monitoring :param interval: Time interval (in seconds) at which the TrainingClient polls @@ -280,7 +280,7 @@ def monitor_job(session: GetiSession, job: Job, timeout: int = 10000, interval: if error.status_code == 404: logging.warning( f"Job with name `{job.name}` and id `{job.id}` was not " - f"found on the Intel Geti instance. Monitoring is skipped " + f"found on the Geti instance. Monitoring is skipped " f"for this job." ) if job.state in completed_states: diff --git a/geti_sdk/utils/label_helpers.py b/geti_sdk/utils/label_helpers.py index 7084ee350..57b8f33fd 100644 --- a/geti_sdk/utils/label_helpers.py +++ b/geti_sdk/utils/label_helpers.py @@ -39,7 +39,7 @@ def generate_classification_labels(labels: list[str], multilabel: bool = False) :param multilabel: True to be able to assign multiple labels to one image, False otherwise. Defaults to False. :return: List of dictionaries containing the label data that can be sent to the - Intel® Geti™ project creation endpoint + Geti™ project creation endpoint """ label_list: list[dict[str, str]] = [] if multilabel or len(labels) == 1: diff --git a/notebooks/002_create_project_from_dataset.ipynb b/notebooks/002_create_project_from_dataset.ipynb index 5491b16eb..11c3d5a27 100644 --- a/notebooks/002_create_project_from_dataset.ipynb +++ b/notebooks/002_create_project_from_dataset.ipynb @@ -39,7 +39,7 @@ "source": [ "## Import from a supported dataset format\n", "\n", - "The Intel Geti SDK package provides a class `GetiIE` to easily import datasets from one of the formats supported by Geti, including:\n", + "The Geti SDK package provides a class `GetiIE` to easily import datasets from one of the formats supported by Geti, including:\n", "- Datumaro\n", "- COCO\n", "- VOC\n", @@ -141,7 +141,7 @@ "\n", "If your dataset does not comply with one of the supported formats, there are several ways how to go around this.\n", "- You can try to convert your dataset to one of the supported formats and come back to the automated approach. This can be done by writing a script that will do the conversion. The drawback of this approach is that you can end up keeping multiple copies of the same dataset.\n", - "- You can implement an [AnnotationReader](https://openvinotoolkit.github.io/geti-sdk/geti_sdk.annotation_readers.html#) of your own by following a few implementation examples already present in the Intel Geti SDK package - [DirectoryTreeAnnotationReader](https://github.com/openvinotoolkit/geti-sdk/blob/main/geti_sdk/annotation_readers/directory_tree_annotation_reader.py). It is especially useful if you have an established home-grown annotation format and the data you gather will be kept in this format in the future as well.\n", + "- You can implement an [AnnotationReader](https://openvinotoolkit.github.io/geti-sdk/geti_sdk.annotation_readers.html#) of your own by following a few implementation examples already present in the Geti SDK package - [DirectoryTreeAnnotationReader](https://github.com/openvinotoolkit/geti-sdk/blob/main/geti_sdk/annotation_readers/directory_tree_annotation_reader.py). It is especially useful if you have an established home-grown annotation format and the data you gather will be kept in this format in the future as well.\n", "- You can create a project from scratch and upload the data and annotations to it, in multiple steps. This is the most straightforward approach, but it requires more interactions with the server.\n", "\n", "The following example adopts the last approach: it reads the dataset annotations from a `csv` file, then uses `geti-sdk` to create a detection project, upload images and annotations to it.\n", diff --git a/notebooks/009_post_inference_hooks.ipynb b/notebooks/009_post_inference_hooks.ipynb index e0667d3e4..cec3fb8e2 100644 --- a/notebooks/009_post_inference_hooks.ipynb +++ b/notebooks/009_post_inference_hooks.ipynb @@ -128,7 +128,7 @@ "- If and only if the prediction contains at least one object labelled `dog`:\n", "- Send the image to the Geti project, to a dedicated dataset named 'Inferred images'\n", "\n", - "Basically, this behaviour can be separated into two parts: A **Trigger** and an **Action**. The first part, in which we check if the prediction contains at least one dog, is the Trigger. If the trigger activates, the Action will be carried out: Sending the data to the Intel Geti server. \n", + "Basically, this behaviour can be separated into two parts: A **Trigger** and an **Action**. The first part, in which we check if the prediction contains at least one dog, is the Trigger. If the trigger activates, the Action will be carried out: Sending the data to the Geti server. \n", "\n", "The reasoning here is that if the prediction contains a dog, we want to collect the image in our animal detection project so that we can include it in the next training round. To achieve this, we will use the `LabelTrigger`: It will activate if the prediction contains any objects labelled `dog`. \n", "\n", diff --git a/notebooks/012_benchmarking_models.ipynb b/notebooks/012_benchmarking_models.ipynb index 31ad016f9..ac6fe9161 100644 --- a/notebooks/012_benchmarking_models.ipynb +++ b/notebooks/012_benchmarking_models.ipynb @@ -145,7 +145,7 @@ "id": "fecd6ede-f3f1-4705-8aa0-4eb3ff2b16ed", "metadata": {}, "source": [ - "## Preparing the Intel® Geti™ project to run the benchmark\n", + "## Preparing the Geti™ project to run the benchmark\n", "Now that the `Benchmarker` is initialized, we need to make sure that all the algorithms that we'd like to benchmark have a model trained in the project. To do so, the Benchmarker provides a `prepare_benchmark` method that we can call. If we call it, the method will make sure of three things:\n", "1. It will check if every algorithm we want to benchmark has a trained model in the project. If not, it will start model training and will wait for it to complete\n", "2. It will check if for every trained model that we want to benchmark an optimized model is available in the specified precision levels. If not, it will trigger model optimiziation in the required precision levels and wait for it to complete\n", diff --git a/notebooks/README.md b/notebooks/README.md index 0143377fd..06261d8c7 100644 --- a/notebooks/README.md +++ b/notebooks/README.md @@ -31,7 +31,7 @@ This directory contains Jupyter notebooks that demonstrate how to use the Geti S ## Try the Notebooks > [!IMPORTANT] -> All notebooks require access to a running Intel® Geti™ server. +> All notebooks require access to a running Geti™ server. > Make sure your server is accessible and your authentication is properly configured before running the notebooks. ### Setup the Repository @@ -53,7 +53,7 @@ This directory contains Jupyter notebooks that demonstrate how to use the Geti S ### Authentication Setup -Create a `.env` file in the `notebooks` directory with your Intel® Geti™ server details: +Create a `.env` file in the `notebooks` directory with your Geti™ server details: #### Option 1: Personal Access Token (Recommended) ```shell @@ -63,7 +63,7 @@ TOKEN=your_personal_access_token ``` To obtain a Personal Access Token: -1. Open Intel® Geti™ in your browser +1. Open Geti™ in your browser 2. Click the **User** menu (top right corner) 3. Select **Personal access token** 4. Follow the steps to create and copy your token diff --git a/notebooks/use_cases/101_simulate_low_light_product_inspection.ipynb b/notebooks/use_cases/101_simulate_low_light_product_inspection.ipynb index fa7ae841b..c20fb9892 100644 --- a/notebooks/use_cases/101_simulate_low_light_product_inspection.ipynb +++ b/notebooks/use_cases/101_simulate_low_light_product_inspection.ipynb @@ -9,8 +9,8 @@ "\n", "This notebook shows how to systematically simulate a change in lighting conditions\n", "(i.e. a shift in data distribution), and the effect such a change has on model\n", - "predictions. The notebook is using the Intel® Geti™ SDK to interact with an\n", - "Intel® Geti™ server.\n", + "predictions. The notebook is using the Geti™ SDK to interact with an\n", + "Geti™ server.\n", "\n", "**Problem description**: For any given project, a data scientist working on it may\n", "want to quantify the effect of image distortions on model performance. For example in\n", @@ -25,14 +25,14 @@ "still want to detect fabrication defects. How will this affect their anomaly\n", "segmentation model? Of course, they will do real-world tests before implementing\n", "any changes, but is it possible to simulate such a shift in data distribution in\n", - "advance? *With Intel® Geti™, it is*.\n", + "advance? *With Geti™, it is*.\n", "\n", "**Project type**: Anomaly segmentation\n", "\n", "**Project name**: Transistor anomaly segmentation\n", "\n", "\n", - "### Step 1: Connect to the Intel® Geti™ server" + "### Step 1: Connect to the Geti™ server" ] }, { diff --git a/notebooks/use_cases/102_from_zero_to_hero_9_steps.ipynb b/notebooks/use_cases/102_from_zero_to_hero_9_steps.ipynb index 5720e343d..de7e92443 100644 --- a/notebooks/use_cases/102_from_zero_to_hero_9_steps.ipynb +++ b/notebooks/use_cases/102_from_zero_to_hero_9_steps.ipynb @@ -6,18 +6,18 @@ "metadata": {}, "source": [ "\n", - "# Intel® Geti™ SDK from Zero to Hero in 9 steps\n", + "# Geti™ SDK from Zero to Hero in 9 steps\n", "\n", - "Intel® Geti™ SDK is a Python package designed to interact with an Intel® Geti™ server via the REST API. It provides various functions for managing projects, downloading and uploading data, deploying projects for local inference, configuring projects and models, launching and monitoring training jobs, and media upload and prediction. Clone and install this repo \n", + "Geti™ SDK is a Python package designed to interact with an Geti™ server via the REST API. It provides various functions for managing projects, downloading and uploading data, deploying projects for local inference, configuring projects and models, launching and monitoring training jobs, and media upload and prediction. Clone and install this repo \n", "https://github.com/openvinotoolkit/geti-sdk\n", "\n", "| ![image-7.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/43b1ded9-5ec2-4e62-a4aa-01bb974302dc) | \n", "|:--:| \n", - "| *Intel® Geti™ Platform* |\n", + "| *Geti™ Platform* |\n", "\n", "|![image.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/933896fb-90d1-4f20-aac0-24dc5e553ffa) | \n", "|:--:| \n", - "| *What you can do with Intel® Geti™ SDK* |" + "| *What you can do with Geti™ SDK* |" ] }, { @@ -25,7 +25,7 @@ "id": "1090003a", "metadata": {}, "source": [ - "Before running this notebook, please make sure you have the Intel Geti SDK installed in your local machine. If not, please follow [these instructions](https://github.com/openvinotoolkit/geti-sdk#installation)." + "Before running this notebook, please make sure you have the Geti SDK installed in your local machine. If not, please follow [these instructions](https://github.com/openvinotoolkit/geti-sdk#installation)." ] }, { @@ -42,7 +42,7 @@ "id": "7bae4a28", "metadata": {}, "source": [ - "In this notebook, we will use the SDK to create a project on the Intel Geti graphics platform, upload videos, download the displays locally, and run the inference by viewing the results on this same notebook." + "In this notebook, we will use the SDK to create a project on the Geti graphics platform, upload videos, download the displays locally, and run the inference by viewing the results on this same notebook." ] }, { @@ -50,7 +50,7 @@ "id": "f97df60a-01e6-4aaa-8013-c7e981485699", "metadata": {}, "source": [ - "# Step 1: Connect with your Intel® Geti™ Instance\n", + "# Step 1: Connect with your Geti™ Instance\n", "\n", "We will connect to the platform first, using the server details from the .env file. We will also create a ProjectClient for the server. If you have doubts, please take a look of the previous work you need to do before to [connect](https://github.com/openvinotoolkit/geti-sdk#connecting-to-the-intel-geti-platform) the SDK and the platform. " ] @@ -87,7 +87,7 @@ "source": [ "# Step 2: Create a project and upload a video for further annotations\n", "\n", - "We will create a new project from scratch and will upload a video using the SDK for further annotations into the Intel Geti Platform. We will create an object detection project for person, bike and card detection. \n", + "We will create a new project from scratch and will upload a video using the SDK for further annotations into the Geti Platform. We will create an object detection project for person, bike and card detection. \n", "\n", "| ![image-3.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/6f338f36-014a-443a-987f-d672a75f908c) | \n", "|:--:| \n", @@ -114,7 +114,7 @@ "\n", "project_client = ProjectClient(session=geti.session, workspace_id=geti.workspace_id) # setting up the project client\n", "\n", - "projects = project_client.list_projects() # listing the projects in the Intel Geti Instance" + "projects = project_client.list_projects() # listing the projects in the Geti Instance" ] }, { @@ -232,11 +232,11 @@ "metadata": {}, "source": [ "# Step 4: Creating annotations\n", - "Once you upload new image or video data, you should open the Intel Geti GUI and create annotations for it. The screenshot below shows an example of the annotator page within Geti.\n", + "Once you upload new image or video data, you should open the Geti GUI and create annotations for it. The screenshot below shows an example of the annotator page within Geti.\n", "\n", "| ![image.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/d6c95554-5eec-474f-94a2-23ac6782786b) | \n", "|:--:| \n", - "| *Annotations within the Intel® Geti™ Platform* |\n", + "| *Annotations within the Geti™ Platform* |\n", "\n", "Alternatively, if you have used the default 'person_car_bike' video that we provided, you can run the cell below to upload some pre-defined annotations for the video to the project. This saves you some time in annotating the frames." ] @@ -268,7 +268,7 @@ "metadata": {}, "source": [ "# Step 5: Training the model\n", - "Once sufficient annotations have been made, the project is ready for training. Due to the incremental learning mechanism within the Intel Geti platform, training will happen automatically and frequently. Whenever sufficient new annotations have been created, the platform will start a training round. \n", + "Once sufficient annotations have been made, the project is ready for training. Due to the incremental learning mechanism within the Geti platform, training will happen automatically and frequently. Whenever sufficient new annotations have been created, the platform will start a training round. \n", "\n", "In the next part of the notebook we will deploy the model that was trained, so that we can use it locally to generate predictions. However, before doing so we need to make sure that the project has a model trained. The cell below ensures this: It will start training and monitor the training progress if no model is available yet." ] @@ -359,11 +359,11 @@ "source": [ "# Step 7: Run the inference and digest new data into the Platform\n", "\n", - "We will run the inference locally and send some detection frames to the Intel Geti Platform, in order to annotate those and retrain a new model.\n", + "We will run the inference locally and send some detection frames to the Geti Platform, in order to annotate those and retrain a new model.\n", "\n", - "What happens if something new comes in your production system? Different acquisition conditions, lighting, camera, backgrounds. You can connect your production system with Intel Geti Platform in a flexible way through the Intel Geti SDK.\n", + "What happens if something new comes in your production system? Different acquisition conditions, lighting, camera, backgrounds. You can connect your production system with Geti Platform in a flexible way through the Geti SDK.\n", "\n", - "Note: For this use case we will send images back to the Intel Geti Platform when the number of detections per frame will be higher than 1." + "Note: For this use case we will send images back to the Geti Platform when the number of detections per frame will be higher than 1." ] }, { @@ -415,7 +415,7 @@ "source": [ "## Main function for running the inference with video files or USB camera\n", "\n", - "This main function create a video player object to manage video files or USB cameras. By default we play the video in 30 FPS, and every single frame will be analyzed by the model. It also runs the inference using the Intel Geti SDK and create a queue of frames to be sent back to the Intel Geti platform.\n", + "This main function create a video player object to manage video files or USB cameras. By default we play the video in 30 FPS, and every single frame will be analyzed by the model. It also runs the inference using the Geti SDK and create a queue of frames to be sent back to the Geti platform.\n", "\n", "Essentially, the code has four main components:\n", "\n", @@ -495,7 +495,7 @@ "\n", " # ==========================3. Sending images back to the platform======================\n", "\n", - " # if the prediction has more than one label send the image back to Intel Geti Platform\n", + " # if the prediction has more than one label send the image back to Geti Platform\n", " if len(prediction.annotations) > 1:\n", " # image = image_client.upload_image(input_image)\n", " uploader.add_data(input_image)\n", @@ -574,7 +574,7 @@ "id": "2f34900c", "metadata": {}, "source": [ - "This example showcases Intel® Geti™ SDK with a video file, but you can use live camera streams or so in a similar manner, just change the source argument in the previous function to make it equal the the camera source number." + "This example showcases Geti™ SDK with a video file, but you can use live camera streams or so in a similar manner, just change the source argument in the previous function to make it equal the the camera source number." ] }, { @@ -590,7 +590,7 @@ "\n", "| ![image.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/f65c8973-b151-47a7-b291-19bb3c3b8694) | \n", "|:--:| \n", - "| *Interactive annotation with the Intel® Geti™ Platform* |\n", + "| *Interactive annotation with the Geti™ Platform* |\n", "\n", "Alternatively, if you have used the default 'person_car_bike' video that we provided, you can run the cell below to upload some pre-defined annotations for the video to the project. This saves you some time in annotating the frames." ] diff --git a/notebooks/use_cases/103_parking_lot_train2deployment.ipynb b/notebooks/use_cases/103_parking_lot_train2deployment.ipynb index e714cc5e3..18a7b3b86 100644 --- a/notebooks/use_cases/103_parking_lot_train2deployment.ipynb +++ b/notebooks/use_cases/103_parking_lot_train2deployment.ipynb @@ -6,11 +6,11 @@ "metadata": {}, "source": [ "\n", - "# Intelligent car counting with Intel® Geti™ SDK from Training to Deployment\n", + "# Intelligent car counting with Geti™ SDK from Training to Deployment\n", "\n", - "## Smart Car Counting for Efficient Urban Management: Harnessing the Power of Intel Geti Platform, Intel Geti SDK, and OpenVINO Integration\n", + "## Smart Car Counting for Efficient Urban Management: Harnessing the Power of Geti Platform, Geti SDK, and OpenVINO Integration\n", "\n", - "In this comprehensive notebook, we will guide developers through the process of creating a smart car counting system for parking lots using the cutting-edge Intel Geti platform, its SDK, and seamless integration with OpenVINO. We will demonstrate how to train models, manipulate training features, and deploy the solution locally, all while reaping the numerous benefits of OpenVINO's accelerated inferencing capabilities.\n", + "In this comprehensive notebook, we will guide developers through the process of creating a smart car counting system for parking lots using the cutting-edge Geti platform, its SDK, and seamless integration with OpenVINO. We will demonstrate how to train models, manipulate training features, and deploy the solution locally, all while reaping the numerous benefits of OpenVINO's accelerated inferencing capabilities.\n", "\n", "| ![image.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/5dc1d5a3-0ea3-42f0-831e-53489304d44e) | \n", "|:--:| \n", @@ -18,7 +18,7 @@ "\n", "| ![image-7.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/5357bd34-26a7-4f20-b4cb-3b56a9b4ee77) | \n", "|:--:| \n", - "| *Intel® Geti™ Platform* |" + "| *Geti™ Platform* |" ] }, { @@ -26,7 +26,7 @@ "id": "1090003a", "metadata": {}, "source": [ - "Before running this notebook, please make sure you have the Intel Geti SDK installed in your local machine. If not, please follow [these instructions](https://github.com/openvinotoolkit/geti-sdk#installation)." + "Before running this notebook, please make sure you have the Geti SDK installed in your local machine. If not, please follow [these instructions](https://github.com/openvinotoolkit/geti-sdk#installation)." ] }, { @@ -34,7 +34,7 @@ "id": "7bae4a28", "metadata": {}, "source": [ - "In this notebook, we will use the SDK to create a project on the Intel Geti graphics platform, upload videos, download the displays locally, and run the inference by viewing the results on this same notebook." + "In this notebook, we will use the SDK to create a project on the Geti graphics platform, upload videos, download the displays locally, and run the inference by viewing the results on this same notebook." ] }, { @@ -62,7 +62,7 @@ "id": "f97df60a-01e6-4aaa-8013-c7e981485699", "metadata": {}, "source": [ - "# Step 1: Connect with your Intel® Geti™ Instance\n", + "# Step 1: Connect with your Geti™ Instance\n", "\n", "We will connect to the platform first, using the server details from the .env file. We will also create a ProjectClient for the server. If you have doubts, please take a look of the previous work you need to do before to [connect](https://github.com/openvinotoolkit/geti-sdk#connecting-to-the-intel-geti-platform) the SDK and the platform. " ] @@ -99,7 +99,7 @@ "source": [ "# Step 2: Create a project and upload a video for further annotations\n", "\n", - "We will create a new project from scratch and will upload a video using the SDK for further annotations into the Intel Geti Platform. We will create an object detection project for person, bike and card detection. \n", + "We will create a new project from scratch and will upload a video using the SDK for further annotations into the Geti Platform. We will create an object detection project for person, bike and card detection. \n", "\n", "| ![image.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/49dbe60f-4a7b-47dd-a42c-71ad28c93593) | \n", "|:--:| \n", @@ -126,7 +126,7 @@ "\n", "project_client = ProjectClient(session=geti.session, workspace_id=geti.workspace_id) # setting up the project client\n", "\n", - "projects = project_client.list_projects() # listing the projects in the Intel Geti Instance" + "projects = project_client.list_projects() # listing the projects in the Geti Instance" ] }, { @@ -276,15 +276,15 @@ "metadata": {}, "source": [ "# Step 4: Creating annotations\n", - "Once you upload new image or video data, you should open the Intel Geti GUI and create annotations for it. The screenshot below shows an example of the annotator page within Geti.\n", + "Once you upload new image or video data, you should open the Geti GUI and create annotations for it. The screenshot below shows an example of the annotator page within Geti.\n", "\n", "| ![image.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/51ba8173-11a1-4cc5-8e24-2be0989afdf8) | \n", "|:--:| \n", - "| *Annotations within the Intel® Geti™ Platform* |\n", + "| *Annotations within the Geti™ Platform* |\n", "\n", "Alternatively, if you have used the default 'parking-lot' image dataset that we provided, you can run the cell below to upload some pre-defined annotations for the images to the project. This saves you some time in annotating the images.\n", "\n", - "But before to upload the annotations, we need to disable the auto-training option from the Intel Geti server, for avoing auto training when the first 12 annotations have been submitted." + "But before to upload the annotations, we need to disable the auto-training option from the Geti server, for avoing auto training when the first 12 annotations have been submitted." ] }, { @@ -331,9 +331,9 @@ "metadata": {}, "source": [ "# Step 5: Training the model\n", - "Once sufficient annotations have been made, the project is ready for training. Due to the incremental learning mechanism within the Intel Geti platform, training will happen automatically and frequently. Whenever sufficient new annotations have been created, the platform will start a training round. \n", + "Once sufficient annotations have been made, the project is ready for training. Due to the incremental learning mechanism within the Geti platform, training will happen automatically and frequently. Whenever sufficient new annotations have been created, the platform will start a training round. \n", "\n", - "In the next part of the notebook we will deploy the model that was trained, so that we can use it locally to generate predictions. However, before doing so we need to make sure that the project has a model trained. The cell below trigger the training process for all possible algorithms the Intel Geti Platform supports. Only one model is trained at a time for a project, so it will take some time but you could see the differences between architectures, and make the decision about which architecture is better for your use case\n", + "In the next part of the notebook we will deploy the model that was trained, so that we can use it locally to generate predictions. However, before doing so we need to make sure that the project has a model trained. The cell below trigger the training process for all possible algorithms the Geti Platform supports. Only one model is trained at a time for a project, so it will take some time but you could see the differences between architectures, and make the decision about which architecture is better for your use case\n", "\n" ] }, @@ -383,7 +383,7 @@ "source": [ "### Optimize/Quantize your models with OpenVINO\n", "\n", - "OpenVINO helps with the optimization and quantization process, there are multiple options to optimize and quantize the models. On of them is using the Post training Quantization process with POT. For triggering that option on the Intel Geti platform, you can fetch the trained model and then request an optimization job to optimize it with POT. The code in the next cell shows how this is done." + "OpenVINO helps with the optimization and quantization process, there are multiple options to optimize and quantize the models. On of them is using the Post training Quantization process with POT. For triggering that option on the Geti platform, you can fetch the trained model and then request an optimization job to optimize it with POT. The code in the next cell shows how this is done." ] }, { @@ -572,11 +572,11 @@ "source": [ "# Step 7: Run the inference and ingest new data into the Platform\n", "\n", - "We will run the inference locally and send some detection frames to the Intel Geti Platform, in order to annotate those and retrain a new model.\n", + "We will run the inference locally and send some detection frames to the Geti Platform, in order to annotate those and retrain a new model.\n", "\n", - "What happens if something new comes in your production system? Different acquisition conditions, lighting, camera, backgrounds. You can connect your production system with Intel Geti Platform in a flexible way through the Intel Geti SDK.\n", + "What happens if something new comes in your production system? Different acquisition conditions, lighting, camera, backgrounds. You can connect your production system with Geti Platform in a flexible way through the Geti SDK.\n", "\n", - "Note: For this use case we will send images back to the Intel Geti Platform when the number of detections per frame will be higher than 1." + "Note: For this use case we will send images back to the Geti Platform when the number of detections per frame will be higher than 1." ] }, { @@ -607,7 +607,7 @@ "source": [ "## Main function for running the inference with video files or USB camera\n", "\n", - "This main function create a video player object to manage video files or USB cameras. By default we play the video in 30 FPS, and every single frame will be analyzed by the model. It also runs the inference using the Intel Geti SDK and create a queue of frames to be sent back to the Intel Geti platform.\n", + "This main function create a video player object to manage video files or USB cameras. By default we play the video in 30 FPS, and every single frame will be analyzed by the model. It also runs the inference using the Geti SDK and create a queue of frames to be sent back to the Geti platform.\n", "\n", "Essentially, the code has four main components:\n", "\n", @@ -714,7 +714,7 @@ "\n", " # ==========================3. Sending images back to the platform======================\n", "\n", - " # if the prediction has more than one label send the image back to Intel Geti Platform\n", + " # if the prediction has more than one label send the image back to Geti Platform\n", " if len(prediction.annotations) == 1:\n", " for annotation in prediction.annotations:\n", " for label in annotation.labels:\n", @@ -825,7 +825,7 @@ "id": "2f34900c", "metadata": {}, "source": [ - "This example showcases Intel® Geti™ SDK with a video file, but you can use live camera streams or so in a similar manner, just change the source argument in the previous function to make it equal the the camera source number." + "This example showcases Geti™ SDK with a video file, but you can use live camera streams or so in a similar manner, just change the source argument in the previous function to make it equal the the camera source number." ] }, { @@ -841,7 +841,7 @@ "\n", "| ![image.png](https://github.com/openvinotoolkit/geti-sdk/assets/76463150/e48e98d1-37d6-4989-90b5-49ac106997dc)) | \n", "|:--:| \n", - "| *Interactive annotation with the Intel® Geti™ Platform* |\n", + "| *Interactive annotation with the Geti™ Platform* |\n", "\n", "Alternatively, if you have used the default 'person_car_bike' video that we provided, you can run the cell below to upload some pre-defined annotations for the video to the project. This saves you some time in annotating the frames." ] diff --git a/notebooks/use_cases/utils/upload.py b/notebooks/use_cases/utils/upload.py index 4f70a001e..12f4c3c6e 100644 --- a/notebooks/use_cases/utils/upload.py +++ b/notebooks/use_cases/utils/upload.py @@ -25,7 +25,7 @@ class Uploader: """ - Upload images to Intel Geti Platform using threading. + Upload images to Geti Platform using threading. :param num_worker_threads: Number of workers to use for the uploading :param image_client: ImageClient instance that will be used to upload the images @@ -45,7 +45,7 @@ def __init__(self, num_worker_threads: int, image_client: ImageClient) -> None: def upload_image(self, image: np.ndarray | str | os.PathLike): """ - Upload image to the Intel Geti project + Upload image to the Geti project :param image: Image to upload """ diff --git a/pyproject.toml b/pyproject.toml index 685f14cc1..2af4280a9 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "hatchling.build" [project] name = "geti-sdk" -description = "Software Development Kit for the Intel® Geti™ platform" +description = "Software Development Kit for the Geti™ platform" authors = [ {name = "Intel Corporation"} ] diff --git a/tests/README.md b/tests/README.md index d8ccaefe2..05fa33476 100644 --- a/tests/README.md +++ b/tests/README.md @@ -1,7 +1,7 @@ -This directory contains the test suite for the Intel® Geti™ SDK. The tests are grouped +This directory contains the test suite for the Geti™ SDK. The tests are grouped into two categories: -1. **Pre-merge tests** These are executed for every Pull Request to the Intel® Geti™ +1. **Pre-merge tests** These are executed for every Pull Request to the Geti™ SDK `main` branch. The suite contains both integration and unit tests, the main focus being the integration tests. The test code can be found in the [pre-merge](pre-merge) folder. @@ -16,7 +16,7 @@ into two categories: The integration tests for the SDK leverage the recording of HTTP requests and responses, relying on the VCR.py package. All integration tests are defined in the [pre-merge/integration](pre-merge/integration) directory. By default, the tests are run -in offline mode, meaning that no actual Intel® Geti™ server is needed and no real +in offline mode, meaning that no actual Geti™ server is needed and no real http requests are being made during testing. All requests are intercepted, and a previously recorded response is returned. The recorded interactions can be found in [fixtures/cassettes](fixtures/cassettes). @@ -31,9 +31,9 @@ integration testing. # Nightly test suite The nightly tests are defined in the [nightly](nightly) directory. They can only be run in -`ONLINE` mode, meaning that a live Intel® Geti™ server is required to run against them. The +`ONLINE` mode, meaning that a live Geti™ server is required to run against them. The nightly tests need to be run using a `online.ini` file that contains the host name and -login details for the Intel® Geti™ server to run the tests against (see section +login details for the Geti™ server to run the tests against (see section [Running the tests](#running-the-tests) below). # Running the tests @@ -48,11 +48,11 @@ can be run in `ONLINE` or `RECORD` mode. The simplest way to change modes is to define a custom pytest configuration file for each mode, as explained below: ### Online mode -If you want to run the test suite against a live Intel® Geti™ server (for example to make sure -that the SDK data models are still up to date with the Intel® Geti™ REST contracts), the tests +If you want to run the test suite against a live Geti™ server (for example to make sure +that the SDK data models are still up to date with the Geti™ REST contracts), the tests can be executed in `ONLINE` mode. To do so, define a file `online.ini` in the `tests` directory. This file should have similar content to the existing `offline.ini`, but -with the Intel® Geti™ server hostname and login details set appropriately: +with the Geti™ server hostname and login details set appropriately: > ```shell > [pytest] @@ -81,10 +81,10 @@ Once you created the custom `online.ini` or `record.ini` configurations, you can the tests using `pytest -c online.ini ./pre-merge`. This will execute the tests in online mode. -### Tests Intel® Geti™ SDK against the previous version of Intel® Geti™ server. -You can run the test suite against a legacy version of Intel® Geti™ server. +### Tests Geti™ SDK against the previous version of Geti™ server. +You can run the test suite against a legacy version of Geti™ server. - In `ONLINE` mode Simply assign the `GETI_HOST` variable with the legacy server’s address. - In `OFFLINE` and `RECORD` modes one can set the `GETI_PLATFORM_VERSION` variable to `LEGACY` within `offline.ini` or `record.ini` correspondingly, thus utilizing the pre-recorded cassettes from the prior server release for testing. -> **_NOTE:_** Currently, Intel® Geti™ 1.8 is considered as the legacy release. +> **_NOTE:_** Currently, Geti™ 1.8 is considered as the legacy release. diff --git a/tests/helpers/datumaro_annotation_reader/datumaro_annotation_reader.py b/tests/helpers/datumaro_annotation_reader/datumaro_annotation_reader.py index 02f77307d..b6e9f25a9 100644 --- a/tests/helpers/datumaro_annotation_reader/datumaro_annotation_reader.py +++ b/tests/helpers/datumaro_annotation_reader/datumaro_annotation_reader.py @@ -172,7 +172,7 @@ def get_data( (e.g. width, height) about the media item to upload the annotation for :param preserve_shape_for_global_labels: False to convert shapes for global tasks to full rectangles (required for classification like tasks in - Intel® Geti™ projects), True to preserve such shapes. This parameter + Geti™ projects), True to preserve such shapes. This parameter should be: - False when uploading annotations to a single task project @@ -194,7 +194,7 @@ def get_data( try: label_name = self.datum_label_map[annotation.label] except KeyError: - # Label is not in the Intel® Geti™ project labels, move on to next + # Label is not in the Geti™ project labels, move on to next # annotation for this dataset item. continue diff --git a/tests/helpers/datumaro_annotation_reader/datumaro_dataset.py b/tests/helpers/datumaro_annotation_reader/datumaro_dataset.py index 56a3f8ca0..32094203d 100644 --- a/tests/helpers/datumaro_annotation_reader/datumaro_dataset.py +++ b/tests/helpers/datumaro_annotation_reader/datumaro_dataset.py @@ -40,7 +40,7 @@ class DatumaroDataset: """ Wrapper for interacting with the datumaro dataset, contains some example functions for dataset operations that can be carried out prior to importing the - dataset into an Intel® Geti™ project. + dataset into an Geti™ project. """ def __init__(self, dataset_format: str, dataset_path: str): @@ -61,7 +61,7 @@ def __init__(self, dataset_format: str, dataset_path: str): def prepare_dataset(self, task_type: TaskType, previous_task_type: TaskType | None = None) -> Dataset: """ - Prepare the dataset for uploading to Intel Geti. + Prepare the dataset for uploading to Geti. :param task_type: TaskType to prepare the dataset for :param previous_task_type: Optional type of the (trainable) task preceding diff --git a/tests/helpers/project_helpers.py b/tests/helpers/project_helpers.py index 7d9297bf3..61302687f 100644 --- a/tests/helpers/project_helpers.py +++ b/tests/helpers/project_helpers.py @@ -48,7 +48,7 @@ def get_or_create_annotated_project_for_test_class( :param annotation_requirements_first_training: The required amount of annotations for first training. :param keypoint_structure: The structure of the keypoints to be used for the project, represented as a graph of nodes and edges. - :return: Project instance corresponding to the project on the Intel® Geti™ server + :return: Project instance corresponding to the project on the Geti™ server """ project_exists = project_service.has_project labels = [reader.get_all_label_names() for reader in annotation_readers] diff --git a/tests/pre-merge/unit/test_platform_version.py b/tests/pre-merge/unit/test_platform_version.py index b54208604..4667d0460 100644 --- a/tests/pre-merge/unit/test_platform_version.py +++ b/tests/pre-merge/unit/test_platform_version.py @@ -32,7 +32,7 @@ def test_init(self) -> None: def test_comparison(self) -> None: """ Test parsing the version from a version string, for different release versions - of the Intel Geti platform. Also test comparisons between versions + of the Geti platform. Also test comparisons between versions """ assert GETI_10_VERSION < GETI_11_VERSION assert GETI_11_VERSION >= GETI_10_VERSION From 8a48c546765800cc1cf06a90106d62f9d88e2d23 Mon Sep 17 00:00:00 2001 From: jcchr Date: Wed, 27 Aug 2025 13:49:11 +0200 Subject: [PATCH 2/7] format corrections --- geti_sdk/data_models/predictions.py | 3 +-- geti_sdk/geti.py | 4 +--- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/geti_sdk/data_models/predictions.py b/geti_sdk/data_models/predictions.py index c662ba972..c5f05818a 100644 --- a/geti_sdk/data_models/predictions.py +++ b/geti_sdk/data_models/predictions.py @@ -81,8 +81,7 @@ def get_data(self, session: GetiSession) -> bytes: self.data = response.content else: raise ValueError( - f"Unable to retrieve data for result medium {self}, received " - f"response {response} from Geti™ server." + f"Unable to retrieve data for result medium {self}, received response {response} from Geti™ server." ) return self.data diff --git a/geti_sdk/geti.py b/geti_sdk/geti.py index b46a3d300..1a9e3958a 100644 --- a/geti_sdk/geti.py +++ b/geti_sdk/geti.py @@ -267,9 +267,7 @@ def get_project( """ project = self.project_client.get_project(project_name=project_name, project_id=project_id, project=project) if project is None: - raise KeyError( - f"Project '{project_name}' was not found in the current workspace on the Geti™ server." - ) + raise KeyError(f"Project '{project_name}' was not found in the current workspace on the Geti™ server.") return project def download_project_data( From 80fb1c11ed5e1efa7ebf77f9ba2ff15f0ed54e95 Mon Sep 17 00:00:00 2001 From: jcchr Date: Tue, 16 Sep 2025 08:47:52 +0200 Subject: [PATCH 3/7] multiworkspace support --- geti_sdk/utils/workspace_helpers.py | 1 + tests/conftest.py | 11 ++++++- tests/fixtures/geti.py | 47 +++++++++++++++++++++-------- 3 files changed, 46 insertions(+), 13 deletions(-) diff --git a/geti_sdk/utils/workspace_helpers.py b/geti_sdk/utils/workspace_helpers.py index e0fb93391..7a51c98e1 100644 --- a/geti_sdk/utils/workspace_helpers.py +++ b/geti_sdk/utils/workspace_helpers.py @@ -19,6 +19,7 @@ class MultipleWorkspacesException(Exception): """Exception raised when multiple workspaces are available thus it is not possible to automatically select one.""" def __init__(self, workspaces_list: list) -> None: + self.available_workspaces = workspaces_list ws_ids_and_names = [(ws["id"], ws["name"]) for ws in workspaces_list] error_message = ( f"Multiple workspaces are available; please select one and provide its id through the 'workspace_id' " diff --git a/tests/conftest.py b/tests/conftest.py index 7c117f7c0..ddc9d12fa 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -23,6 +23,7 @@ from geti_sdk import Geti from geti_sdk.http_session import ServerCredentialConfig, ServerTokenConfig +from geti_sdk.utils.workspace_helpers import MultipleWorkspacesException from tests.helpers.project_helpers import remove_all_test_projects from .helpers import SdkTestMode, get_sdk_fixtures, replace_unique_entries_in_cassettes @@ -174,7 +175,15 @@ def _get_geti_instance() -> Geti: proxies = {"http": GETI_HTTP_PROXY, "https": GETI_HTTPS_PROXY} else: proxies = None - return Geti(host=HOST, **auth_params, proxies=proxies, verify_certificate=False) + + # handle multiple workspaces + try: + return Geti(host=HOST, **auth_params, proxies=proxies, verify_certificate=False) + except MultipleWorkspacesException as exe: + workspaces_list = exe.ws_ids_and_names + workspace_id = workspaces_list[0][0] + print(f"workspace id {workspace_id}") + return Geti(host=HOST, **auth_params, proxies=proxies, verify_certificate=False, workspace_id=workspace_id) def pytest_sessionstart(session: Session) -> None: diff --git a/tests/fixtures/geti.py b/tests/fixtures/geti.py index 5727bcb60..d7d29eaea 100644 --- a/tests/fixtures/geti.py +++ b/tests/fixtures/geti.py @@ -16,6 +16,7 @@ from geti_sdk import Geti from geti_sdk.http_session import GetiSession, ServerCredentialConfig, ServerTokenConfig +from geti_sdk.utils.workspace_helpers import MultipleWorkspacesException from tests.helpers.constants import CASSETTE_EXTENSION, DUMMY_PASSWORD, DUMMY_USER @@ -56,12 +57,23 @@ def fxt_geti(fxt_vcr, fxt_server_config: ServerTokenConfig | ServerCredentialCon } else: auth_params = {"token": fxt_server_config.token} - yield Geti( - host=fxt_server_config.host, - verify_certificate=fxt_server_config.has_valid_certificate, - proxies=fxt_server_config.proxies, - **auth_params, - ) + try: + yield Geti( + host=fxt_server_config.host, + verify_certificate=fxt_server_config.has_valid_certificate, + proxies=fxt_server_config.proxies, + **auth_params, + ) + except MultipleWorkspacesException as exe: + workspaces_list = exe.available_workspaces + workspace_id = workspaces_list[0]["id"] + yield Geti( + host=fxt_server_config.host, + verify_certificate=fxt_server_config.has_valid_certificate, + proxies=fxt_server_config.proxies, + **auth_params, + workspace_id=workspace_id, + ) @pytest.fixture(scope="module") @@ -75,9 +87,20 @@ def fxt_geti_no_vcr( } else: auth_params = {"token": fxt_server_config.token} - yield Geti( - host=fxt_server_config.host, - proxies=fxt_server_config.proxies, - **auth_params, - verify_certificate=fxt_server_config.has_valid_certificate, - ) + try: + yield Geti( + host=fxt_server_config.host, + proxies=fxt_server_config.proxies, + **auth_params, + verify_certificate=fxt_server_config.has_valid_certificate, + ) + except MultipleWorkspacesException as exe: + workspaces_list = exe.available_workspaces + workspace_id = workspaces_list[0]["id"] + yield Geti( + host=fxt_server_config.host, + proxies=fxt_server_config.proxies, + **auth_params, + verify_certificate=fxt_server_config.has_valid_certificate, + workspace_id=workspace_id, +) From 511b8bfb11248204fe409ab3fdcaaaa7a237637d Mon Sep 17 00:00:00 2001 From: jcchr Date: Tue, 16 Sep 2025 09:06:21 +0200 Subject: [PATCH 4/7] modification of establishing a workspace for tests --- tests/conftest.py | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/tests/conftest.py b/tests/conftest.py index ddc9d12fa..67c0f757c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -180,9 +180,8 @@ def _get_geti_instance() -> Geti: try: return Geti(host=HOST, **auth_params, proxies=proxies, verify_certificate=False) except MultipleWorkspacesException as exe: - workspaces_list = exe.ws_ids_and_names - workspace_id = workspaces_list[0][0] - print(f"workspace id {workspace_id}") + workspaces_list = exe.available_workspaces + workspace_id = workspaces_list[0]["id"] return Geti(host=HOST, **auth_params, proxies=proxies, verify_certificate=False, workspace_id=workspace_id) From 8290887efc77a1bfa372712281932c2d66d3a54f Mon Sep 17 00:00:00 2001 From: jcchr Date: Tue, 16 Sep 2025 09:14:57 +0200 Subject: [PATCH 5/7] format correction --- tests/fixtures/geti.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tests/fixtures/geti.py b/tests/fixtures/geti.py index d7d29eaea..4778bc48f 100644 --- a/tests/fixtures/geti.py +++ b/tests/fixtures/geti.py @@ -103,4 +103,4 @@ def fxt_geti_no_vcr( **auth_params, verify_certificate=fxt_server_config.has_valid_certificate, workspace_id=workspace_id, -) + ) From 3590e865d6db8e1b7a675a9691aa12db173eb006 Mon Sep 17 00:00:00 2001 From: jcchr Date: Tue, 4 Nov 2025 12:17:28 +0100 Subject: [PATCH 6/7] modification of a logo --- README.md | 2 +- docs/geti-logo.png | Bin 77138 -> 0 bytes 2 files changed, 1 insertion(+), 1 deletion(-) delete mode 100644 docs/geti-logo.png diff --git a/README.md b/README.md index 96245cf4d..b80fa7ed7 100644 --- a/README.md +++ b/README.md @@ -4,7 +4,7 @@ Geti™ enables anyone from domain experts to data scientists to rapidly develop production-ready AI models. diff --git a/docs/geti-logo.png b/docs/geti-logo.png deleted file mode 100644 index d87b6b938dcfe0da472ec5eeed46102ba26f66b1..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 77138 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 Date: Thu, 6 Nov 2025 13:12:20 +0100 Subject: [PATCH 7/7] geti version in badge updated --- README.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/README.md b/README.md index 891f52f63..58be1e1e0 100644 --- a/README.md +++ b/README.md @@ -13,7 +13,7 @@
[![python](https://img.shields.io/badge/python-3.10%2B-green)]() -![Geti](https://img.shields.io/badge/Intel%C2%AE%20Geti%E2%84%A2-2.12-blue?link=https%3A%2F%2Fgeti.intel.com%2F) +![Geti](https://img.shields.io/badge/Intel%C2%AE%20Geti%E2%84%A2-2.13-blue?link=https%3A%2F%2Fgeti.intel.com%2F) [![openvino](https://img.shields.io/badge/openvino-2025.2-purple)](https://github.com/openvinotoolkit/openvino) ![Pre-merge Tests Status](https://img.shields.io/github/actions/workflow/status/open-edge-platform/geti-sdk/pre-merge-tests.yml?label=pre-merge%20tests&link=https%3A%2F%2Fgithub.com%2Fopen-edge-platform%2Fgeti-sdk%2Factions%2Fworkflows%2Fpre-merge-tests.yml)