Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Refactor to create a more maintainable structure #16

Merged
merged 13 commits into from
Jul 11, 2023
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 6 additions & 8 deletions cads_adaptors/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -22,14 +22,12 @@
# Local copy or not installed with setuptools
__version__ = "999"

from .adaptor import AbstractAdaptor, DummyAdaptor
from .adaptor_cds import (
AbstractCdsAdaptor,
DirectMarsCdsAdaptor,
LegacyCdsAdaptor,
MarsCdsAdaptor,
UrlCdsAdaptor,
)
from cads_adaptors.adaptors import AbstractAdaptor, DummyAdaptor
from cads_adaptors.adaptors.cds import AbstractCdsAdaptor
from cads_adaptors.adaptors.legacy import LegacyCdsAdaptor
from cads_adaptors.adaptors.mars import DirectMarsCdsAdaptor, MarsCdsAdaptor
from cads_adaptors.adaptors.url import UrlCdsAdaptor

from .tools.adaptor_tools import get_adaptor_class

__all__ = [
Expand Down
99 changes: 0 additions & 99 deletions cads_adaptors/adaptor_cds.py

This file was deleted.

File renamed without changes.
28 changes: 28 additions & 0 deletions cads_adaptors/adaptors/cds.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
from typing import Any

from cads_adaptors import constraints, costing
from cads_adaptors.adaptors import AbstractAdaptor, Request


class AbstractCdsAdaptor(AbstractAdaptor):
resources = {"CADS_ADAPTORS": 1}

def __init__(self, form: dict[str, Any], **config: Any):
self.form = form
self.constraints = config.pop("constraints", [])
self.mapping = config.pop("mapping", {})
self.licences: list[tuple[str, int]] = config.pop("licences", [])
self.config = config

def validate(self, request: Request) -> bool:
return True

def apply_constraints(self, request: Request) -> dict[str, Any]:
return constraints.validate_constraints(self.form, request, self.constraints)

def estimate_costs(self, request: Request) -> dict[str, int]:
costs = {"size": costing.estimate_size(self.form, request, self.constraints)}
return costs

def get_licences(self, request: Request) -> list[tuple[str, int]]:
return self.licences
18 changes: 18 additions & 0 deletions cads_adaptors/adaptors/legacy.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
from typing import BinaryIO

from cads_adaptors.adaptors import Request, cds


class LegacyCdsAdaptor(cds.AbstractCdsAdaptor):
def retrieve(self, request: Request) -> BinaryIO:
import cdsapi

# parse input options
collection_id = self.config.pop("collection_id", None)
if not collection_id:
raise ValueError("collection_id is required in request")

# retrieve data
client = cdsapi.Client(self.config["url"], self.config["key"], retry_max=1)
result_path = client.retrieve(collection_id, request).download()
return open(result_path, "rb")
40 changes: 40 additions & 0 deletions cads_adaptors/adaptors/mars.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
import os
from typing import BinaryIO

from cads_adaptors import mapping
from cads_adaptors.adaptors import Request, cds


class DirectMarsCdsAdaptor(cds.AbstractCdsAdaptor):
resources = {"MARS_CLIENT": 1}

def retrieve(self, request: Request) -> BinaryIO:
import subprocess

with open("r", "w") as fp:
print("retrieve, target=data.grib", file=fp)
for key, value in request.items():
if not isinstance(value, (list, tuple)):
value = [value]
print(f", {key}={'/'.join(str(v) for v in value)}", file=fp)

env = dict(**os.environ)
# FIXME: set with the namespace and user_id
namespace = "cads"
user_id = 0
env["MARS_USER"] = f"{namespace}-{user_id}"

subprocess.run(["/usr/local/bin/mars", "r"], check=True, env=env)

return open("data.grib") # type: ignore


class MarsCdsAdaptor(cds.AbstractCdsAdaptor):
def retrieve(self, request: Request) -> BinaryIO:
format = request.pop("format", "grib")

mapped_request = mapping.apply_mapping(request, self.mapping) # type: ignore
if format != "grib":
# FIXME: reformat if needed
pass
return super().retrieve(mapped_request)
25 changes: 25 additions & 0 deletions cads_adaptors/adaptors/url.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,25 @@
from typing import BinaryIO

from cads_adaptors import mapping
from cads_adaptors.adaptors import Request, cds


class UrlCdsAdaptor(cds.AbstractCdsAdaptor):
def retrieve(self, request: Request) -> BinaryIO:
from cads_adaptors.tools import url_tools

data_format = request.pop("format", "zip")

if data_format not in {"zip", "tgz"}:
raise ValueError(f"{data_format=} is not supported")

mapped_request = mapping.apply_mapping(request, self.mapping) # type: ignore

requests_urls = url_tools.requests_to_urls(
mapped_request, patterns=self.config["patterns"]
)

path = url_tools.download_from_urls(
[ru["url"] for ru in requests_urls], data_format=data_format
)
return open(path, "rb")
6 changes: 3 additions & 3 deletions cads_adaptors/tools/adaptor_tools.py
Original file line number Diff line number Diff line change
@@ -1,11 +1,11 @@
from typing import Any

from .. import adaptor
from cads_adaptors.adaptors import AbstractAdaptor


def get_adaptor_class(
entry_point: str, setup_code: str | None = None
) -> type[adaptor.AbstractAdaptor]:
) -> type[AbstractAdaptor]:
from cacholote import decode

try:
Expand All @@ -17,7 +17,7 @@ def get_adaptor_class(
raise TypeError
exec(setup_code)
adaptor_class = eval(entry_point)
if not issubclass(adaptor_class, adaptor.AbstractAdaptor):
if not issubclass(adaptor_class, AbstractAdaptor):
raise TypeError(f"{adaptor_class!r} is not subclass of AbstractAdaptor")
return adaptor_class # type: ignore

Expand Down