From 34f45f9899529782198f08638d580599bed2c524 Mon Sep 17 00:00:00 2001 From: Adrian Damian Date: Thu, 28 Mar 2024 12:09:38 -0700 Subject: [PATCH] Streamlined cavern calls --- vos/vos/tests/test_vos.py | 11 +++++++++++ vos/vos/vos.py | 16 +++++++++++----- 2 files changed, 22 insertions(+), 5 deletions(-) diff --git a/vos/vos/tests/test_vos.py b/vos/vos/tests/test_vos.py index c7c8bf44..56d006ad 100644 --- a/vos/vos/tests/test_vos.py +++ b/vos/vos/tests/test_vos.py @@ -149,6 +149,7 @@ def test_get_node_url(): response.headers = {'Location': transfer_url} mock_session = Mock(spec=requests.Session, get=Mock(return_value=response)) client.get_session = Mock(return_value=mock_session) + client._fs_type = False assert transfer_url == \ client.get_node_url('vos://cadc.nrc.ca!vospace/auser', view='header') @@ -478,11 +479,21 @@ def is_remote_file(uri): response.iter_content.return_value = BytesIO(file_content) session.get.return_value = response test_client.get_session = Mock(return_value=session) + # client must be a vault client + test_client._fs_type = False test_client.copy('{}{}'.format(vospaceLocation, '[1][10:60]'), osLocation) get_node_url_mock.assert_called_once_with( vospaceLocation, method='GET', cutout='[1][10:60]', view='cutout') + # test cavern does not support SODA operations + test_client._fs_type = True + with pytest.raises(ValueError): + test_client.copy('{}{}'.format(vospaceLocation, '[1][10:60]'), osLocation) + with pytest.raises(ValueError): + test_client.copy(vospaceLocation, osLocation, head=True) + + test_client._fs_type = False # copy to vospace when md5 sums are the same -> only update occurs get_node_url_mock.reset_mock() computed_md5_mock.reset_mock() diff --git a/vos/vos/vos.py b/vos/vos/vos.py index 499e84a1..529e0869 100644 --- a/vos/vos/vos.py +++ b/vos/vos/vos.py @@ -1526,6 +1526,7 @@ def __init__(self, vospace_certfile=None, Client.VOSPACE_CERTFILE or vospace_certfile self.vospace_token = vospace_token self.insecure = insecure + self._fs_type = True # True - file system type (cavern), False - db type (vault) def glob(self, pathname): """Return a list of paths matching a pathname pattern. @@ -1690,6 +1691,10 @@ def get_endpoints(self, uri): else: raise OSError('No scheme in {}'.format(uri)) + # following is a CADC hack as others can deploy the services under different + # resource IDs + if 'vault' in resource_id: + self._fs_type = False if resource_id not in self._endpoints: try: self._endpoints[resource_id] = EndPoints( @@ -1844,6 +1849,8 @@ def copy(self, source, destination, send_md5=False, disposition=False, get_urls = [] files_url = None + if self._fs_type and (cutout or view == 'header'): + raise ValueError('cavern/arc service does not support cutouts or header operations') if new_vos: files_url = self.get_node_url(source, method='GET', cutout=cutout, view=view) @@ -2419,6 +2426,10 @@ def _get(self, uri): if not file_path: return None files_url = '{}{}'.format(files_ep, file_path) + if self._fs_type: + # files_url contains the bytes + return files_url + # remaining is for vault try: response = self.get_session(uri).get(files_url, allow_redirects=False) response.raise_for_status() @@ -2426,11 +2437,6 @@ def _get(self, uri): return None if response.status_code == 303: return response.headers.get('Location', None) - elif response.status_code == 200: - # TODO this happens for cavern. It is wasteful since the response - # already contains the bytes but there's no other way to find out the - # actual location of the bytes. - return files_url return None def _add_soda_ops(self, url, view=None, cutout=None):