Skip to content
This repository was archived by the owner on Nov 19, 2024. It is now read-only.

Commit bb42c45

Browse files
authored
implement legacy remote (#87)
1 parent 79b012d commit bb42c45

File tree

3 files changed

+51
-19
lines changed

3 files changed

+51
-19
lines changed

cads_api_client/legacy_api_client.py

Lines changed: 28 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -9,10 +9,13 @@
99
from typing import Any, Callable, TypeVar, cast, overload
1010

1111
import cdsapi.api
12+
import multiurl
1213
import requests
1314

1415
from . import __version__ as cads_api_client_version
15-
from . import api_client, processing
16+
from . import processing
17+
from .api_client import ApiClient
18+
from .processing import Remote, Results
1619

1720
LEGACY_KWARGS = [
1821
"full_stack",
@@ -101,7 +104,7 @@ def __init__(
101104
UserWarning,
102105
)
103106

104-
self.client = self.logging_decorator(api_client.ApiClient)(
107+
self.client = self.logging_decorator(ApiClient)(
105108
url=self.url,
106109
key=self.key,
107110
verify=self.verify,
@@ -139,7 +142,7 @@ def logging_decorator(self, func: F) -> F:
139142
@functools.wraps(func)
140143
def wrapper(*args: Any, **kwargs: Any) -> Any:
141144
with LoggingContext(
142-
logger=processing.logger, quiet=self.quiet, debug=self._debug
145+
logger=processing.LOGGER, quiet=self.quiet, debug=self._debug
143146
):
144147
return func(*args, **kwargs)
145148

@@ -151,12 +154,12 @@ def retrieve(self, name: str, request: dict[str, Any], target: str) -> str: ...
151154
@overload
152155
def retrieve(
153156
self, name: str, request: dict[str, Any], target: None = ...
154-
) -> processing.Results: ...
157+
) -> Results: ...
155158

156159
def retrieve(
157160
self, name: str, request: dict[str, Any], target: str | None = None
158-
) -> str | processing.Remote | processing.Results:
159-
submitted: processing.Remote | processing.Results
161+
) -> str | Remote | Results:
162+
submitted: Remote | Results
160163
if self.wait_until_complete:
161164
submitted = self.logging_decorator(self.client.submit_and_wait_on_results)(
162165
collection_id=name,
@@ -206,7 +209,7 @@ def status(self, context: Any = None) -> dict[str, list[str]]:
206209

207210
@typing.no_type_check
208211
def _download(self, results, targets=None):
209-
if isinstance(results, (processing.Results, processing.Remote)):
212+
if hasattr(results, "download"):
210213
if targets:
211214
path = targets.pop(0)
212215
else:
@@ -221,8 +224,22 @@ def _download(self, results, targets=None):
221224

222225
return results
223226

224-
def remote(self, url): # type: ignore
225-
self.raise_not_implemented_error()
227+
@typing.no_type_check
228+
def download(self, results, targets=None):
229+
if targets:
230+
# Make a copy
231+
targets = [t for t in targets]
232+
return self._download(results, targets)
233+
234+
def remote(self, url: str) -> cdsapi.api.Result:
235+
r = requests.head(url)
236+
reply = dict(
237+
location=url,
238+
content_length=r.headers["Content-Length"],
239+
content_type=r.headers["Content-Type"],
240+
)
241+
return cdsapi.api.Result(self, reply)
226242

227-
def robust(self, call): # type: ignore
228-
self.raise_not_implemented_error()
243+
def robust(self, call: F) -> F:
244+
robust: F = multiurl.robust(call, **self.client._retry_options)
245+
return robust

cads_api_client/processing.py

Lines changed: 5 additions & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -23,7 +23,7 @@
2323

2424
T_ApiResponse = TypeVar("T_ApiResponse", bound="ApiResponse")
2525

26-
logger = logging.getLogger(__name__)
26+
LOGGER = logging.getLogger(__name__)
2727

2828
LEVEL_NAMES_MAPPING = {
2929
"CRITICAL": 50,
@@ -138,11 +138,11 @@ def from_request(
138138
robust_request = multiurl.robust(session.request, **retry_options)
139139

140140
inputs = kwargs.get("json", {}).get("inputs", {})
141-
logger.debug(f"{method.upper()} {url} {inputs or ''}".strip())
141+
LOGGER.debug(f"{method.upper()} {url} {inputs or ''}".strip())
142142
response = robust_request(
143143
method, url, headers=headers, **request_options, **kwargs
144144
)
145-
logger.debug(f"REPLY {response.text}")
145+
LOGGER.debug(f"REPLY {response.text}")
146146

147147
cads_raise_for_status(response)
148148

@@ -223,7 +223,7 @@ def _from_rel_href(self, rel: str) -> Self | None:
223223
return out
224224

225225
def log(self, *args: Any, **kwargs: Any) -> None:
226-
logger.log(*args, **kwargs)
226+
LOGGER.log(*args, **kwargs)
227227

228228
def info(self, *args: Any, **kwargs: Any) -> None:
229229
self.log(logging.INFO, *args, **kwargs)
@@ -548,7 +548,7 @@ def reply(self) -> dict[str, Any]:
548548
return reply
549549

550550
def log(self, *args: Any, **kwargs: Any) -> None:
551-
logger.log(*args, **kwargs)
551+
LOGGER.log(*args, **kwargs)
552552

553553
def info(self, *args: Any, **kwargs: Any) -> None:
554554
self.log(logging.INFO, *args, **kwargs)

tests/integration_test_70_legacy_api_client.py

Lines changed: 18 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -18,7 +18,7 @@
1818

1919
@pytest.fixture
2020
def legacy_client(api_root_url: str, api_anon_key: str) -> LegacyApiClient:
21-
return LegacyApiClient(url=api_root_url, key=api_anon_key, retry_max=0)
21+
return LegacyApiClient(url=api_root_url, key=api_anon_key, retry_max=1)
2222

2323

2424
def legacy_update(remote: processing.Remote) -> None:
@@ -218,9 +218,11 @@ def test_legacy_api_client_logging(
218218

219219
def test_legacy_api_client_download(
220220
tmp_path: pathlib.Path,
221+
monkeypatch: pytest.MonkeyPatch,
221222
api_root_url: str,
222223
api_anon_key: str,
223224
) -> None:
225+
monkeypatch.chdir(tmp_path)
224226
client = LegacyApiClient(
225227
url=api_root_url,
226228
key=api_anon_key,
@@ -229,10 +231,12 @@ def test_legacy_api_client_download(
229231
)
230232
remote = client.retrieve("test-adaptor-dummy", {"size": 1})
231233
assert isinstance(remote, processing.Remote)
234+
target = client.download(remote)
235+
assert os.path.getsize(target) == 1
232236

233237
results = (remote, remote.make_results())
234-
target1 = str(tmp_path / "remote.grib")
235-
target2 = str(tmp_path / "results.grib")
238+
target1 = "remote.grib"
239+
target2 = "results.grib"
236240
assert client.download(results, [target1, target2]) == [target1, target2]
237241
assert os.path.getsize(target1) == os.path.getsize(target2) == 1
238242

@@ -254,3 +258,14 @@ def test_legacy_api_client_status(legacy_client: LegacyApiClient) -> None:
254258
for value in status.values()
255259
for string in value
256260
)
261+
262+
263+
def test_legacy_api_client_remote(
264+
legacy_client: LegacyApiClient, tmp_path: pathlib.Path
265+
) -> None:
266+
results = legacy_client.retrieve("test-adaptor-dummy", {"size": 1})
267+
remote = legacy_client.remote(results.location)
268+
target = str(tmp_path / "dummy.grib")
269+
actual_target = remote.download(target)
270+
assert target == actual_target
271+
assert os.path.getsize(target) == 1

0 commit comments

Comments
 (0)