diff --git a/changelog.d/20241209_143843_30907815+rjmello_globus_sdk_compute_client_sc_36127.rst b/changelog.d/20241209_143843_30907815+rjmello_globus_sdk_compute_client_sc_36127.rst new file mode 100644 index 000000000..973917e4e --- /dev/null +++ b/changelog.d/20241209_143843_30907815+rjmello_globus_sdk_compute_client_sc_36127.rst @@ -0,0 +1,7 @@ +Deprecated +^^^^^^^^^^ + +- The ``WebClient`` class and ``Client.web_client`` attribute have been deprecated. + Please use the ``ComputeClient``, ``ComputeClientV2``, and ``ComputeClientV3`` + classes from the `Globus Python SDK `_ + to interact directly with the Globus Compute API. diff --git a/compute_endpoint/tests/conftest.py b/compute_endpoint/tests/conftest.py index 6c5776a09..12333ff55 100644 --- a/compute_endpoint/tests/conftest.py +++ b/compute_endpoint/tests/conftest.py @@ -87,6 +87,7 @@ def get_web_client(self, *, base_url: str | None = None) -> WebClient: return WebClient( base_url="https://compute.api.globus.org", authorizer=globus_sdk.NullAuthorizer(), + _deprecation_warning=False ) diff --git a/compute_sdk/globus_compute_sdk/sdk/client.py b/compute_sdk/globus_compute_sdk/sdk/client.py index 8c757ceb6..b48d133bd 100644 --- a/compute_sdk/globus_compute_sdk/sdk/client.py +++ b/compute_sdk/globus_compute_sdk/sdk/client.py @@ -129,7 +129,7 @@ def __init__( elif login_manager: self.login_manager = login_manager self.auth_client = login_manager.get_auth_client() - self.web_client = self.login_manager.get_web_client( + self._web_client = self.login_manager.get_web_client( base_url=self.web_service_address ) self._compute_web_client = _ComputeWebClient( @@ -138,7 +138,11 @@ def __init__( else: self.app = app if app else get_globus_app(environment=environment) self.auth_client = ComputeAuthClient(app=self.app) - self.web_client = WebClient(base_url=self.web_service_address, app=self.app) + self._web_client = WebClient( + base_url=self.web_service_address, + app=self.app, + _deprecation_warning=False, + ) self._compute_web_client = _ComputeWebClient( base_url=self.web_service_address, app=self.app ) @@ -153,6 +157,20 @@ def __init__( if do_version_check: self.version_check() + @property + def web_client(self): + warnings.warn( + "The 'Client.web_client' attribute is deprecated" + " and will be removed in a future release.", + DeprecationWarning, + stacklevel=2, + ) + return self._web_client + + @web_client.setter + def web_client(self, val: WebClient): + self._web_client = val + def version_check(self, endpoint_version: str | None = None) -> None: """Check this client version meets the service's minimum supported version. diff --git a/compute_sdk/globus_compute_sdk/sdk/login_manager/authorizer_login_manager.py b/compute_sdk/globus_compute_sdk/sdk/login_manager/authorizer_login_manager.py index f94576103..0f2a22332 100644 --- a/compute_sdk/globus_compute_sdk/sdk/login_manager/authorizer_login_manager.py +++ b/compute_sdk/globus_compute_sdk/sdk/login_manager/authorizer_login_manager.py @@ -36,6 +36,7 @@ def get_web_client( base_url=base_url, app_name=app_name, authorizer=self.authorizers[ComputeScopes.resource_server], + _deprecation_warning=False, ) def ensure_logged_in(self): diff --git a/compute_sdk/globus_compute_sdk/sdk/login_manager/manager.py b/compute_sdk/globus_compute_sdk/sdk/login_manager/manager.py index 417fade4f..4c83d5833 100644 --- a/compute_sdk/globus_compute_sdk/sdk/login_manager/manager.py +++ b/compute_sdk/globus_compute_sdk/sdk/login_manager/manager.py @@ -170,4 +170,5 @@ def get_web_client( base_url=base_url, app_name=app_name, authorizer=self._get_authorizer(ComputeScopes.resource_server), + _deprecation_warning=False, ) diff --git a/compute_sdk/globus_compute_sdk/sdk/web_client.py b/compute_sdk/globus_compute_sdk/sdk/web_client.py index 8edacc1a0..5b7b2de9d 100644 --- a/compute_sdk/globus_compute_sdk/sdk/web_client.py +++ b/compute_sdk/globus_compute_sdk/sdk/web_client.py @@ -17,7 +17,6 @@ from globus_compute_sdk.sdk.utils.uuid_like import UUID_LIKE_T from globus_compute_sdk.serialize import ComputeSerializer from globus_compute_sdk.version import __version__ -from globus_sdk import GlobusAPIError, GlobusApp, Scope from .auth.scopes import ComputeScopes @@ -104,20 +103,29 @@ class WebClient(globus_sdk.BaseClient): # it does not have any other effects service_name: str = "funcx" # use the Globus Compute-specific error class - error_class = GlobusAPIError + error_class = globus_sdk.GlobusAPIError scopes = ComputeScopes - default_scope_requirements = [Scope(ComputeScopes.all)] + default_scope_requirements = [globus_sdk.Scope(ComputeScopes.all)] def __init__( self, *, environment: t.Optional[str] = None, base_url: t.Optional[str] = None, - app: t.Optional[GlobusApp] = None, + app: t.Optional[globus_sdk.GlobusApp] = None, app_name: t.Optional[str] = None, + _deprecation_warning: bool = True, **kwargs, ): + if _deprecation_warning: + warnings.warn( + "The 'WebClient' class is deprecated." + " Please use globus_sdk.ComputeClient instead.", + category=DeprecationWarning, + stacklevel=2, + ) + if base_url is None: base_url = get_web_service_url(environment) base_url = remove_url_path(base_url) diff --git a/compute_sdk/tests/integration/test_web_client_exceptions.py b/compute_sdk/tests/integration/test_web_client_exceptions.py index 2dfe72263..12fc04344 100644 --- a/compute_sdk/tests/integration/test_web_client_exceptions.py +++ b/compute_sdk/tests/integration/test_web_client_exceptions.py @@ -21,7 +21,11 @@ def mocked_responses(): @pytest.fixture def client(): # for the default test client, set a fake URL and disable retries - return WebClient(base_url="https://api.funcx", transport_params={"max_retries": 0}) + return WebClient( + base_url="https://api.funcx", + transport_params={"max_retries": 0}, + _deprecation_warning=False, + ) @pytest.mark.parametrize("http_status", [400, 500]) diff --git a/compute_sdk/tests/unit/test_client.py b/compute_sdk/tests/unit/test_client.py index 358185a4f..76e8bf718 100644 --- a/compute_sdk/tests/unit/test_client.py +++ b/compute_sdk/tests/unit/test_client.py @@ -36,9 +36,11 @@ def gcc(): do_version_check=False, login_manager=mock.Mock(spec=LoginManager), ) - _gcc._compute_web_client = mock.Mock(spec=_ComputeWebClient) - _gcc._compute_web_client.v2 = mock.Mock(spec=ComputeClientV2) - _gcc._compute_web_client.v3 = mock.Mock(spec=ComputeClientV3) + _gcc._compute_web_client = mock.Mock( + spec=_ComputeWebClient, + v2=mock.Mock(spec=ComputeClientV2), + v3=mock.Mock(spec=ComputeClientV3), + ) yield _gcc @@ -733,7 +735,7 @@ def test_client_handles_globus_app( assert client.web_client is mock_web_client.return_value assert client._compute_web_client is mock_compute_web_client.return_value mock_web_client.assert_called_once_with( - base_url=client.web_service_address, app=mock_app + base_url=client.web_service_address, app=mock_app, _deprecation_warning=False ) mock_compute_web_client.assert_called_once_with( base_url=client.web_service_address, app=mock_app @@ -766,3 +768,11 @@ def test_client_logout_with_login_manager(): client = gc.Client(do_version_check=False, login_manager=mock_lm) client.logout() assert mock_lm.logout.called + + +def test_web_client_deprecated(): + gcc = gc.Client(do_version_check=False) + with pytest.warns(DeprecationWarning) as record: + assert gcc.web_client, "Client.web_client needed for backward compatibility" + msg = "'Client.web_client' attribute is deprecated" + assert any(msg in str(r.message) for r in record) diff --git a/compute_sdk/tests/unit/test_web_client.py b/compute_sdk/tests/unit/test_web_client.py index 51d8a6905..6b0e20060 100644 --- a/compute_sdk/tests/unit/test_web_client.py +++ b/compute_sdk/tests/unit/test_web_client.py @@ -30,12 +30,23 @@ def mocked_responses(): @pytest.fixture def client(): # for the default test client, set a fake URL and disable retries - return WebClient(base_url=_BASE_URL, transport_params={"max_retries": 0}) + return WebClient( + base_url=_BASE_URL, + transport_params={"max_retries": 0}, + _deprecation_warning=False, + ) + + +def test_web_client_deprecated(): + with pytest.warns(DeprecationWarning) as record: + WebClient(base_url="blah") + msg = "'WebClient' class is deprecated" + assert any(msg in str(r.message) for r in record) def test_web_client_can_set_explicit_base_url(): - c1 = WebClient(base_url="https://foo.example.com/") - c2 = WebClient(base_url="https://bar.example.com/") + c1 = WebClient(base_url="https://foo.example.com/", _deprecation_warning=False) + c2 = WebClient(base_url="https://bar.example.com/", _deprecation_warning=False) assert c1.base_url == "https://foo.example.com/" assert c2.base_url == "https://bar.example.com/" @@ -64,7 +75,7 @@ def test_get_version_service_param(client, service_param): @pytest.mark.parametrize("app_name", [None, str(uuid.uuid4())]) def test_app_name_value(app_name: str | None): - wc = WebClient(base_url=_BASE_URL, app_name=app_name) + wc = WebClient(base_url=_BASE_URL, app_name=app_name, _deprecation_warning=False) if app_name is None: assert wc.app_name == f"globus-compute-sdk-{__version__}" else: diff --git a/smoke_tests/tests/conftest.py b/smoke_tests/tests/conftest.py index 4794d1f6f..0c21fca48 100644 --- a/smoke_tests/tests/conftest.py +++ b/smoke_tests/tests/conftest.py @@ -149,7 +149,7 @@ def get_auth_client(self) -> AuthClient: return AuthClient(authorizer=auth_authorizer) def get_web_client(self, *, base_url: str | None = None) -> WebClient: - return WebClient(base_url=base_url, authorizer=funcx_authorizer) + return WebClient(base_url=base_url, authorizer=funcx_authorizer, _deprecation_warning=False) login_manager = TestsuiteLoginManager()