diff --git a/libs/labelbox/src/labelbox/exceptions.py b/libs/labelbox/src/labelbox/exceptions.py index 644fac0ab..048ca0757 100644 --- a/libs/labelbox/src/labelbox/exceptions.py +++ b/libs/labelbox/src/labelbox/exceptions.py @@ -44,7 +44,7 @@ def __init__(self, db_object_type=None, params=None, message=None): super().__init__(message) else: super().__init__("Resource '%s' not found for params: %r" % - (db_object_type.type_name(), params)) + (db_object_type.type_name(), params)) self.db_object_type = db_object_type self.params = params @@ -144,6 +144,11 @@ class OperationNotAllowedException(Exception): pass +class OperationNotSupportedException(Exception): + """Raised when sdk does not support requested operation""" + pass + + class ConfidenceNotSupportedException(Exception): """Raised when confidence is specified for unsupported annotation type""" diff --git a/libs/labelbox/src/labelbox/orm/db_object.py b/libs/labelbox/src/labelbox/orm/db_object.py index 326043d32..c4f87eac5 100644 --- a/libs/labelbox/src/labelbox/orm/db_object.py +++ b/libs/labelbox/src/labelbox/orm/db_object.py @@ -1,10 +1,11 @@ +from dataclasses import dataclass from datetime import datetime, timezone from functools import wraps import logging import json from labelbox import utils -from labelbox.exceptions import InvalidQueryError, InvalidAttributeError +from labelbox.exceptions import InvalidQueryError, InvalidAttributeError, OperationNotSupportedException from labelbox.orm import query from labelbox.orm.model import Field, Relationship, Entity from labelbox.pagination import PaginatedCollection @@ -123,6 +124,7 @@ def __init__(self, source, relationship, value=None): self.supports_sorting = True self.filter_on_id = True self.value = value + self.config = relationship.config def __call__(self, *args, **kwargs): """ Forwards the call to either `_to_many` or `_to_one` methods, @@ -191,6 +193,10 @@ def connect(self, other): def disconnect(self, other): """ Disconnects source object of this manager from the `other` object. """ + if not self.config.disconnect_supported: + raise OperationNotSupportedException( + "Disconnect is not supported for this relationship") + query_string, params = query.update_relationship( self.source, other, self.relationship, "disconnect") self.source.client.execute(query_string, params) diff --git a/libs/labelbox/src/labelbox/orm/model.py b/libs/labelbox/src/labelbox/orm/model.py index f3afa174e..5720b67cc 100644 --- a/libs/labelbox/src/labelbox/orm/model.py +++ b/libs/labelbox/src/labelbox/orm/model.py @@ -1,3 +1,4 @@ +from dataclasses import dataclass from enum import Enum, auto from typing import Dict, List, Union, Any, Type, TYPE_CHECKING @@ -219,6 +220,10 @@ class Relationship: """ + @dataclass + class Config: + disconnect_supported: bool = True + class Type(Enum): ToOne = auto() ToMany = auto() @@ -238,12 +243,14 @@ def __init__(self, name=None, graphql_name=None, cache=False, - deprecation_warning=None): + deprecation_warning=None, + config=Config()): self.relationship_type = relationship_type self.destination_type_name = destination_type_name self.filter_deleted = filter_deleted self.cache = cache self.deprecation_warning = deprecation_warning + self.config = config if name is None: name = utils.snake_case(destination_type_name) + ( diff --git a/libs/labelbox/src/labelbox/schema/project.py b/libs/labelbox/src/labelbox/schema/project.py index 761d0e391..24e01442a 100644 --- a/libs/labelbox/src/labelbox/schema/project.py +++ b/libs/labelbox/src/labelbox/schema/project.py @@ -132,7 +132,9 @@ class Project(DbObject, Updateable, Deletable): # Relationships created_by = Relationship.ToOne("User", False, "created_by") organization = Relationship.ToOne("Organization", False) - labeling_frontend = Relationship.ToOne("LabelingFrontend") + labeling_frontend = Relationship.ToOne( + "LabelingFrontend", + config=Relationship.Config(disconnect_supported=False)) labeling_frontend_options = Relationship.ToMany( "LabelingFrontendOptions", False, "labeling_frontend_options") labeling_parameter_overrides = Relationship.ToMany( diff --git a/libs/labelbox/tests/integration/test_labeling_frontend.py b/libs/labelbox/tests/integration/test_labeling_frontend.py index 59ab0b924..d13871372 100644 --- a/libs/labelbox/tests/integration/test_labeling_frontend.py +++ b/libs/labelbox/tests/integration/test_labeling_frontend.py @@ -1,6 +1,8 @@ -from labelbox import LabelingFrontend import pytest +from labelbox import LabelingFrontend +from labelbox.exceptions import OperationNotSupportedException + def test_get_labeling_frontends(client): filtered_frontends = list( @@ -18,5 +20,5 @@ def test_labeling_frontend_connecting_to_project(project): project.labeling_frontend.connect(default_labeling_frontend) assert project.labeling_frontend() == default_labeling_frontend - project.labeling_frontend.disconnect(default_labeling_frontend) - assert project.labeling_frontend() == None + with pytest.raises(OperationNotSupportedException): + project.labeling_frontend.disconnect(default_labeling_frontend)