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

Commit

Permalink
implement legacy remote (#87)
Browse files Browse the repository at this point in the history
  • Loading branch information
malmans2 authored Sep 25, 2024
1 parent 79b012d commit bb42c45
Show file tree
Hide file tree
Showing 3 changed files with 51 additions and 19 deletions.
39 changes: 28 additions & 11 deletions cads_api_client/legacy_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,10 +9,13 @@
from typing import Any, Callable, TypeVar, cast, overload

import cdsapi.api
import multiurl
import requests

from . import __version__ as cads_api_client_version
from . import api_client, processing
from . import processing
from .api_client import ApiClient
from .processing import Remote, Results

LEGACY_KWARGS = [
"full_stack",
Expand Down Expand Up @@ -101,7 +104,7 @@ def __init__(
UserWarning,
)

self.client = self.logging_decorator(api_client.ApiClient)(
self.client = self.logging_decorator(ApiClient)(
url=self.url,
key=self.key,
verify=self.verify,
Expand Down Expand Up @@ -139,7 +142,7 @@ def logging_decorator(self, func: F) -> F:
@functools.wraps(func)
def wrapper(*args: Any, **kwargs: Any) -> Any:
with LoggingContext(
logger=processing.logger, quiet=self.quiet, debug=self._debug
logger=processing.LOGGER, quiet=self.quiet, debug=self._debug
):
return func(*args, **kwargs)

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

def retrieve(
self, name: str, request: dict[str, Any], target: str | None = None
) -> str | processing.Remote | processing.Results:
submitted: processing.Remote | processing.Results
) -> str | Remote | Results:
submitted: Remote | Results
if self.wait_until_complete:
submitted = self.logging_decorator(self.client.submit_and_wait_on_results)(
collection_id=name,
Expand Down Expand Up @@ -206,7 +209,7 @@ def status(self, context: Any = None) -> dict[str, list[str]]:

@typing.no_type_check
def _download(self, results, targets=None):
if isinstance(results, (processing.Results, processing.Remote)):
if hasattr(results, "download"):
if targets:
path = targets.pop(0)
else:
Expand All @@ -221,8 +224,22 @@ def _download(self, results, targets=None):

return results

def remote(self, url): # type: ignore
self.raise_not_implemented_error()
@typing.no_type_check
def download(self, results, targets=None):
if targets:
# Make a copy
targets = [t for t in targets]
return self._download(results, targets)

def remote(self, url: str) -> cdsapi.api.Result:
r = requests.head(url)
reply = dict(
location=url,
content_length=r.headers["Content-Length"],
content_type=r.headers["Content-Type"],
)
return cdsapi.api.Result(self, reply)

def robust(self, call): # type: ignore
self.raise_not_implemented_error()
def robust(self, call: F) -> F:
robust: F = multiurl.robust(call, **self.client._retry_options)
return robust
10 changes: 5 additions & 5 deletions cads_api_client/processing.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@

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

logger = logging.getLogger(__name__)
LOGGER = logging.getLogger(__name__)

LEVEL_NAMES_MAPPING = {
"CRITICAL": 50,
Expand Down Expand Up @@ -138,11 +138,11 @@ def from_request(
robust_request = multiurl.robust(session.request, **retry_options)

inputs = kwargs.get("json", {}).get("inputs", {})
logger.debug(f"{method.upper()} {url} {inputs or ''}".strip())
LOGGER.debug(f"{method.upper()} {url} {inputs or ''}".strip())
response = robust_request(
method, url, headers=headers, **request_options, **kwargs
)
logger.debug(f"REPLY {response.text}")
LOGGER.debug(f"REPLY {response.text}")

cads_raise_for_status(response)

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

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

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

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

def info(self, *args: Any, **kwargs: Any) -> None:
self.log(logging.INFO, *args, **kwargs)
Expand Down
21 changes: 18 additions & 3 deletions tests/integration_test_70_legacy_api_client.py
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,7 @@

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


def legacy_update(remote: processing.Remote) -> None:
Expand Down Expand Up @@ -218,9 +218,11 @@ def test_legacy_api_client_logging(

def test_legacy_api_client_download(
tmp_path: pathlib.Path,
monkeypatch: pytest.MonkeyPatch,
api_root_url: str,
api_anon_key: str,
) -> None:
monkeypatch.chdir(tmp_path)
client = LegacyApiClient(
url=api_root_url,
key=api_anon_key,
Expand All @@ -229,10 +231,12 @@ def test_legacy_api_client_download(
)
remote = client.retrieve("test-adaptor-dummy", {"size": 1})
assert isinstance(remote, processing.Remote)
target = client.download(remote)
assert os.path.getsize(target) == 1

results = (remote, remote.make_results())
target1 = str(tmp_path / "remote.grib")
target2 = str(tmp_path / "results.grib")
target1 = "remote.grib"
target2 = "results.grib"
assert client.download(results, [target1, target2]) == [target1, target2]
assert os.path.getsize(target1) == os.path.getsize(target2) == 1

Expand All @@ -254,3 +258,14 @@ def test_legacy_api_client_status(legacy_client: LegacyApiClient) -> None:
for value in status.values()
for string in value
)


def test_legacy_api_client_remote(
legacy_client: LegacyApiClient, tmp_path: pathlib.Path
) -> None:
results = legacy_client.retrieve("test-adaptor-dummy", {"size": 1})
remote = legacy_client.remote(results.location)
target = str(tmp_path / "dummy.grib")
actual_target = remote.download(target)
assert target == actual_target
assert os.path.getsize(target) == 1

0 comments on commit bb42c45

Please sign in to comment.