Skip to content

Commit

Permalink
Merge pull request #394 from euroargodev/releasev0.1.17
Browse files Browse the repository at this point in the history
Prepare for v0.1.17 Bat Release 🦇
  • Loading branch information
gmaze authored Sep 20, 2024
2 parents 0f5a754 + b135bfa commit 4ae5aab
Show file tree
Hide file tree
Showing 216 changed files with 5,262 additions and 4,979 deletions.
1 change: 0 additions & 1 deletion argopy/data_fetchers/erddap_data.py
Original file line number Diff line number Diff line change
Expand Up @@ -620,7 +620,6 @@ def getNfromncHeader(url):
N += getNfromncHeader(url)
return N


def post_process(
self, this_ds, add_dm: bool = True, URI: list = None
): # noqa: C901
Expand Down
1 change: 0 additions & 1 deletion argopy/data_fetchers/erddap_refdata.py
Original file line number Diff line number Diff line change
Expand Up @@ -110,7 +110,6 @@ def _add_attributes(self, this): # noqa: C901

return this


@property
def _minimal_vlist(self):
"""Return the minimal list of variables to retrieve measurements for"""
Expand Down
1 change: 0 additions & 1 deletion argopy/errors.py
Original file line number Diff line number Diff line change
Expand Up @@ -194,4 +194,3 @@ def __init__(self, reason: str = None, version: str = None, ignore_caller: List

else:
raise TypeError(repr(type(reason)))

51 changes: 28 additions & 23 deletions argopy/fetchers.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,16 +16,16 @@
import logging

from .options import OPTIONS, _VALIDATORS
from .errors import InvalidFetcherAccessPoint, InvalidFetcher, OptionValueError, OptionDeprecatedWarning
from .errors import (
InvalidFetcherAccessPoint,
InvalidFetcher,
OptionValueError,
OptionDeprecatedWarning,
)
from .related import (
get_coriolis_profile_id,
)
from .utils.checkers import (
is_box,
is_indexbox,
check_wmo,
check_cyc
)
from .utils.checkers import is_box, is_indexbox, check_wmo, check_cyc
from .utils.lists import (
list_available_data_src,
list_available_index_src,
Expand Down Expand Up @@ -166,12 +166,15 @@ def __init__(self, mode: str = "", src: str = "", ds: str = "", **fetcher_kwargs
if self._src == "argovis" and (
self._mode == "expert" or self._mode == "research"
):
raise OptionValueError("The 'argovis' data source fetching is only available in 'standard' user mode")
raise OptionValueError(
"The 'argovis' data source fetching is only available in 'standard' user mode"
)

if self._src == "gdac" and "ftp" in self.fetcher_kwargs:
OptionDeprecatedWarning(reason="The GDAC 'ftp' argument is deprecated, it will be replaced by 'gdac' in versions >= 0.1.18",
version="v0.0.17")

OptionDeprecatedWarning(
reason="The GDAC 'ftp' argument is deprecated, it will be replaced by 'gdac' in versions >= 0.1.18",
version="v0.0.17",
)

def __repr__(self):
para = (
Expand Down Expand Up @@ -306,7 +309,7 @@ def domain(self):

@property
def mission(self):
if self._dataset_id == 'bgc':
if self._dataset_id == "bgc":
return "BGC"
else:
return "core+deep"
Expand Down Expand Up @@ -530,18 +533,21 @@ def to_index(self, full: bool = False, coriolis_id: bool = False):
:class:`pandas.DataFrame`
Argo-like index of fetched data
"""

def prt(txt):
msg = [txt]
if self._request != self.__repr__():
msg.append(self._request)
log.debug("\n".join(msg))

def add_coriolis(this_df):
if 'id' not in this_df:
if "id" not in this_df:
this_df["id"] = None

def fc(row):
row["id"] = get_coriolis_profile_id(row["wmo"], row["cyc"])["ID"].values[0]
row["id"] = get_coriolis_profile_id(row["wmo"], row["cyc"])[
"ID"
].values[0]
return row

this_df = this_df.apply(fc, axis=1)
Expand All @@ -550,7 +556,9 @@ def fc(row):
# With the gdac and erddap+bgc,
# we rely on the fetcher ArgoIndex:
# (hence we always return a full index)
if (self._src == 'erddap' and self._dataset_id == 'bgc') or (self._src == 'gdac'):
if (self._src == "erddap" and self._dataset_id == "bgc") or (
self._src == "gdac"
):
prt("to_index working with fetcher ArgoIndex instance")
idx = self.fetcher.indexfs
if self._AccessPoint == "region":
Expand All @@ -564,7 +572,9 @@ def fc(row):
if self._AccessPoint == "float":
idx.search_wmo(self._AccessPoint_data["wmo"])
if self._AccessPoint == "profile":
idx.search_wmo_cyc(self._AccessPoint_data["wmo"], self._AccessPoint_data["cyc"])
idx.search_wmo_cyc(
self._AccessPoint_data["wmo"], self._AccessPoint_data["cyc"]
)

# Then export search result to Index dataframe:
df = idx.to_dataframe()
Expand Down Expand Up @@ -611,14 +621,14 @@ def fc(row):
df = add_coriolis(df) if coriolis_id else df

# Possibly replace the light index with the full version:
if 'profiler_code' not in df or self._request == self.__repr__():
if "profiler_code" not in df or self._request == self.__repr__():
prt("to_index replaced the light index with the full version")
self._index = df

return df

def load(self, force: bool = False, **kwargs):
""" Fetch data (and compute a profile index) if not already in memory
"""Fetch data (and compute a profile index) if not already in memory
Apply the default to_xarray() and to_index() methods and store results in memory.
You can access loaded measurements structure with the `data` and `index` properties.
Expand Down Expand Up @@ -752,11 +762,6 @@ def __init__(
_VALIDATORS["src"](self._src)

# Load data source access points:
if self._src == "localftp":
raise ValueError(
"The 'localftp' data source is deprecated. It's been replaced by 'gdac'."
)

if self._src not in AVAILABLE_INDEX_SOURCES:
raise InvalidFetcher(
"Requested index fetcher '%s' not available ! "
Expand Down
127 changes: 71 additions & 56 deletions argopy/options.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,22 +4,28 @@
# Like always, largely inspired by xarray code:
# https://github.com/pydata/xarray/blob/cafab46aac8f7a073a32ec5aa47e213a9810ed54/xarray/core/options.py
"""

import os
import warnings
import logging
import fsspec
from fsspec.core import split_protocol
from socket import gaierror
from urllib.parse import urlparse
from .errors import OptionValueError, FtpPathError, ErddapPathError, OptionDeprecatedWarning
from .errors import (
OptionValueError,
FtpPathError,
ErddapPathError,
OptionDeprecatedWarning,
)

# Define a logger
log = logging.getLogger("argopy.options")

# Define option names as seen by users:
DATA_SOURCE = "src"
FTP = "ftp"
ERDDAP = 'erddap'
ERDDAP = "erddap"
DATASET = "dataset"
CACHE_FOLDER = "cachedir"
CACHE_EXPIRATION = "cache_expiration"
Expand Down Expand Up @@ -62,15 +68,15 @@ def _positive_integer(value):

def validate_ftp(this_path):
if this_path != "-":
return check_gdac_path(this_path, errors='raise')
return check_gdac_path(this_path, errors="raise")
else:
log.debug("OPTIONS['%s'] is not defined" % FTP)
return False


def validate_http(this_path):
if this_path != "-":
return check_erddap_path(this_path, errors='raise')
return check_erddap_path(this_path, errors="raise")
else:
log.debug("OPTIONS['%s'] is not defined" % ERDDAP)
return False
Expand Down Expand Up @@ -186,16 +192,20 @@ def __init__(self, **kwargs):
raise OptionValueError(f"option {k!r} given an invalid value: {v!r}")
self.old[k] = OPTIONS[k]

if k == 'dataset':
OptionDeprecatedWarning(reason="The 'dataset' option is deprecated, it will be replaced by 'ds' in "
"versions >= 0.1.18",
version="v0.0.17",
ignore_caller='test_opt_dataset')
if k == "dataset":
OptionDeprecatedWarning(
reason="The 'dataset' option is deprecated, it will be replaced by 'ds' in "
"versions >= 0.1.18",
version="v0.0.17",
ignore_caller="test_opt_dataset",
)

if k == 'ftp':
OptionDeprecatedWarning(reason="The 'ftp' option is deprecated, it will be replaced by 'gdac' in "
"versions >= 0.1.18",
version="v0.0.17")
if k == "ftp":
OptionDeprecatedWarning(
reason="The 'ftp' option is deprecated, it will be replaced by 'gdac' in "
"versions >= 0.1.18",
version="v0.0.17",
)

self._apply_update(kwargs)

Expand All @@ -214,9 +224,9 @@ def reset_options():
set_options(**DEFAULT)


def check_erddap_path(path, errors='ignore'):
def check_erddap_path(path, errors="ignore"):
"""Check if an url points to an ERDDAP server"""
fs = fsspec.filesystem('http', ssl=False)
fs = fsspec.filesystem("http", ssl=False)
check1 = fs.exists(path + "/info/index.json")
if check1:
return True
Expand All @@ -230,60 +240,62 @@ def check_erddap_path(path, errors='ignore'):
return False


def check_gdac_path(path, errors='ignore'): # noqa: C901
""" Check if a path has the expected GDAC ftp structure
Check if a path is structured like:
.
└── dac
├── aoml
├── ...
├── coriolis
├── ...
├── meds
└── nmdis
Examples:
>>> check_gdac_path("https://data-argo.ifremer.fr") # True
>>> check_gdac_path("ftp://ftp.ifremer.fr/ifremer/argo") # True
>>> check_gdac_path("ftp://usgodae.org/pub/outgoing/argo") # True
>>> check_gdac_path("/home/ref-argo/gdac") # True
>>> check_gdac_path("https://www.ifremer.fr") # False
>>> check_gdac_path("ftp://usgodae.org/pub/outgoing") # False
Parameters
----------
path: str
Path name to check, including access protocol
errors: str
"ignore" or "raise" (or "warn")
Returns
-------
checked: boolean
True if at least one DAC folder is found under path/dac/<dac_name>
False otherwise
def check_gdac_path(path, errors="ignore"): # noqa: C901
"""Check if a path has the expected GDAC ftp structure
Check if a path is structured like:
.
└── dac
├── aoml
├── ...
├── coriolis
├── ...
├── meds
└── nmdis
Examples:
>>> check_gdac_path("https://data-argo.ifremer.fr") # True
>>> check_gdac_path("ftp://ftp.ifremer.fr/ifremer/argo") # True
>>> check_gdac_path("ftp://usgodae.org/pub/outgoing/argo") # True
>>> check_gdac_path("/home/ref-argo/gdac") # True
>>> check_gdac_path("https://www.ifremer.fr") # False
>>> check_gdac_path("ftp://usgodae.org/pub/outgoing") # False
Parameters
----------
path: str
Path name to check, including access protocol
errors: str
"ignore" or "raise" (or "warn")
Returns
-------
checked: boolean
True if at least one DAC folder is found under path/dac/<dac_name>
False otherwise
"""
# Create a file system for this path
if split_protocol(path)[0] is None:
fs = fsspec.filesystem('file')
elif split_protocol(path)[0] in ['https', 'http']:
fs = fsspec.filesystem('http')
elif 'ftp' in split_protocol(path)[0]:
fs = fsspec.filesystem("file")
elif split_protocol(path)[0] in ["https", "http"]:
fs = fsspec.filesystem("http")
elif "ftp" in split_protocol(path)[0]:
try:
host = urlparse(path).hostname
port = 0 if urlparse(path).port is None else urlparse(path).port
fs = fsspec.filesystem('ftp', host=host, port=port)
fs = fsspec.filesystem("ftp", host=host, port=port)
except gaierror:
if errors == 'raise':
if errors == "raise":
raise FtpPathError("Can't get address info (GAIerror) on '%s'" % host)
elif errors == "warn":
warnings.warn("Can't get address info (GAIerror) on '%s'" % host)
return False
else:
return False
else:
raise FtpPathError("Unknown protocol for an Argo GDAC host: %s" % split_protocol(path)[0])
raise FtpPathError(
"Unknown protocol for an Argo GDAC host: %s" % split_protocol(path)[0]
)

# dacs = [
# "aoml",
Expand All @@ -310,7 +322,10 @@ def check_gdac_path(path, errors='ignore'): # noqa: C901
return True

elif errors == "raise":
raise FtpPathError("This path is not GDAC compliant (no `dac` folder with legitimate sub-folder):\n%s" % path)
raise FtpPathError(
"This path is not GDAC compliant (no `dac` folder with legitimate sub-folder):\n%s"
% path
)

elif errors == "warn":
warnings.warn("This path is not GDAC compliant:\n%s" % path)
Expand Down
2 changes: 1 addition & 1 deletion argopy/related/argo_documentation.py
Original file line number Diff line number Diff line change
Expand Up @@ -75,7 +75,7 @@ def parse(self, file):
else:
# print("-", line)
record[tag].append(line)
except UnboundLocalError as e:
except UnboundLocalError:
pass
elif len(line) == 2:
record[line] = []
Expand Down
12 changes: 5 additions & 7 deletions argopy/related/reference_tables.py
Original file line number Diff line number Diff line change
Expand Up @@ -31,9 +31,6 @@ class ArgoNVSReferenceTables:

valid_ref = [
"R01",
"RR2",
"RD2",
"RP2",
"R03",
"R04",
"R05",
Expand All @@ -46,8 +43,6 @@ class ArgoNVSReferenceTables:
"R12",
"R13",
"R15",
"RMC",
"RTV",
"R16",
"R18",
"R19",
Expand All @@ -60,9 +55,12 @@ class ArgoNVSReferenceTables:
"R26",
"R27",
"R28",
"R29",
"R30",
"R40",
"RD2",
"RMC",
"RP2",
"RR2",
"RTV",
]
"""List of all available Reference Tables"""

Expand Down
Loading

0 comments on commit 4ae5aab

Please sign in to comment.